Skip to content

Commit

Permalink
[testcontainers#399] #IMPLEMENT 'assemblyName: DotNet.Testcontainers;…
Browse files Browse the repository at this point in the history
… function:

ExecScript
{Add function in the database modules to execute scripts}
  • Loading branch information
fabiogouw committed Oct 4, 2021
1 parent ef67133 commit d811057
Show file tree
Hide file tree
Showing 13 changed files with 274 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
namespace DotNet.Testcontainers.Containers
{
using System;
using System.Text;
using System.Threading.Tasks;
using DotNet.Testcontainers.Configurations;
using DotNet.Testcontainers.Containers.Modules;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;

/// <inheritdoc cref="TestcontainerDatabase" />
[PublicAPI]
public sealed class CouchbaseTestcontainer : TestcontainerDatabase
public sealed class CouchbaseTestcontainer : TestcontainerDatabase, IScriptExecution
{
private const string CouchbaseCli = "/opt/couchbase/bin/couchbase-cli";

Expand Down Expand Up @@ -50,5 +53,18 @@ public Task<ExecResult> FlushBucket(string bucket)
var flushBucketCommand = $"yes | {CouchbaseCli} bucket-flush -c 127.0.0.1:8091 --username {this.Username} --password {this.Password} --bucket {bucket}";
return this.ExecAsync(new[] { "/bin/sh", "-c", flushBucketCommand });
}

/// <summary>
/// Executes a N1QL script in the database container.
/// </summary>
/// <param name="scriptContent">The content of the N1QL script to be executed.</param>
/// <returns>Task that completes when the script has been executed.</returns>
public async Task<ExecResult> ExecScript(string scriptContent)
{
var randomFileName = $"/{Guid.NewGuid()}.n1ql";
await this.CopyFileAsync(randomFileName, Encoding.ASCII.GetBytes(scriptContent));
var execScriptCommand = $"cbq -user {this.Username} -password {this.Password} -file={randomFileName}";
return await this.ExecAsync(new[] { "/bin/sh", "-c", execScriptCommand });
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
namespace DotNet.Testcontainers.Containers
{
using System;
using System.Text;
using System.Threading.Tasks;
using DotNet.Testcontainers.Configurations;
using DotNet.Testcontainers.Containers.Modules;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;

/// <inheritdoc cref="TestcontainerDatabase" />
[PublicAPI]
public sealed class MsSqlTestcontainer : TestcontainerDatabase
public sealed class MsSqlTestcontainer : TestcontainerDatabase, IScriptExecution
{
/// <summary>
/// Initializes a new instance of the <see cref="MsSqlTestcontainer" /> class.
Expand All @@ -21,5 +25,14 @@ internal MsSqlTestcontainer(ITestcontainersConfiguration configuration, ILogger
/// <inheritdoc />
public override string ConnectionString
=> $"Server={this.Hostname},{this.Port};Database={this.Database};User Id={this.Username};Password={this.Password};";

/// <inheritdoc />
public async Task<ExecResult> ExecScript(string scriptContent)
{
var randomFileName = $"/{Guid.NewGuid()}.sql";
await this.CopyFileAsync(randomFileName, Encoding.ASCII.GetBytes(scriptContent));
var execScriptCommand = $"/opt/mssql-tools/bin/sqlcmd -b -r1 -S {this.Hostname} -U {this.Username} -P \"{this.Password}\" -i {randomFileName}";
return await this.ExecAsync(new[] { "/bin/sh", "-c", execScriptCommand });
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
namespace DotNet.Testcontainers.Containers
{
using System;
using System.Text;
using System.Threading.Tasks;
using DotNet.Testcontainers.Configurations;
using DotNet.Testcontainers.Containers.Modules;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;

/// <inheritdoc cref="TestcontainerDatabase" />
[PublicAPI]
public sealed class MySqlTestcontainer : TestcontainerDatabase
public sealed class MySqlTestcontainer : TestcontainerDatabase, IScriptExecution
{
/// <summary>
/// Initializes a new instance of the <see cref="MySqlTestcontainer" /> class.
Expand All @@ -21,5 +25,14 @@ internal MySqlTestcontainer(ITestcontainersConfiguration configuration, ILogger
/// <inheritdoc />
public override string ConnectionString
=> $"Server={this.Hostname};Port={this.Port};Database={this.Database};Uid={this.Username};Pwd={this.Password};";

/// <inheritdoc />
public async Task<ExecResult> ExecScript(string scriptContent)
{
var randomFileName = $"/{Guid.NewGuid()}.sql";
await this.CopyFileAsync(randomFileName, Encoding.ASCII.GetBytes(scriptContent));
var execScriptCommand = $"mysql -u{this.Username} -p{this.Password} {this.Database} < {randomFileName}";
return await this.ExecAsync(new[] { "/bin/sh", "-c", execScriptCommand });
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
namespace DotNet.Testcontainers.Containers
namespace DotNet.Testcontainers.Containers
{
using System;
using System.Text;
using System.Threading.Tasks;
using DotNet.Testcontainers.Configurations;
using DotNet.Testcontainers.Containers.Modules;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;

/// <inheritdoc cref="TestcontainerDatabase" />
[PublicAPI]
public sealed class OracleTestcontainer : TestcontainerDatabase
public sealed class OracleTestcontainer : TestcontainerDatabase, IScriptExecution
{
/// <summary>
/// Initializes a new instance of the <see cref="OracleTestcontainer" /> class.
Expand All @@ -21,5 +25,14 @@ internal OracleTestcontainer(ITestcontainersConfiguration configuration, ILogger
/// <inheritdoc />
public override string ConnectionString
=> $"Data Source={this.Hostname}:{this.Port};User id={this.Username};Password={this.Password};";

/// <inheritdoc />
public async Task<ExecResult> ExecScript(string scriptContent)
{
var randomFileName = $"/{Guid.NewGuid()}.sql";
await this.CopyFileAsync(randomFileName, Encoding.ASCII.GetBytes(scriptContent));
var execScriptCommand = $"exit | $ORACLE_HOME/bin/sqlplus -S {this.Username}/{this.Password}@{this.Hostname} @{randomFileName}";
return await this.ExecAsync(new[] { "/bin/sh", "-c", execScriptCommand });
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
namespace DotNet.Testcontainers.Containers
{
using System;
using System.Text;
using System.Threading.Tasks;
using DotNet.Testcontainers.Configurations;
using DotNet.Testcontainers.Containers.Modules;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;

/// <inheritdoc cref="TestcontainerDatabase" />
[PublicAPI]
public sealed class PostgreSqlTestcontainer : TestcontainerDatabase
public sealed class PostgreSqlTestcontainer : TestcontainerDatabase, IScriptExecution
{
/// <summary>
/// Initializes a new instance of the <see cref="PostgreSqlTestcontainer" /> class.
Expand All @@ -21,5 +25,14 @@ internal PostgreSqlTestcontainer(ITestcontainersConfiguration configuration, ILo
/// <inheritdoc />
public override string ConnectionString
=> $"Server={this.Hostname};Port={this.Port};Database={this.Database};User Id={this.Username};Password={this.Password};";

/// <inheritdoc />
public async Task<ExecResult> ExecScript(string scriptContent)
{
var randomFileName = $"/{Guid.NewGuid()}.sql";
await this.CopyFileAsync(randomFileName, Encoding.ASCII.GetBytes(scriptContent));
var execScriptCommand = $"psql -U {this.Username} -d {this.Database} -a -f {randomFileName}";
return await this.ExecAsync(new[] { "/bin/sh", "-c", execScriptCommand });
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
namespace DotNet.Testcontainers.Containers
{
using System;
using System.Text;
using System.Threading.Tasks;
using DotNet.Testcontainers.Configurations;
using DotNet.Testcontainers.Containers.Modules;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;

/// <inheritdoc cref="TestcontainerDatabase" />
[PublicAPI]
public sealed class RedisTestcontainer : TestcontainerDatabase
public sealed class RedisTestcontainer : TestcontainerDatabase, IScriptExecution
{
/// <summary>
/// Initializes a new instance of the <see cref="RedisTestcontainer" /> class.
Expand All @@ -21,5 +25,18 @@ internal RedisTestcontainer(ITestcontainersConfiguration configuration, ILogger
/// <inheritdoc />
public override string ConnectionString
=> $"{this.Hostname}:{this.Port}";

/// <summary>
/// Executes a Lua script in the database container.
/// </summary>
/// <param name="scriptContent">The content of the Lua script to be executed.</param>
/// <returns>Task that completes when the script has been executed.</returns>
public async Task<ExecResult> ExecScript(string scriptContent)
{
var randomFileName = $"/{Guid.NewGuid()}.lua";
await this.CopyFileAsync(randomFileName, Encoding.ASCII.GetBytes(scriptContent));
var execScriptCommand = $"redis-cli --no-raw --eval {randomFileName}";
return await this.ExecAsync(new[] { "/bin/sh", "-c", execScriptCommand });
}
}
}
19 changes: 19 additions & 0 deletions src/DotNet.Testcontainers/Containers/Modules/IScriptExecution.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace DotNet.Testcontainers.Containers.Modules
{
using System.Threading.Tasks;
using JetBrains.Annotations;

/// <summary>
/// Define the contract for database modules that has the script execution capability.
/// </summary>
public interface IScriptExecution
{
/// <summary>
/// Executes a script in the database container.
/// </summary>
/// <param name="scriptContent">The content of the script to be executed.</param>
/// <returns>Task that completes when the script has been executed.</returns>
[PublicAPI]
Task<ExecResult> ExecScript(string scriptContent);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,27 @@ public void ShouldThrowArgumentOutOfRangeExceptionWhenClusterAnalyticsRamSizeIsN
Assert.Equal("Couchbase ClusterAnalyticsRamSize ram size can not be less than 1024 MB. (Parameter 'ClusterAnalyticsRamSize')", exception.Message);
}

[Fact]
public async Task ShouldExecuteCommandsWhenScriptExecuted()
{
// Given
var script = @"
CREATE PRIMARY INDEX ON `Sample`;
INSERT INTO `Sample` (KEY,VALUE)
VALUES (""mykey"", { ""name"": ""MyName"", ""type"": ""MyType""});
SELECT * FROM `Sample`;
";

// When
await this.couchbaseFixture.Container.ExecScript(script)
.ConfigureAwait(false);
var results = await this.couchbaseFixture.Container.ExecScript("SELECT * FROM `Sample`")
.ConfigureAwait(false);

// Then
Assert.Contains("MyName", results.Stdout);
}

private readonly struct Customer
{
public Customer(string name, int age)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,44 @@ public void CannotSetUsername()
var mssql = new MsSqlTestcontainerConfiguration();
Assert.Throws<NotImplementedException>(() => mssql.Username = string.Empty);
}

[Fact]
public async Task ScriptExecuted()
{
// Given
var script = @"
CREATE DATABASE testcontainers;
GO
USE testcontainers;
GO
CREATE TABLE MyTable (
id INT,
name VARCHAR(30) NOT NULL
);
GO
INSERT INTO MyTable (id, name) VALUES (1, 'MyName');
SELECT * FROM MyTable;
";

// When
var results = await this.msSqlFixture.Container.ExecScript(script);

// Then
Assert.Contains("MyName", results.Stdout);
}

[Fact]
public async Task ScriptThrowsError()
{
// Given
var script = "invalid SQL command";

// When
var results = await this.msSqlFixture.Container.ExecScript(script);

// Then
Assert.NotEqual(0, results.ExitCode);
Assert.NotEqual(string.Empty, results.Stderr);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,41 @@ await connection.OpenAsync()
// Then
Assert.Equal(ConnectionState.Open, connection.State);
}

[Fact]
public async Task ScriptExecuted()
{
// Given
var script = @"
CREATE TABLE MyTable (
id INT(6) UNSIGNED PRIMARY KEY,
name VARCHAR(30) NOT NULL
);
GO
INSERT INTO MyTable (id, name) VALUES (1, 'MyName');
GO
SELECT * FROM MyTable;
";

// When
var results = await this.mySqlFixture.Container.ExecScript(script);

// Then
Assert.Contains("MyName", results.Stdout);
}

[Fact]
public async Task ScriptThrowsError()
{
// Given
var script = "invalid SQL command";

// When
var results = await this.mySqlFixture.Container.ExecScript(script);

// Then
Assert.NotEqual(0, results.ExitCode);
Assert.NotEqual(string.Empty, results.Stderr);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace DotNet.Testcontainers.Tests.Unit
namespace DotNet.Testcontainers.Tests.Unit
{
using System;
using System.Data;
Expand Down Expand Up @@ -51,5 +51,26 @@ public void CannotSetPassword()
var oracle = new OracleTestcontainerConfiguration();
Assert.Throws<NotImplementedException>(() => oracle.Password = string.Empty);
}

[Fact]
public async Task ScriptExecuted()
{
// Given
var script = @"
CREATE TABLE MyTable (
id INT,
name VARCHAR(30) NOT NULL
);
GO
INSERT INTO MyTable (id, name) VALUES (1, 'MyName');
SELECT * FROM MyTable;
";

// When
var results = await this.oracleFixture.Container.ExecScript(script);

// Then
Assert.Contains("MyName", results.Stdout);
}
}
}
Loading

0 comments on commit d811057

Please sign in to comment.