From fa9bf37f47237cdc4f4baa65340b9b12dc43682d Mon Sep 17 00:00:00 2001 From: Shir Avneri Date: Fri, 1 Dec 2023 00:38:43 +0200 Subject: [PATCH 1/2] feat: Add ArangoDB module --- Testcontainers.sln | 14 +++ src/Testcontainers.ArangoDb/.editorconfig | 1 + .../ArangoDbBuilder.cs | 92 +++++++++++++++++++ .../ArangoDbConfiguration.cs | 62 +++++++++++++ .../ArangoDbContainer.cs | 25 +++++ .../Testcontainers.ArangoDb.csproj | 12 +++ src/Testcontainers.ArangoDb/Usings.cs | 8 ++ .../.editorconfig | 1 + .../ArangoDbContainerTest.cs | 33 +++++++ .../Testcontainers.ArangoDb.Tests.csproj | 18 ++++ tests/Testcontainers.ArangoDb.Tests/Usings.cs | 7 ++ 11 files changed, 273 insertions(+) create mode 100644 src/Testcontainers.ArangoDb/.editorconfig create mode 100644 src/Testcontainers.ArangoDb/ArangoDbBuilder.cs create mode 100644 src/Testcontainers.ArangoDb/ArangoDbConfiguration.cs create mode 100644 src/Testcontainers.ArangoDb/ArangoDbContainer.cs create mode 100644 src/Testcontainers.ArangoDb/Testcontainers.ArangoDb.csproj create mode 100644 src/Testcontainers.ArangoDb/Usings.cs create mode 100644 tests/Testcontainers.ArangoDb.Tests/.editorconfig create mode 100644 tests/Testcontainers.ArangoDb.Tests/ArangoDbContainerTest.cs create mode 100644 tests/Testcontainers.ArangoDb.Tests/Testcontainers.ArangoDb.Tests.csproj create mode 100644 tests/Testcontainers.ArangoDb.Tests/Usings.cs diff --git a/Testcontainers.sln b/Testcontainers.sln index c8163da29..7507b0faa 100644 --- a/Testcontainers.sln +++ b/Testcontainers.sln @@ -15,6 +15,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{7164F1FB EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.ActiveMq", "src\Testcontainers.ActiveMq\Testcontainers.ActiveMq.csproj", "{5365F780-0E6C-41F0-B1B9-7DC34368F80C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.ArangoDb", "src\Testcontainers.ArangoDb\Testcontainers.ArangoDb.csproj", "{AB9C1563-07C7-4685-BACD-BB1FF64B3611}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Azurite", "src\Testcontainers.Azurite\Testcontainers.Azurite.csproj", "{3F2E254F-C203-43FD-A078-DC3E2CBC0F9F}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.BigQuery", "src\Testcontainers.BigQuery\Testcontainers.BigQuery.csproj", "{A9FF9C7F-BBA0-4B44-90B7-48A60F9E00F3}" @@ -93,6 +95,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers", "src\Testc EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.ActiveMq.Tests", "tests\Testcontainers.ActiveMq.Tests\Testcontainers.ActiveMq.Tests.csproj", "{AB93C67F-0A53-4525-AE6C-29B065820ABE}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.ArangoDb.Tests", "tests\Testcontainers.ArangoDb.Tests\Testcontainers.ArangoDb.Tests.csproj", "{8E1E0A6D-EEBB-4455-B8E8-A55AF9B2062C}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Azurite.Tests", "tests\Testcontainers.Azurite.Tests\Testcontainers.Azurite.Tests.csproj", "{B272FDDE-5E01-425D-B9E1-10FF883DDAAA}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.BigQuery.Tests", "tests\Testcontainers.BigQuery.Tests\Testcontainers.BigQuery.Tests.csproj", "{03E60673-078A-4508-99AD-8537CE6F78F1}" @@ -192,6 +196,10 @@ Global {5365F780-0E6C-41F0-B1B9-7DC34368F80C}.Debug|Any CPU.Build.0 = Debug|Any CPU {5365F780-0E6C-41F0-B1B9-7DC34368F80C}.Release|Any CPU.ActiveCfg = Release|Any CPU {5365F780-0E6C-41F0-B1B9-7DC34368F80C}.Release|Any CPU.Build.0 = Release|Any CPU + {AB9C1563-07C7-4685-BACD-BB1FF64B3611}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AB9C1563-07C7-4685-BACD-BB1FF64B3611}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AB9C1563-07C7-4685-BACD-BB1FF64B3611}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AB9C1563-07C7-4685-BACD-BB1FF64B3611}.Release|Any CPU.Build.0 = Release|Any CPU {3F2E254F-C203-43FD-A078-DC3E2CBC0F9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3F2E254F-C203-43FD-A078-DC3E2CBC0F9F}.Debug|Any CPU.Build.0 = Debug|Any CPU {3F2E254F-C203-43FD-A078-DC3E2CBC0F9F}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -348,6 +356,10 @@ Global {AB93C67F-0A53-4525-AE6C-29B065820ABE}.Debug|Any CPU.Build.0 = Debug|Any CPU {AB93C67F-0A53-4525-AE6C-29B065820ABE}.Release|Any CPU.ActiveCfg = Release|Any CPU {AB93C67F-0A53-4525-AE6C-29B065820ABE}.Release|Any CPU.Build.0 = Release|Any CPU + {8E1E0A6D-EEBB-4455-B8E8-A55AF9B2062C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8E1E0A6D-EEBB-4455-B8E8-A55AF9B2062C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8E1E0A6D-EEBB-4455-B8E8-A55AF9B2062C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8E1E0A6D-EEBB-4455-B8E8-A55AF9B2062C}.Release|Any CPU.Build.0 = Release|Any CPU {B272FDDE-5E01-425D-B9E1-10FF883DDAAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B272FDDE-5E01-425D-B9E1-10FF883DDAAA}.Debug|Any CPU.Build.0 = Debug|Any CPU {B272FDDE-5E01-425D-B9E1-10FF883DDAAA}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -523,6 +535,7 @@ Global EndGlobalSection GlobalSection(NestedProjects) = preSolution {5365F780-0E6C-41F0-B1B9-7DC34368F80C} = {673F23AE-7694-4BB9-ABD4-136D6C13634E} + {AB9C1563-07C7-4685-BACD-BB1FF64B3611} = {673F23AE-7694-4BB9-ABD4-136D6C13634E} {3F2E254F-C203-43FD-A078-DC3E2CBC0F9F} = {673F23AE-7694-4BB9-ABD4-136D6C13634E} {A9FF9C7F-BBA0-4B44-90B7-48A60F9E00F3} = {673F23AE-7694-4BB9-ABD4-136D6C13634E} {302EC1E0-AE75-4E99-A6BF-524F35338BC8} = {673F23AE-7694-4BB9-ABD4-136D6C13634E} @@ -562,6 +575,7 @@ Global {64A87DE5-29B0-4A54-9E74-560484D8C7C0} = {673F23AE-7694-4BB9-ABD4-136D6C13634E} {EC76857B-A3B8-4B7A-A1B0-8D867A4D1733} = {673F23AE-7694-4BB9-ABD4-136D6C13634E} {AB93C67F-0A53-4525-AE6C-29B065820ABE} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF} + {8E1E0A6D-EEBB-4455-B8E8-A55AF9B2062C} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF} {B272FDDE-5E01-425D-B9E1-10FF883DDAAA} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF} {03E60673-078A-4508-99AD-8537CE6F78F1} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF} {2E7B92E3-8526-4706-90F3-00F0F5C47C37} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF} diff --git a/src/Testcontainers.ArangoDb/.editorconfig b/src/Testcontainers.ArangoDb/.editorconfig new file mode 100644 index 000000000..6f066619d --- /dev/null +++ b/src/Testcontainers.ArangoDb/.editorconfig @@ -0,0 +1 @@ +root = true \ No newline at end of file diff --git a/src/Testcontainers.ArangoDb/ArangoDbBuilder.cs b/src/Testcontainers.ArangoDb/ArangoDbBuilder.cs new file mode 100644 index 000000000..d9d192566 --- /dev/null +++ b/src/Testcontainers.ArangoDb/ArangoDbBuilder.cs @@ -0,0 +1,92 @@ +namespace Testcontainers.ArangoDb; + +/// +[PublicAPI] +public sealed class ArangoDbBuilder : ContainerBuilder +{ + public const string ArangoDbImage = "arangodb:3.11.5"; + + public const ushort ArangoDbPort = 8529; + + public const string DefaultUsername = "root"; + + public const string DefaultPassword = "root"; + + /// + /// Initializes a new instance of the class. + /// + public ArangoDbBuilder() + : this(new ArangoDbConfiguration()) + { + DockerResourceConfiguration = Init().DockerResourceConfiguration; + } + + /// + /// Initializes a new instance of the class. + /// + /// The Docker resource configuration. + private ArangoDbBuilder(ArangoDbConfiguration resourceConfiguration) + : base(resourceConfiguration) + { + DockerResourceConfiguration = resourceConfiguration; + } + + /// + protected override ArangoDbConfiguration DockerResourceConfiguration { get; } + + /// + /// Sets the ArangoDb password. + /// + /// The ArangoDb password. + /// A configured instance of . + public ArangoDbBuilder WithPassword(string password) + { + return Merge(DockerResourceConfiguration, new ArangoDbConfiguration(password: password)) + .WithEnvironment("ARANGO_ROOT_PASSWORD", password); + } + + /// + public override ArangoDbContainer Build() + { + Validate(); + return new ArangoDbContainer(DockerResourceConfiguration, TestcontainersSettings.Logger); + } + + /// + protected override ArangoDbBuilder Init() + { + return base.Init() + .WithImage(ArangoDbImage) + .WithPortBinding(ArangoDbPort, true) + .WithPassword(DefaultPassword) + .WithWaitStrategy(Wait.ForUnixContainer().UntilMessageIsLogged("Have fun!")); + } + + /// + protected override void Validate() + { + base.Validate(); + + _ = Guard.Argument(DockerResourceConfiguration.Password, nameof(DockerResourceConfiguration.Password)) + .NotNull() + .NotEmpty(); + } + + /// + protected override ArangoDbBuilder Clone(IResourceConfiguration resourceConfiguration) + { + return Merge(DockerResourceConfiguration, new ArangoDbConfiguration(resourceConfiguration)); + } + + /// + protected override ArangoDbBuilder Clone(IContainerConfiguration resourceConfiguration) + { + return Merge(DockerResourceConfiguration, new ArangoDbConfiguration(resourceConfiguration)); + } + + /// + protected override ArangoDbBuilder Merge(ArangoDbConfiguration oldValue, ArangoDbConfiguration newValue) + { + return new ArangoDbBuilder(new ArangoDbConfiguration(oldValue, newValue)); + } +} \ No newline at end of file diff --git a/src/Testcontainers.ArangoDb/ArangoDbConfiguration.cs b/src/Testcontainers.ArangoDb/ArangoDbConfiguration.cs new file mode 100644 index 000000000..aa71236e9 --- /dev/null +++ b/src/Testcontainers.ArangoDb/ArangoDbConfiguration.cs @@ -0,0 +1,62 @@ +namespace Testcontainers.ArangoDb; + +/// +[PublicAPI] +public sealed class ArangoDbConfiguration : ContainerConfiguration +{ + /// + /// Initializes a new instance of the class. + /// + /// The ArangoDb password. + public ArangoDbConfiguration( + string password = null) + { + Password = password; + } + + /// + /// Initializes a new instance of the class. + /// + /// The Docker resource configuration. + public ArangoDbConfiguration(IResourceConfiguration resourceConfiguration) + : base(resourceConfiguration) + { + // Passes the configuration upwards to the base implementations to create an updated immutable copy. + } + + /// + /// Initializes a new instance of the class. + /// + /// The Docker resource configuration. + public ArangoDbConfiguration(IContainerConfiguration resourceConfiguration) + : base(resourceConfiguration) + { + // Passes the configuration upwards to the base implementations to create an updated immutable copy. + } + + /// + /// Initializes a new instance of the class. + /// + /// The Docker resource configuration. + public ArangoDbConfiguration(ArangoDbConfiguration resourceConfiguration) + : this(new ArangoDbConfiguration(), resourceConfiguration) + { + // Passes the configuration upwards to the base implementations to create an updated immutable copy. + } + + /// + /// Initializes a new instance of the class. + /// + /// The old Docker resource configuration. + /// The new Docker resource configuration. + public ArangoDbConfiguration(ArangoDbConfiguration oldValue, ArangoDbConfiguration newValue) + : base(oldValue, newValue) + { + Password = BuildConfiguration.Combine(oldValue.Password, newValue.Password); + } + + /// + /// Gets the ArangoDb password. + /// + public string Password { get; } +} \ No newline at end of file diff --git a/src/Testcontainers.ArangoDb/ArangoDbContainer.cs b/src/Testcontainers.ArangoDb/ArangoDbContainer.cs new file mode 100644 index 000000000..45ac0d1d7 --- /dev/null +++ b/src/Testcontainers.ArangoDb/ArangoDbContainer.cs @@ -0,0 +1,25 @@ +namespace Testcontainers.ArangoDb; + +/// +[PublicAPI] +public sealed class ArangoDbContainer : DockerContainer +{ + /// + /// Initializes a new instance of the class. + /// + /// The container configuration. + /// The logger. + public ArangoDbContainer(ArangoDbConfiguration configuration, ILogger logger) + : base(configuration, logger) + { + } + + /// + /// Gets the transport address. + /// + /// The transport address. + public string GetTransportAddress() + { + return new UriBuilder("http://", Hostname, GetMappedPublicPort(ArangoDbBuilder.ArangoDbPort)).ToString(); + } +} \ No newline at end of file diff --git a/src/Testcontainers.ArangoDb/Testcontainers.ArangoDb.csproj b/src/Testcontainers.ArangoDb/Testcontainers.ArangoDb.csproj new file mode 100644 index 000000000..7048179d1 --- /dev/null +++ b/src/Testcontainers.ArangoDb/Testcontainers.ArangoDb.csproj @@ -0,0 +1,12 @@ + + + netstandard2.0;netstandard2.1 + latest + + + + + + + + \ No newline at end of file diff --git a/src/Testcontainers.ArangoDb/Usings.cs b/src/Testcontainers.ArangoDb/Usings.cs new file mode 100644 index 000000000..c6ee33b57 --- /dev/null +++ b/src/Testcontainers.ArangoDb/Usings.cs @@ -0,0 +1,8 @@ +global using System; +global using Docker.DotNet.Models; +global using DotNet.Testcontainers; +global using DotNet.Testcontainers.Builders; +global using DotNet.Testcontainers.Configurations; +global using DotNet.Testcontainers.Containers; +global using JetBrains.Annotations; +global using Microsoft.Extensions.Logging; \ No newline at end of file diff --git a/tests/Testcontainers.ArangoDb.Tests/.editorconfig b/tests/Testcontainers.ArangoDb.Tests/.editorconfig new file mode 100644 index 000000000..6f066619d --- /dev/null +++ b/tests/Testcontainers.ArangoDb.Tests/.editorconfig @@ -0,0 +1 @@ +root = true \ No newline at end of file diff --git a/tests/Testcontainers.ArangoDb.Tests/ArangoDbContainerTest.cs b/tests/Testcontainers.ArangoDb.Tests/ArangoDbContainerTest.cs new file mode 100644 index 000000000..7c5e3d811 --- /dev/null +++ b/tests/Testcontainers.ArangoDb.Tests/ArangoDbContainerTest.cs @@ -0,0 +1,33 @@ +namespace Testcontainers.ArangoDb; + +public sealed class ArangoDbContainerTest : IAsyncLifetime +{ + private readonly ArangoDbContainer _arangoDbContainer = new ArangoDbBuilder().Build(); + + public Task InitializeAsync() + { + return _arangoDbContainer.StartAsync(); + } + + public Task DisposeAsync() + { + return _arangoDbContainer.DisposeAsync().AsTask(); + } + + [Fact] + [Trait(nameof(DockerCli.DockerPlatform), nameof(DockerCli.DockerPlatform.Linux))] + public async Task RetrievesDatabases() + { + // Given + var address = new Uri(_arangoDbContainer.GetTransportAddress()); + using var transport = HttpApiTransport.UsingBasicAuth(address, "_system", ArangoDbBuilder.DefaultUsername, ArangoDbBuilder.DefaultPassword); + using var client = new ArangoDBClient(transport); + + // When + var response = await client.Database.GetDatabasesAsync() + .ConfigureAwait(false); + + // Then + Assert.Equal(HttpStatusCode.OK, response.Code); + } +} \ No newline at end of file diff --git a/tests/Testcontainers.ArangoDb.Tests/Testcontainers.ArangoDb.Tests.csproj b/tests/Testcontainers.ArangoDb.Tests/Testcontainers.ArangoDb.Tests.csproj new file mode 100644 index 000000000..b2e8bf3c8 --- /dev/null +++ b/tests/Testcontainers.ArangoDb.Tests/Testcontainers.ArangoDb.Tests.csproj @@ -0,0 +1,18 @@ + + + net8.0 + false + false + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/Testcontainers.ArangoDb.Tests/Usings.cs b/tests/Testcontainers.ArangoDb.Tests/Usings.cs new file mode 100644 index 000000000..50a456699 --- /dev/null +++ b/tests/Testcontainers.ArangoDb.Tests/Usings.cs @@ -0,0 +1,7 @@ +global using System; +global using System.Net; +global using System.Threading.Tasks; +global using DotNet.Testcontainers.Commons; +global using ArangoDBNetStandard; +global using ArangoDBNetStandard.Transport.Http; +global using Xunit; \ No newline at end of file From f42f0c7b68a987976613aae93bab749b0915bd1f Mon Sep 17 00:00:00 2001 From: Andre Hofmeister <9199345+HofmeisterAn@users.noreply.github.com> Date: Sat, 2 Dec 2023 15:45:04 +0100 Subject: [PATCH 2/2] chore: Remove csproj UTF-8 BOM --- src/Testcontainers.ArangoDb/ArangoDbContainer.cs | 2 +- .../ArangoDbContainerTest.cs | 4 +++- .../Testcontainers.ArangoDb.Tests.csproj | 16 ++++++++-------- tests/Testcontainers.ArangoDb.Tests/Usings.cs | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/Testcontainers.ArangoDb/ArangoDbContainer.cs b/src/Testcontainers.ArangoDb/ArangoDbContainer.cs index 45ac0d1d7..5568ccaa3 100644 --- a/src/Testcontainers.ArangoDb/ArangoDbContainer.cs +++ b/src/Testcontainers.ArangoDb/ArangoDbContainer.cs @@ -20,6 +20,6 @@ public ArangoDbContainer(ArangoDbConfiguration configuration, ILogger logger) /// The transport address. public string GetTransportAddress() { - return new UriBuilder("http://", Hostname, GetMappedPublicPort(ArangoDbBuilder.ArangoDbPort)).ToString(); + return new UriBuilder(Uri.UriSchemeHttp, Hostname, GetMappedPublicPort(ArangoDbBuilder.ArangoDbPort)).ToString(); } } \ No newline at end of file diff --git a/tests/Testcontainers.ArangoDb.Tests/ArangoDbContainerTest.cs b/tests/Testcontainers.ArangoDb.Tests/ArangoDbContainerTest.cs index 7c5e3d811..9d8c6a71e 100644 --- a/tests/Testcontainers.ArangoDb.Tests/ArangoDbContainerTest.cs +++ b/tests/Testcontainers.ArangoDb.Tests/ArangoDbContainerTest.cs @@ -20,7 +20,9 @@ public async Task RetrievesDatabases() { // Given var address = new Uri(_arangoDbContainer.GetTransportAddress()); - using var transport = HttpApiTransport.UsingBasicAuth(address, "_system", ArangoDbBuilder.DefaultUsername, ArangoDbBuilder.DefaultPassword); + + using var transport = HttpApiTransport.UsingBasicAuth(address, ArangoDbBuilder.DefaultUsername, ArangoDbBuilder.DefaultPassword); + using var client = new ArangoDBClient(transport); // When diff --git a/tests/Testcontainers.ArangoDb.Tests/Testcontainers.ArangoDb.Tests.csproj b/tests/Testcontainers.ArangoDb.Tests/Testcontainers.ArangoDb.Tests.csproj index b2e8bf3c8..b66e4623e 100644 --- a/tests/Testcontainers.ArangoDb.Tests/Testcontainers.ArangoDb.Tests.csproj +++ b/tests/Testcontainers.ArangoDb.Tests/Testcontainers.ArangoDb.Tests.csproj @@ -1,18 +1,18 @@ - + net8.0 false false - - - - - + + + + + - - + + \ No newline at end of file diff --git a/tests/Testcontainers.ArangoDb.Tests/Usings.cs b/tests/Testcontainers.ArangoDb.Tests/Usings.cs index 50a456699..6ef74341d 100644 --- a/tests/Testcontainers.ArangoDb.Tests/Usings.cs +++ b/tests/Testcontainers.ArangoDb.Tests/Usings.cs @@ -1,7 +1,7 @@ global using System; global using System.Net; global using System.Threading.Tasks; -global using DotNet.Testcontainers.Commons; global using ArangoDBNetStandard; global using ArangoDBNetStandard.Transport.Http; +global using DotNet.Testcontainers.Commons; global using Xunit; \ No newline at end of file