Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented Test containers for integration testing - phase 1 #3472

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Ginger/GingerCoreNET/GingerCoreNET.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@
<PackageReference Include="MySql.Data" Version="8.0.16" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Npgsql" Version="4.0.7" />
<PackageReference Include="NPOI" Version="2.5.3" />
<PackageReference Include="NPOI" Version="2.6.2" />
<PackageReference Include="NUglify" Version="1.9.7" />
<PackageReference Include="protobuf-net" Version="3.2.26" />
<PackageReference Include="protobuf-net.Core" Version="3.2.26" />
Expand Down
126 changes: 126 additions & 0 deletions Ginger/GingerCoreNETUnitTest/DatabaseTest/CouchbaseIntegrationTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
using Couchbase;
using Couchbase.Configuration.Client;
using GingerCore.Actions;
using GingerCore.Environments;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Testcontainers.Couchbase;

namespace GingerCoreNETUnitTest.DatabaseTest
{
[TestClass]
public sealed class CouchbaseIntegrationTests
{

private static readonly CouchbaseContainer _couchbaseContainer = new CouchbaseBuilder().Build();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instantiating the Couchbase container without specifying an image version could lead to inconsistent test environments. It's recommended to specify a version for predictability.

- private static readonly CouchbaseContainer _couchbaseContainer = new CouchbaseBuilder().Build();
+ private static readonly CouchbaseContainer _couchbaseContainer = new CouchbaseBuilder().WithImage("couchbase/server:enterprise-6.5.1").Build();

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
private static readonly CouchbaseContainer _couchbaseContainer = new CouchbaseBuilder().Build();
private static readonly CouchbaseContainer _couchbaseContainer = new CouchbaseBuilder().WithImage("couchbase/server:enterprise-6.5.1").Build();


[ClassInitialize]
public static async Task ClassInitialize(TestContext context)
{
await _couchbaseContainer.StartAsync();

Check failure on line 23 in Ginger/GingerCoreNETUnitTest/DatabaseTest/CouchbaseIntegrationTests.cs

View workflow job for this annotation

GitHub Actions / Ginger Windows UnitTests

GingerCoreNETUnitTest.DatabaseTest.CouchbaseIntegrationTests ► ShouldReturnTwoCustomers

Failed test found in: D:/a/TestResults/runneradmin_fv-az836-25_2024-03-22_17_08_41.trx Error: Class Initialization method GingerCoreNETUnitTest.DatabaseTest.CouchbaseIntegrationTests.ClassInitialize threw exception. Docker.DotNet.DockerImageNotFoundException: Docker.DotNet.DockerImageNotFoundException: Docker API responded with status code=NotFound, response={"message":"No such image: couchbase:community-7.0.2"} .
Raw output
Class Initialization method GingerCoreNETUnitTest.DatabaseTest.CouchbaseIntegrationTests.ClassInitialize threw exception. Docker.DotNet.DockerImageNotFoundException: Docker.DotNet.DockerImageNotFoundException: Docker API responded with status code=NotFound, response={"message":"No such image: couchbase:community-7.0.2"}
.
   at Docker.DotNet.ContainerOperations.<>c.<.cctor>b__30_1(HttpStatusCode statusCode, String responseBody)
   at Docker.DotNet.DockerClient.HandleIfErrorResponseAsync(HttpStatusCode statusCode, HttpResponseMessage response, IEnumerable`1 handlers)
   at Docker.DotNet.DockerClient.MakeRequestAsync(IEnumerable`1 errorHandlers, HttpMethod method, String path, IQueryString queryString, IRequestContent body, IDictionary`2 headers, TimeSpan timeout, CancellationToken token)
   at Docker.DotNet.ContainerOperations.CreateContainerAsync(CreateContainerParameters parameters, CancellationToken cancellationToken)
   at DotNet.Testcontainers.Clients.DockerContainerOperations.RunAsync(IContainerConfiguration configuration, CancellationToken ct)
   at DotNet.Testcontainers.Clients.TestcontainersClient.RunAsync(IContainerConfiguration configuration, CancellationToken ct)
   at DotNet.Testcontainers.Containers.DockerContainer.UnsafeCreateAsync(CancellationToken ct)
   at DotNet.Testcontainers.Containers.DockerContainer.StartAsync(CancellationToken ct)
   at GingerCoreNETUnitTest.DatabaseTest.CouchbaseIntegrationTests.ClassInitialize(TestContext context) in D:\a\Ginger\Ginger\Ginger\GingerCoreNETUnitTest\DatabaseTest\CouchbaseIntegrationTests.cs:line 23
await CreateTestData();

}

[TestCleanup]
public Task DisposeAsync()
{
return _couchbaseContainer.DisposeAsync().AsTask();
Comment on lines +28 to +31
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DisposeAsync method should be marked as async and use the await keyword for disposal, similar to the other test classes.

- public Task DisposeAsync()
+ public async Task DisposeAsync()

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
[TestCleanup]
public Task DisposeAsync()
{
return _couchbaseContainer.DisposeAsync().AsTask();
[TestCleanup]
public async Task DisposeAsync()
{
return _couchbaseContainer.DisposeAsync().AsTask();

}
public static async Task CreateTestData()
{

try
{
// var clusterOptions = new ClusterOptions();

Check warning on line 38 in Ginger/GingerCoreNETUnitTest/DatabaseTest/CouchbaseIntegrationTests.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

Ginger/GingerCoreNETUnitTest/DatabaseTest/CouchbaseIntegrationTests.cs#L38

Remove this commented out code.
// clusterOptions.ConnectionString = _couchbaseContainer.GetConnectionString();
// clusterOptions.UserName = CouchbaseBuilder.DefaultUsername;
// clusterOptions.Password = CouchbaseBuilder.DefaultPassword;

// var cluster = await Cluster.ConnectAsync(clusterOptions)
//.ConfigureAwait(true);

// // When
// var ping = await cluster.PingAsync()
// .ConfigureAwait(true);

// var bucket = await cluster.BucketAsync(_couchbaseContainer.Buckets.Single().Name)
// .ConfigureAwait(true);

// When
//var database = await client.Database.PutAsync()
// .ConfigureAwait(true);
var cluster = new Cluster(new ClientConfiguration
{
Servers = new List<Uri> { new Uri("http://" + _couchbaseContainer.GetConnectionString()) },
UseSsl = false
});

cluster.Authenticate(CouchbaseBuilder.DefaultUsername, CouchbaseBuilder.DefaultPassword);

var clusterManager = cluster.CreateManager(CouchbaseBuilder.DefaultUsername, CouchbaseBuilder.DefaultPassword);
var buckets = clusterManager.ListBuckets().Value;
//var result = clusterManager.CreateBucket(new BucketSettings() { Name = "GingerBucket", BucketType = Couchbase.Core.Buckets.BucketTypeEnum.Couchbase, AuthType = Couchbase.Authentication.AuthType.None });

Check warning on line 66 in Ginger/GingerCoreNETUnitTest/DatabaseTest/CouchbaseIntegrationTests.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

Ginger/GingerCoreNETUnitTest/DatabaseTest/CouchbaseIntegrationTests.cs#L66

Remove this commented out code.
//var bucket = cluster.OpenBucket("GingerBucket");
var bucket = cluster.OpenBucket(_couchbaseContainer.Buckets.FirstOrDefault().Name);
Comment on lines +56 to +68
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commented-out code should be removed to keep the codebase clean and maintainable. If this code is meant for future reference, consider adding a detailed comment explaining its purpose or moving it to documentation.

- //      var clusterOptions = new ClusterOptions();
- //      clusterOptions.ConnectionString = _couchbaseContainer.GetConnectionString();
- //      clusterOptions.UserName = CouchbaseBuilder.DefaultUsername;
- //      clusterOptions.Password = CouchbaseBuilder.DefaultPassword;
- //      var cluster = await Cluster.ConnectAsync(clusterOptions)
- //.ConfigureAwait(true);
- //      var ping = await cluster.PingAsync()
- //          .ConfigureAwait(true);
- //      var bucket = await cluster.BucketAsync(_couchbaseContainer.Buckets.Single().Name)
- //          .ConfigureAwait(true);
- //var database = await client.Database.PutAsync()
- //    .ConfigureAwait(true);

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
var cluster = new Cluster(new ClientConfiguration
{
Servers = new List<Uri> { new Uri("http://" + _couchbaseContainer.GetConnectionString()) },
UseSsl = false
});
cluster.Authenticate(CouchbaseBuilder.DefaultUsername, CouchbaseBuilder.DefaultPassword);
var clusterManager = cluster.CreateManager(CouchbaseBuilder.DefaultUsername, CouchbaseBuilder.DefaultPassword);
var buckets = clusterManager.ListBuckets().Value;
//var result = clusterManager.CreateBucket(new BucketSettings() { Name = "GingerBucket", BucketType = Couchbase.Core.Buckets.BucketTypeEnum.Couchbase, AuthType = Couchbase.Authentication.AuthType.None });
//var bucket = cluster.OpenBucket("GingerBucket");
var bucket = cluster.OpenBucket(_couchbaseContainer.Buckets.FirstOrDefault().Name);
var cluster = new Cluster(new ClientConfiguration
{
Servers = new List<Uri> { new Uri("http://" + _couchbaseContainer.GetConnectionString()) },
UseSsl = false
});
cluster.Authenticate(CouchbaseBuilder.DefaultUsername, CouchbaseBuilder.DefaultPassword);
var clusterManager = cluster.CreateManager(CouchbaseBuilder.DefaultUsername, CouchbaseBuilder.DefaultPassword);
var buckets = clusterManager.ListBuckets().Value;
var bucket = cluster.OpenBucket(_couchbaseContainer.Buckets.FirstOrDefault().Name);

//// Insert sample data
var document = new Document<dynamic>
{
Id = "Customer",
Content = new[]{
new { Name = "Mahesh", Value = 1 , Dept = "AQE I&T"},
new { Name = "Jinendra", Value = 2, Dept = "AQE I&T"}
},
};
var upsertResult = await bucket.UpsertAsync(document);
}
catch (Exception ex)

Check notice on line 80 in Ginger/GingerCoreNETUnitTest/DatabaseTest/CouchbaseIntegrationTests.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

Ginger/GingerCoreNETUnitTest/DatabaseTest/CouchbaseIntegrationTests.cs#L80

Add logic to this catch clause or eliminate it and rethrow the exception automatically.
{

throw;
Comment on lines +80 to +83
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The catch block simply rethrows the exception without any additional handling or logging. If there's no specific error handling needed, consider removing the try-catch block to let the exception propagate naturally.

- catch (Exception ex)
- {
-     throw;
- }

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
catch (Exception ex)
{
throw;

}
}


[TestMethod]
public void ShouldReturnTwoCustomers()
{
// Given
Database db = new Database();
ActDBValidation mact = new ActDBValidation();
//actDBValidation

db.DBType = Database.eDBTypes.Couchbase;
DatabaseOperations databaseOperations = new DatabaseOperations(db);
db.DatabaseOperations = databaseOperations;
//ATT LS DB
//Db.DatabaseOperations.TNSCalculated
db.TNS = "http://" + _couchbaseContainer.GetConnectionString();
db.User = CouchbaseBuilder.DefaultUsername;
db.Pass = CouchbaseBuilder.DefaultPassword;
// NoSqlBase noSqlBase = new GingerCouchbase(ActDBValidation.eDBValidationType.FreeSQL, db, mact);

Check warning on line 104 in Ginger/GingerCoreNETUnitTest/DatabaseTest/CouchbaseIntegrationTests.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

Ginger/GingerCoreNETUnitTest/DatabaseTest/CouchbaseIntegrationTests.cs#L104

Remove this commented out code.
mact.DB = db;

Boolean connectionSuccessful = mact.DB.DatabaseOperations.Connect();

// When
List<object> recs = new List<object>();
if (connectionSuccessful)
{
mact.SQL = "SELECT * FROM `Ginger-bucket` WHERE META().id = 1";
mact.Execute();

//db.DatabaseOperations.CloseConnection();

Check warning on line 116 in Ginger/GingerCoreNETUnitTest/DatabaseTest/CouchbaseIntegrationTests.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

Ginger/GingerCoreNETUnitTest/DatabaseTest/CouchbaseIntegrationTests.cs#L116

Remove this commented out code.
}

//then
Assert.AreEqual(connectionSuccessful, true, "Connected Successfully to CouchbaseDB");
//Assert.IsNotNull(recs.Count, 0);

Check warning on line 121 in Ginger/GingerCoreNETUnitTest/DatabaseTest/CouchbaseIntegrationTests.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

Ginger/GingerCoreNETUnitTest/DatabaseTest/CouchbaseIntegrationTests.cs#L121

Remove this commented out code.
Assert.AreEqual(recs.Count, 2, "Fetched 2 records from Postgre Table");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assertion message states "Fetched 2 records from Postgre Table," which seems to be a copy-paste error from the PostgreSQL tests. Correct the message to reflect Couchbase testing.

- Assert.AreEqual(recs.Count, 2, "Fetched 2 records from Postgre Table");
+ Assert.AreEqual(recs.Count, 2, "Fetched 2 records from Couchbase bucket");

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
Assert.AreEqual(recs.Count, 2, "Fetched 2 records from Postgre Table");
Assert.AreEqual(recs.Count, 2, "Fetched 2 records from Couchbase bucket");

}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using GingerCore.Environments;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Testcontainers.Oracle;
using Oracle;
using Oracle.ManagedDataAccess.Client;

namespace GingerCoreNETUnitTest.DatabaseTest
{
[TestClass]
public class OracleIntegrationTests
{
private static readonly OracleContainer _oracleContainer = new OracleBuilder().Build();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Oracle container is instantiated without specifying an image version, which could lead to unpredictable test environments due to differences in Oracle versions. Specifying a version can help ensure consistent test results.

- private static readonly OracleContainer _oracleContainer = new OracleBuilder().Build();
+ private static readonly OracleContainer _oracleContainer = new OracleBuilder().WithImage("oracle/database:19.3.0-ee").Build();

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
private static readonly OracleContainer _oracleContainer = new OracleBuilder().Build();
private static readonly OracleContainer _oracleContainer = new OracleBuilder().WithImage("oracle/database:19.3.0-ee").Build();


[ClassInitialize]
public static async Task ClassInitialize(TestContext context)
{
await _oracleContainer.StartAsync();

Check failure on line 20 in Ginger/GingerCoreNETUnitTest/DatabaseTest/OracleIntegrationTests.cs

View workflow job for this annotation

GitHub Actions / Ginger Windows UnitTests

GingerCoreNETUnitTest.DatabaseTest.OracleIntegrationTests ► ShouldReturnTwoCustomers

Failed test found in: D:/a/TestResults/runneradmin_fv-az836-25_2024-03-22_17_08_41.trx Error: Class Initialization method GingerCoreNETUnitTest.DatabaseTest.OracleIntegrationTests.ClassInitialize threw exception. Docker.DotNet.DockerImageNotFoundException: Docker.DotNet.DockerImageNotFoundException: Docker API responded with status code=NotFound, response={"message":"No such image: gvenzl/oracle-xe:21.3.0-slim-faststart"} .
Raw output
Class Initialization method GingerCoreNETUnitTest.DatabaseTest.OracleIntegrationTests.ClassInitialize threw exception. Docker.DotNet.DockerImageNotFoundException: Docker.DotNet.DockerImageNotFoundException: Docker API responded with status code=NotFound, response={"message":"No such image: gvenzl/oracle-xe:21.3.0-slim-faststart"}
.
   at Docker.DotNet.ContainerOperations.<>c.<.cctor>b__30_1(HttpStatusCode statusCode, String responseBody)
   at Docker.DotNet.DockerClient.HandleIfErrorResponseAsync(HttpStatusCode statusCode, HttpResponseMessage response, IEnumerable`1 handlers)
   at Docker.DotNet.DockerClient.MakeRequestAsync(IEnumerable`1 errorHandlers, HttpMethod method, String path, IQueryString queryString, IRequestContent body, IDictionary`2 headers, TimeSpan timeout, CancellationToken token)
   at Docker.DotNet.ContainerOperations.CreateContainerAsync(CreateContainerParameters parameters, CancellationToken cancellationToken)
   at DotNet.Testcontainers.Clients.DockerContainerOperations.RunAsync(IContainerConfiguration configuration, CancellationToken ct)
   at DotNet.Testcontainers.Clients.TestcontainersClient.RunAsync(IContainerConfiguration configuration, CancellationToken ct)
   at DotNet.Testcontainers.Containers.DockerContainer.UnsafeCreateAsync(CancellationToken ct)
   at DotNet.Testcontainers.Containers.DockerContainer.StartAsync(CancellationToken ct)
   at GingerCoreNETUnitTest.DatabaseTest.OracleIntegrationTests.ClassInitialize(TestContext context) in D:\a\Ginger\Ginger\Ginger\GingerCoreNETUnitTest\DatabaseTest\OracleIntegrationTests.cs:line 20
await CreateTestData();

}

[TestCleanup]
public Task DisposeAsync()
{
return _oracleContainer.DisposeAsync().AsTask();
Comment on lines +25 to +28
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the PostgreSQL tests, the DisposeAsync method in Oracle tests should be marked as async and use the await keyword for disposal to align with best practices.

- public Task DisposeAsync()
+ public async Task DisposeAsync()

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
[TestCleanup]
public Task DisposeAsync()
{
return _oracleContainer.DisposeAsync().AsTask();
[TestCleanup]
public async Task DisposeAsync()
{
return _oracleContainer.DisposeAsync().AsTask();

}
public static async Task CreateTestData()
{
try
{
var scriptContent = "CREATE TABLE Customer (Id NUMBER PRIMARY KEY, Name varchar2(50));" +
"INSERT INTO Customer (Id, Name) VALUES (1, 'Mahesh'); " +
"INSERT INTO Customer (Id, Name) VALUES (2, 'kale');";
Comment on lines +34 to +36
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SQL script concatenation for creating and inserting data into the Customer table is prone to SQL injection risks. Use parameterized queries to mitigate this risk, even in test environments.

- var scriptContent = "CREATE TABLE Customer (Id NUMBER PRIMARY KEY, Name varchar2(50));" +
-                     "INSERT INTO Customer (Id, Name) VALUES (1, 'Mahesh'); " +
-                     "INSERT INTO Customer (Id, Name) VALUES (2, 'kale');";
+ var scriptContent = @"CREATE TABLE Customer (Id NUMBER PRIMARY KEY, Name varchar2(50));
+                       INSERT INTO Customer (Id, Name) VALUES (:Id1, :Name1);
+                       INSERT INTO Customer (Id, Name) VALUES (:Id2, :Name2);";
+ command.Parameters.Add(new OracleParameter(":Id1", 1));
+ command.Parameters.Add(new OracleParameter(":Name1", "Mahesh"));
+ command.Parameters.Add(new OracleParameter(":Id2", 2));
+ command.Parameters.Add(new OracleParameter(":Name2", "kale"));

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
var scriptContent = "CREATE TABLE Customer (Id NUMBER PRIMARY KEY, Name varchar2(50));" +
"INSERT INTO Customer (Id, Name) VALUES (1, 'Mahesh'); " +
"INSERT INTO Customer (Id, Name) VALUES (2, 'kale');";
var scriptContent = @"CREATE TABLE Customer (Id NUMBER PRIMARY KEY, Name varchar2(50));
INSERT INTO Customer (Id, Name) VALUES (:Id1, :Name1);
INSERT INTO Customer (Id, Name) VALUES (:Id2, :Name2);";
command.Parameters.Add(new OracleParameter(":Id1", 1));
command.Parameters.Add(new OracleParameter(":Name1", "Mahesh"));
command.Parameters.Add(new OracleParameter(":Id2", 2));
command.Parameters.Add(new OracleParameter(":Name2", "kale"));

//var execResult = await _oracleContainer.ExecScriptAsync(scriptContent)
// .ConfigureAwait(false);

Check warning on line 38 in Ginger/GingerCoreNETUnitTest/DatabaseTest/OracleIntegrationTests.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

Ginger/GingerCoreNETUnitTest/DatabaseTest/OracleIntegrationTests.cs#L38

Remove this commented out code.

using (var connection = new OracleConnection(_oracleContainer.GetConnectionString()))
{
await connection.OpenAsync();

// Example: Create a table and insert test data
using (var command = connection.CreateCommand())
{
command.CommandText = scriptContent;
await command.ExecuteNonQueryAsync();
}
}

}
catch (Exception ex)

Check notice on line 53 in Ginger/GingerCoreNETUnitTest/DatabaseTest/OracleIntegrationTests.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

Ginger/GingerCoreNETUnitTest/DatabaseTest/OracleIntegrationTests.cs#L53

Handle the exception or explain in a comment why it can be ignored.
{

Check warning on line 54 in Ginger/GingerCoreNETUnitTest/DatabaseTest/OracleIntegrationTests.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

Ginger/GingerCoreNETUnitTest/DatabaseTest/OracleIntegrationTests.cs#L54

Either remove or fill this block of code.

}
Comment on lines +53 to +56
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The catch block is empty, which can swallow exceptions and make debugging difficult. Consider logging the exception or rethrowing it after handling.

- catch (Exception ex)
- {
- 
- }
+ catch (Exception ex)
+ {
+     // Log the exception or handle it appropriately
+     throw;
+ }

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
catch (Exception ex)
{
}
catch (Exception ex)
{
// Log the exception or handle it appropriately
throw;
}

}

[TestMethod]
public void ShouldReturnTwoCustomers()
{
// Given
Database db = new Database();
DatabaseOperations databaseOperations = new DatabaseOperations(db);
db.DatabaseOperations = databaseOperations;
db.DBType = Database.eDBTypes.Oracle;
//ATT LS DB
db.ConnectionString = _oracleContainer.GetConnectionString();
Boolean connectionSuccessful = db.DatabaseOperations.Connect();


// When

List<object> recs = new List<object>();
if (connectionSuccessful)
{

string sqlQuery = "SELECT Id, Name FROM Customer";
recs = db.DatabaseOperations.FreeSQL(sqlQuery);

db.DatabaseOperations.CloseConnection();
}

//then
Assert.AreEqual(connectionSuccessful, true, "Connected Successfully to Oracle");
//Assert.IsNotNull(recs.Count, 0);

Check warning on line 86 in Ginger/GingerCoreNETUnitTest/DatabaseTest/OracleIntegrationTests.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

Ginger/GingerCoreNETUnitTest/DatabaseTest/OracleIntegrationTests.cs#L86

Remove this commented out code.
Assert.AreEqual(recs.Count, 2, "Fetched 2 records from Oracle Table");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using GingerCore.Environments;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Npgsql;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Testcontainers.PostgreSql;

namespace GingerCoreNETUnitTest.DatabaseTest
{
[TestClass]
public sealed class PostgreSqlIntegrationTests
{
private static readonly PostgreSqlContainer _postgres = new PostgreSqlBuilder()
.WithImage("postgres:15-alpine")
.Build();
Comment on lines +14 to +16
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of a hard-coded PostgreSQL image version (postgres:15-alpine) may lead to future compatibility issues or unexpected behavior if the image is updated or deprecated. Consider parameterizing the PostgreSQL version or using a more stable version tag.

- .WithImage("postgres:15-alpine")
+ .WithImage("postgres:latest")

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
private static readonly PostgreSqlContainer _postgres = new PostgreSqlBuilder()
.WithImage("postgres:15-alpine")
.Build();
private static readonly PostgreSqlContainer _postgres = new PostgreSqlBuilder()
.WithImage("postgres:latest")
.Build();


[ClassInitialize]
public static async Task ClassInitialize(TestContext context)
{
await _postgres.StartAsync();

Check failure on line 21 in Ginger/GingerCoreNETUnitTest/DatabaseTest/PostgreSqlIntegrationTests.cs

View workflow job for this annotation

GitHub Actions / Ginger Windows UnitTests

GingerCoreNETUnitTest.DatabaseTest.PostgreSqlIntegrationTests ► ShouldReturnTwoCustomers

Failed test found in: D:/a/TestResults/runneradmin_fv-az836-25_2024-03-22_17_08_41.trx Error: Class Initialization method GingerCoreNETUnitTest.DatabaseTest.PostgreSqlIntegrationTests.ClassInitialize threw exception. Docker.DotNet.DockerImageNotFoundException: Docker.DotNet.DockerImageNotFoundException: Docker API responded with status code=NotFound, response={"message":"No such image: postgres:15-alpine"} .
Raw output
Class Initialization method GingerCoreNETUnitTest.DatabaseTest.PostgreSqlIntegrationTests.ClassInitialize threw exception. Docker.DotNet.DockerImageNotFoundException: Docker.DotNet.DockerImageNotFoundException: Docker API responded with status code=NotFound, response={"message":"No such image: postgres:15-alpine"}
.
   at Docker.DotNet.ContainerOperations.<>c.<.cctor>b__30_1(HttpStatusCode statusCode, String responseBody)
   at Docker.DotNet.DockerClient.HandleIfErrorResponseAsync(HttpStatusCode statusCode, HttpResponseMessage response, IEnumerable`1 handlers)
   at Docker.DotNet.DockerClient.MakeRequestAsync(IEnumerable`1 errorHandlers, HttpMethod method, String path, IQueryString queryString, IRequestContent body, IDictionary`2 headers, TimeSpan timeout, CancellationToken token)
   at Docker.DotNet.ContainerOperations.CreateContainerAsync(CreateContainerParameters parameters, CancellationToken cancellationToken)
   at DotNet.Testcontainers.Clients.DockerContainerOperations.RunAsync(IContainerConfiguration configuration, CancellationToken ct)
   at DotNet.Testcontainers.Clients.TestcontainersClient.RunAsync(IContainerConfiguration configuration, CancellationToken ct)
   at DotNet.Testcontainers.Containers.DockerContainer.UnsafeCreateAsync(CancellationToken ct)
   at DotNet.Testcontainers.Containers.DockerContainer.StartAsync(CancellationToken ct)
   at GingerCoreNETUnitTest.DatabaseTest.PostgreSqlIntegrationTests.ClassInitialize(TestContext context) in D:\a\Ginger\Ginger\Ginger\GingerCoreNETUnitTest\DatabaseTest\PostgreSqlIntegrationTests.cs:line 21
await CreateTestData();

}

[TestCleanup]
public Task DisposeAsync()
{
return _postgres.DisposeAsync().AsTask();
Comment on lines +26 to +29
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DisposeAsync method is marked with the [TestCleanup] attribute but is not asynchronous. To align with best practices and the method's intent, consider marking this method as async and using the await keyword for the disposal operation.

- public Task DisposeAsync()
+ public async Task DisposeAsync()

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
[TestCleanup]
public Task DisposeAsync()
{
return _postgres.DisposeAsync().AsTask();
[TestCleanup]
public async Task DisposeAsync()
{
return _postgres.DisposeAsync().AsTask();

}
public static async Task CreateTestData()
{
using (var connection = new NpgsqlConnection(_postgres.GetConnectionString()))
{
await connection.OpenAsync();

// Create test data
using (var command = connection.CreateCommand())
{
command.CommandText = "CREATE TABLE Customer (Id serial PRIMARY KEY, Name varchar(255));" +
"INSERT INTO Customer (Name) VALUES ('1'), ('Mahesh kale');" +
"INSERT INTO Customer (Name) VALUES ('1'), ('Jinendra Ghodke');";
Comment on lines +40 to +42
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SQL command text concatenates strings to form a SQL query, which can be prone to SQL injection if dynamic data were ever to be included. Although this is a test environment setup, adopting best practices such as using parameterized queries is recommended to ensure security practices are followed consistently.

- command.CommandText = "CREATE TABLE Customer (Id serial PRIMARY KEY, Name varchar(255));" +
-                       "INSERT INTO Customer (Name) VALUES ('1'), ('Mahesh kale');" +
-                       "INSERT INTO Customer (Name) VALUES ('1'), ('Jinendra Ghodke');";
+ command.CommandText = @"CREATE TABLE Customer (Id serial PRIMARY KEY, Name varchar(255));
+                         INSERT INTO Customer (Name) VALUES (@Name1), (@Name2);
+                         INSERT INTO Customer (Name) VALUES (@Name3), (@Name4);";
+ command.Parameters.AddWithValue("@Name1", "1");
+ command.Parameters.AddWithValue("@Name2", "Mahesh kale");
+ command.Parameters.AddWithValue("@Name3", "1");
+ command.Parameters.AddWithValue("@Name4", "Jinendra Ghodke");

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
command.CommandText = "CREATE TABLE Customer (Id serial PRIMARY KEY, Name varchar(255));" +
"INSERT INTO Customer (Name) VALUES ('1'), ('Mahesh kale');" +
"INSERT INTO Customer (Name) VALUES ('1'), ('Jinendra Ghodke');";
command.CommandText = @"CREATE TABLE Customer (Id serial PRIMARY KEY, Name varchar(255));
INSERT INTO Customer (Name) VALUES (@Name1), (@Name2);
INSERT INTO Customer (Name) VALUES (@Name3), (@Name4);";
command.Parameters.AddWithValue("@Name1", "1");
command.Parameters.AddWithValue("@Name2", "Mahesh kale");
command.Parameters.AddWithValue("@Name3", "1");
command.Parameters.AddWithValue("@Name4", "Jinendra Ghodke");

await command.ExecuteNonQueryAsync();
}
}

}

[TestMethod]
public void ShouldReturnTwoCustomers()
{
// Given
Database db = new Database();
DatabaseOperations databaseOperations = new DatabaseOperations(db);
db.DatabaseOperations = databaseOperations;
db.DBType = Database.eDBTypes.PostgreSQL;
//ATT LS DB
db.ConnectionString = _postgres.GetConnectionString();
Boolean connectionSuccessful = db.DatabaseOperations.Connect();


// When

List<object> recs = new List<object>();
if (connectionSuccessful)
{

string sqlQuery = "SELECT Id, Name FROM Customer";
recs = db.DatabaseOperations.FreeSQL(sqlQuery);

db.DatabaseOperations.CloseConnection();
}

//then
Assert.AreEqual(connectionSuccessful, true, "Connected Successfully to PostgreSQL");
//Assert.IsNotNull(recs.Count, 0);

Check warning on line 76 in Ginger/GingerCoreNETUnitTest/DatabaseTest/PostgreSqlIntegrationTests.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

Ginger/GingerCoreNETUnitTest/DatabaseTest/PostgreSqlIntegrationTests.cs#L76

Remove this commented out code.
Assert.AreEqual(recs.Count,2, "Fetched 2 records from Postgre Table");
Comment on lines +76 to +77
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment //Assert.IsNotNull(recs.Count, 0); is commented out and seems to be incorrect as Assert.IsNotNull does not take a second argument for comparison. If the intent was to ensure recs is not null and has a count of 0, use Assert.IsNotNull(recs) and Assert.AreEqual(0, recs.Count) separately.

}
}
}
6 changes: 5 additions & 1 deletion Ginger/GingerCoreNETUnitTest/GingerCoreNETUnitTest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
</Content>
</ItemGroup>

<ItemGroup>
<ItemGroup>
<PackageReference Include="Ginger.ExecuterService.Contracts" Version="23.5.1" />
<PackageReference Include="GingerTestHelper" Version="2.0.2" />
<PackageReference Include="Microsoft.CodeAnalysis.Scripting" Version="3.7.0" />
Expand All @@ -94,6 +94,10 @@
<PackageReference Include="MSTest.TestAdapter" Version="2.1.2" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.2" />
<PackageReference Include="System.Resources.Extensions" Version="8.0.0" />
<PackageReference Include="Testcontainers" Version="3.7.0" />
<PackageReference Include="Testcontainers.Couchbase" Version="3.7.0" />
<PackageReference Include="Testcontainers.Oracle" Version="3.7.0" />
<PackageReference Include="Testcontainers.PostgreSql" Version="3.7.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ limitations under the License.
using GingerCore.Environments;
using GingerCoreNET.ALMLib;
using GingerCoreNET.SourceControl;
using Oracle.ManagedDataAccess.Client;
using System;
using System.Collections.Generic;
using System.Data.Common;
Expand Down Expand Up @@ -178,7 +179,7 @@ public IWebserviceDriverWindow GetWebserviceDriverWindow(BusinessFlow businessFl

public DbConnection GetOracleConnection(string ConnectionString)
{
throw new NotImplementedException();
return new OracleConnection(ConnectionString);
}

public bool IsSharedRepositoryItem(RepositoryItemBase item)
Expand Down
Loading