diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml
index 036861069..45542b95d 100644
--- a/.github/workflows/cicd.yml
+++ b/.github/workflows/cicd.yml
@@ -78,6 +78,7 @@ jobs:
{ name: "Testcontainers.RavenDb", runs-on: "ubuntu-22.04" },
{ name: "Testcontainers.Redis", runs-on: "ubuntu-22.04" },
{ name: "Testcontainers.Redpanda", runs-on: "ubuntu-22.04" },
+ { name: "Testcontainers.Seq", runs-on: "ubuntu-22.04" },
{ name: "Testcontainers.WebDriver", runs-on: "ubuntu-22.04" },
{ name: "Testcontainers.Xunit", runs-on: "ubuntu-22.04" }
]
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 813d398cf..004f60648 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -9,6 +9,7 @@
+
@@ -23,6 +24,8 @@
+
+
diff --git a/Testcontainers.sln b/Testcontainers.sln
index 1caef1ce5..6cbd1c779 100644
--- a/Testcontainers.sln
+++ b/Testcontainers.sln
@@ -201,14 +201,15 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.WebDriver.Te
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Xunit.Tests", "tests\Testcontainers.Xunit.Tests\Testcontainers.Xunit.Tests.csproj", "{E901DF14-6F05-4FC2-825A-3055FAD33561}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Seq", "..\testcontainers-dotnet\src\Testcontainers.Seq\Testcontainers.Seq.csproj", "{F148CB77-9438-9DCF-CA37-75F7BCD5FEF6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Seq.Tests", "..\testcontainers-dotnet\tests\Testcontainers.Seq.Tests\Testcontainers.Seq.Tests.csproj", "{6FF86CD0-3801-ADE4-A59B-271AC8B2390C}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5365F780-0E6C-41F0-B1B9-7DC34368F80C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5365F780-0E6C-41F0-B1B9-7DC34368F80C}.Debug|Any CPU.Build.0 = Debug|Any CPU
@@ -586,6 +587,17 @@ Global
{E901DF14-6F05-4FC2-825A-3055FAD33561}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E901DF14-6F05-4FC2-825A-3055FAD33561}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E901DF14-6F05-4FC2-825A-3055FAD33561}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F148CB77-9438-9DCF-CA37-75F7BCD5FEF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F148CB77-9438-9DCF-CA37-75F7BCD5FEF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F148CB77-9438-9DCF-CA37-75F7BCD5FEF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F148CB77-9438-9DCF-CA37-75F7BCD5FEF6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6FF86CD0-3801-ADE4-A59B-271AC8B2390C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6FF86CD0-3801-ADE4-A59B-271AC8B2390C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6FF86CD0-3801-ADE4-A59B-271AC8B2390C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6FF86CD0-3801-ADE4-A59B-271AC8B2390C}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{5365F780-0E6C-41F0-B1B9-7DC34368F80C} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
@@ -682,5 +694,10 @@ Global
{27CDB869-A150-4593-958F-6F26E5391E7C} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
{EBA72C3B-57D5-43FF-A5B4-3D55B3B6D4C2} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
{E901DF14-6F05-4FC2-825A-3055FAD33561} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
+ {F148CB77-9438-9DCF-CA37-75F7BCD5FEF6} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
+ {6FF86CD0-3801-ADE4-A59B-271AC8B2390C} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {5EC93352-CD4F-4CB4-84D3-B822DB932443}
EndGlobalSection
EndGlobal
diff --git a/src/Testcontainers.Seq/.editorconfig b/src/Testcontainers.Seq/.editorconfig
new file mode 100644
index 000000000..6f066619d
--- /dev/null
+++ b/src/Testcontainers.Seq/.editorconfig
@@ -0,0 +1 @@
+root = true
\ No newline at end of file
diff --git a/src/Testcontainers.Seq/SeqBuilder.cs b/src/Testcontainers.Seq/SeqBuilder.cs
new file mode 100644
index 000000000..e0648c85f
--- /dev/null
+++ b/src/Testcontainers.Seq/SeqBuilder.cs
@@ -0,0 +1,72 @@
+namespace Testcontainers.Seq;
+
+///
+[PublicAPI]
+public sealed class SeqBuilder : ContainerBuilder
+{
+ public const string SeqImage = "datalust/seq:2024.2.11456";
+
+ public const ushort SeqApiPort = 80;
+ public const ushort SeqIngestionPort = 5341;
+
+ ///
+ protected override SeqConfiguration DockerResourceConfiguration { get; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public SeqBuilder()
+ : this(new SeqConfiguration())
+ {
+ DockerResourceConfiguration = Init().DockerResourceConfiguration;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The Docker resource configuration.
+ private SeqBuilder(SeqConfiguration resourceConfiguration)
+ : base(resourceConfiguration)
+ {
+ DockerResourceConfiguration = resourceConfiguration;
+ }
+
+ ///
+ public override SeqContainer Build()
+ {
+ Validate();
+ return new SeqContainer(DockerResourceConfiguration);
+ }
+ ///
+ protected override SeqBuilder Init()
+ {
+ return base.Init()
+ .WithImage(SeqImage)
+ .WithPortBinding(SeqApiPort, true)
+ .WithPortBinding(SeqIngestionPort, true)
+ .WithEnvironment(new Dictionary
+ {
+ {"ACCEPT_EULA", "Y" }
+ })
+ .WithWaitStrategy(Wait.ForUnixContainer().UntilHttpRequestIsSucceeded(request =>
+ request.ForPath("/health").ForPort(SeqApiPort)));
+ }
+
+ ///
+ protected override SeqBuilder Clone(IResourceConfiguration resourceConfiguration)
+ {
+ return Merge(DockerResourceConfiguration, new SeqConfiguration(resourceConfiguration));
+ }
+
+ ///
+ protected override SeqBuilder Clone(IContainerConfiguration resourceConfiguration)
+ {
+ return Merge(DockerResourceConfiguration, new SeqConfiguration(resourceConfiguration));
+ }
+
+ ///
+ protected override SeqBuilder Merge(SeqConfiguration oldValue, SeqConfiguration newValue)
+ {
+ return new SeqBuilder(new SeqConfiguration(oldValue, newValue));
+ }
+}
\ No newline at end of file
diff --git a/src/Testcontainers.Seq/SeqConfiguration.cs b/src/Testcontainers.Seq/SeqConfiguration.cs
new file mode 100644
index 000000000..3302aa1e9
--- /dev/null
+++ b/src/Testcontainers.Seq/SeqConfiguration.cs
@@ -0,0 +1,56 @@
+namespace Testcontainers.Seq;
+
+///
+[PublicAPI]
+public sealed class SeqConfiguration : ContainerConfiguration
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The Orion.TestContainers.Seq config.
+ public SeqConfiguration(object config = null)
+ {
+ // Sets the custom builder methods property values.
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The Docker resource configuration.
+ public SeqConfiguration(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 SeqConfiguration(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 SeqConfiguration(SeqConfiguration resourceConfiguration)
+ : this(new SeqConfiguration(), 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 SeqConfiguration(SeqConfiguration oldValue, SeqConfiguration newValue)
+ : base(oldValue, newValue)
+ {
+ // Create an updated immutable copy of the module configuration.
+ }
+}
\ No newline at end of file
diff --git a/src/Testcontainers.Seq/SeqContainer.cs b/src/Testcontainers.Seq/SeqContainer.cs
new file mode 100644
index 000000000..befc9850a
--- /dev/null
+++ b/src/Testcontainers.Seq/SeqContainer.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace Testcontainers.Seq;
+
+///
+[PublicAPI]
+public sealed class SeqContainer : DockerContainer
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The container configuration.
+ public SeqContainer(SeqConfiguration configuration)
+ : base(configuration)
+ {
+ }
+
+ public string GetServerApiUrl()
+ {
+ return new UriBuilder("http", Hostname, GetMappedPublicPort(SeqBuilder.SeqApiPort)).Uri.ToString();
+ }
+}
\ No newline at end of file
diff --git a/src/Testcontainers.Seq/Testcontainers.Seq.csproj b/src/Testcontainers.Seq/Testcontainers.Seq.csproj
new file mode 100644
index 000000000..8b2ed72c6
--- /dev/null
+++ b/src/Testcontainers.Seq/Testcontainers.Seq.csproj
@@ -0,0 +1,12 @@
+
+
+ net6.0;net8.0;netstandard2.0;netstandard2.1
+ latest
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Testcontainers.Seq/Usings.cs b/src/Testcontainers.Seq/Usings.cs
new file mode 100644
index 000000000..080580c42
--- /dev/null
+++ b/src/Testcontainers.Seq/Usings.cs
@@ -0,0 +1,6 @@
+global using System.Collections.Generic;
+global using Docker.DotNet.Models;
+global using DotNet.Testcontainers.Builders;
+global using DotNet.Testcontainers.Configurations;
+global using DotNet.Testcontainers.Containers;
+global using JetBrains.Annotations;
diff --git a/tests/Testcontainers.Databases.Tests/Testcontainers.Databases.Tests.csproj b/tests/Testcontainers.Databases.Tests/Testcontainers.Databases.Tests.csproj
index 2ca23a8cb..a5f13fc67 100644
--- a/tests/Testcontainers.Databases.Tests/Testcontainers.Databases.Tests.csproj
+++ b/tests/Testcontainers.Databases.Tests/Testcontainers.Databases.Tests.csproj
@@ -5,13 +5,59 @@
false
-
-
-
-
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/Testcontainers.Seq.Tests/.editorconfig b/tests/Testcontainers.Seq.Tests/.editorconfig
new file mode 100644
index 000000000..6f066619d
--- /dev/null
+++ b/tests/Testcontainers.Seq.Tests/.editorconfig
@@ -0,0 +1 @@
+root = true
\ No newline at end of file
diff --git a/tests/Testcontainers.Seq.Tests/SeqContainerTest.cs b/tests/Testcontainers.Seq.Tests/SeqContainerTest.cs
new file mode 100644
index 000000000..ed30ff6e9
--- /dev/null
+++ b/tests/Testcontainers.Seq.Tests/SeqContainerTest.cs
@@ -0,0 +1,38 @@
+using Microsoft.Extensions.Logging;
+using Seq.Api;
+using System;
+using System.Linq;
+
+namespace Testcontainers.Seq;
+
+public sealed class SeqContainerTest : IAsyncLifetime
+{
+ private readonly SeqContainer _seqContainer = new SeqBuilder().Build();
+
+ public Task InitializeAsync()
+ {
+ return _seqContainer.StartAsync();
+ }
+
+ public Task DisposeAsync()
+ {
+ return _seqContainer.DisposeAsync().AsTask();
+ }
+
+ [Fact]
+ [Trait(nameof(DockerCli.DockerPlatform), nameof(DockerCli.DockerPlatform.Linux))]
+ public async Task CanLog()
+ {
+ var currentSeqApiPort = _seqContainer.GetMappedPublicPort(80);
+ var currentSeqHostname = _seqContainer.Hostname;
+
+ ILoggerFactory loggerFactory = new LoggerFactory();
+ loggerFactory.AddSeq(_seqContainer.GetServerApiUrl());
+ var testLogger = loggerFactory.CreateLogger("testlogger");
+ testLogger.LogInformation("TRY THIS");
+
+ var seqConnection = new SeqConnection(_seqContainer.GetServerApiUrl());
+ var eventList = await seqConnection.Events.ListAsync(fromDateUtc: DateTime.Now.AddMinutes(-1));
+ Assert.Contains(eventList, e => e.MessageTemplateTokens.Last().Text == "TRY THIS");
+ }
+}
\ No newline at end of file
diff --git a/tests/Testcontainers.Seq.Tests/Testcontainers.Seq.Tests.csproj b/tests/Testcontainers.Seq.Tests/Testcontainers.Seq.Tests.csproj
new file mode 100644
index 000000000..4ea635b58
--- /dev/null
+++ b/tests/Testcontainers.Seq.Tests/Testcontainers.Seq.Tests.csproj
@@ -0,0 +1,26 @@
+
+
+ net8.0
+ false
+ false
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/Testcontainers.Seq.Tests/Usings.cs b/tests/Testcontainers.Seq.Tests/Usings.cs
new file mode 100644
index 000000000..346085388
--- /dev/null
+++ b/tests/Testcontainers.Seq.Tests/Usings.cs
@@ -0,0 +1,3 @@
+global using System.Threading.Tasks;
+global using DotNet.Testcontainers.Commons;
+global using Xunit;
\ No newline at end of file