Skip to content

Commit

Permalink
feat: Add Weaviate module (#1356)
Browse files Browse the repository at this point in the history
Co-authored-by: Andre Hofmeister <[email protected]>
  • Loading branch information
roji and HofmeisterAn authored Feb 2, 2025
1 parent 2c6c915 commit 40227bf
Show file tree
Hide file tree
Showing 14 changed files with 221 additions and 6 deletions.
1 change: 1 addition & 0 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ jobs:
{ name: "Testcontainers.Redis", runs-on: "ubuntu-22.04" },
{ name: "Testcontainers.Redpanda", runs-on: "ubuntu-22.04" },
{ name: "Testcontainers.ServiceBus", runs-on: "ubuntu-22.04" },
{ name: "Testcontainers.Weaviate", runs-on: "ubuntu-22.04" },
{ name: "Testcontainers.WebDriver", runs-on: "ubuntu-22.04" },
{ name: "Testcontainers.Xunit", runs-on: "ubuntu-22.04" }
]
Expand Down
3 changes: 2 additions & 1 deletion Testcontainers.dic
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ testcontainer
testcontainers
tlsverify
toml
vstest
vstest
weaviate
14 changes: 14 additions & 0 deletions Testcontainers.sln
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Redpanda", "
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.ServiceBus", "src\Testcontainers.ServiceBus\Testcontainers.ServiceBus.csproj", "{2E39E532-B81E-4B48-A004-FAE18EDF9E79}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Weaviate", "src\Testcontainers.Weaviate\Testcontainers.Weaviate.csproj", "{68F8600D-24E9-4E03-9E25-5F6EB338EAC1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.WebDriver", "src\Testcontainers.WebDriver\Testcontainers.WebDriver.csproj", "{64A87DE5-29B0-4A54-9E74-560484D8C7C0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Xunit", "src\Testcontainers.Xunit\Testcontainers.Xunit.csproj", "{380BB29B-F556-404D-B13B-CA250599C565}"
Expand Down Expand Up @@ -201,6 +203,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.ServiceBus.T
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Tests", "tests\Testcontainers.Tests\Testcontainers.Tests.csproj", "{27CDB869-A150-4593-958F-6F26E5391E7C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Weaviate.Tests", "tests\Testcontainers.Weaviate.Tests\Testcontainers.Weaviate.Tests.csproj", "{DDB41BC8-5826-4D97-9C5F-001151E3FFD6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.WebDriver.Tests", "tests\Testcontainers.WebDriver.Tests\Testcontainers.WebDriver.Tests.csproj", "{EBA72C3B-57D5-43FF-A5B4-3D55B3B6D4C2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Xunit.Tests", "tests\Testcontainers.Xunit.Tests\Testcontainers.Xunit.Tests.csproj", "{E901DF14-6F05-4FC2-825A-3055FAD33561}"
Expand Down Expand Up @@ -382,6 +386,10 @@ Global
{2E39E532-B81E-4B48-A004-FAE18EDF9E79}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2E39E532-B81E-4B48-A004-FAE18EDF9E79}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2E39E532-B81E-4B48-A004-FAE18EDF9E79}.Release|Any CPU.Build.0 = Release|Any CPU
{68F8600D-24E9-4E03-9E25-5F6EB338EAC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{68F8600D-24E9-4E03-9E25-5F6EB338EAC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{68F8600D-24E9-4E03-9E25-5F6EB338EAC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{68F8600D-24E9-4E03-9E25-5F6EB338EAC1}.Release|Any CPU.Build.0 = Release|Any CPU
{64A87DE5-29B0-4A54-9E74-560484D8C7C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{64A87DE5-29B0-4A54-9E74-560484D8C7C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{64A87DE5-29B0-4A54-9E74-560484D8C7C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -590,6 +598,10 @@ Global
{27CDB869-A150-4593-958F-6F26E5391E7C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{27CDB869-A150-4593-958F-6F26E5391E7C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{27CDB869-A150-4593-958F-6F26E5391E7C}.Release|Any CPU.Build.0 = Release|Any CPU
{DDB41BC8-5826-4D97-9C5F-001151E3FFD6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DDB41BC8-5826-4D97-9C5F-001151E3FFD6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DDB41BC8-5826-4D97-9C5F-001151E3FFD6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DDB41BC8-5826-4D97-9C5F-001151E3FFD6}.Release|Any CPU.Build.0 = Release|Any CPU
{EBA72C3B-57D5-43FF-A5B4-3D55B3B6D4C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EBA72C3B-57D5-43FF-A5B4-3D55B3B6D4C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EBA72C3B-57D5-43FF-A5B4-3D55B3B6D4C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -642,6 +654,7 @@ Global
{BFDA179A-40EB-4CEB-B8E9-0DF32C65E2C5} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
{45D6F69C-4D87-4130-AA90-0DB2F7460DAE} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
{2E39E532-B81E-4B48-A004-FAE18EDF9E79} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
{68F8600D-24E9-4E03-9E25-5F6EB338EAC1} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
{64A87DE5-29B0-4A54-9E74-560484D8C7C0} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
{380BB29B-F556-404D-B13B-CA250599C565} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
{84911C93-C2A9-46E9-AE5E-D567306589E5} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
Expand Down Expand Up @@ -694,6 +707,7 @@ Global
{9E8E6AA5-65D1-498F-BEAB-BA34723A0050} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
{232DD918-46ED-4BA8-B383-1A9146D83064} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
{27CDB869-A150-4593-958F-6F26E5391E7C} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
{DDB41BC8-5826-4D97-9C5F-001151E3FFD6} = {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}
EndGlobalSection
Expand Down
11 changes: 6 additions & 5 deletions Testcontainers.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/NAMESPACE_BODY/@EntryValue">BlockScoped</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/QualifiedUsingAtNestedScope/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/InstalledDictionaries/InstalledDictionaries/=Testcontainers_002Edic/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=azurite/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=awslocal/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=azurecr/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=azurite/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=capi/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=creds/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=dind/@EntryIndexedValue">True</s:Boolean>
Expand Down Expand Up @@ -42,10 +42,11 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=testcontainer/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=testcontainers/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=tlsverify/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=toml/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=toml/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=vstest/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CheckNamespace/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToUsingDeclaration/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseAwaitUsing/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=weaviate/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CheckNamespace/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToUsingDeclaration/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseAwaitUsing/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeObjectCreationWhenTypeEvident/@EntryIndexedValue">DO_NOT_SHOW</s:String>
</wpf:ResourceDictionary>
1 change: 1 addition & 0 deletions src/Testcontainers.Weaviate/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
root = true
12 changes: 12 additions & 0 deletions src/Testcontainers.Weaviate/Testcontainers.Weaviate.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0;net9.0;netstandard2.0;netstandard2.1</TargetFrameworks>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" VersionOverride="2023.3.0" PrivateAssets="All"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../Testcontainers/Testcontainers.csproj"/>
</ItemGroup>
</Project>
6 changes: 6 additions & 0 deletions src/Testcontainers.Weaviate/Usings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
global using System;
global using Docker.DotNet.Models;
global using DotNet.Testcontainers.Builders;
global using DotNet.Testcontainers.Configurations;
global using DotNet.Testcontainers.Containers;
global using JetBrains.Annotations;
61 changes: 61 additions & 0 deletions src/Testcontainers.Weaviate/WeaviateBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
namespace Testcontainers.Weaviate;

/// <inheritdoc cref="ContainerBuilder{TBuilderEntity, TContainerEntity, TConfigurationEntity}" />
[PublicAPI]
public sealed class WeaviateBuilder : ContainerBuilder<WeaviateBuilder, WeaviateContainer, WeaviateConfiguration>
{
public const string WeaviateImage = "semitechnologies/weaviate:1.26.14";

public const ushort WeaviateHttpPort = 8080;

public const ushort WeaviateGrpcPort = 50051;

/// <summary>
/// Initializes a new instance of the <see cref="WeaviateBuilder" /> class.
/// </summary>
public WeaviateBuilder() : this(new WeaviateConfiguration())
=> DockerResourceConfiguration = Init().DockerResourceConfiguration;

/// <summary>
/// Initializes a new instance of the <see cref="WeaviateBuilder" /> class.
/// </summary>
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
private WeaviateBuilder(WeaviateConfiguration resourceConfiguration) : base(resourceConfiguration)
=> DockerResourceConfiguration = resourceConfiguration;

/// <inheritdoc />
protected override WeaviateConfiguration DockerResourceConfiguration { get; }

/// <inheritdoc />
public override WeaviateContainer Build()
{
Validate();
return new WeaviateContainer(DockerResourceConfiguration);
}

/// <inheritdoc />
protected override WeaviateBuilder Init()
=> base.Init()
.WithImage(WeaviateImage)
.WithPortBinding(WeaviateHttpPort, true)
.WithPortBinding(WeaviateGrpcPort, true)
.WithEnvironment("AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED", "true")
.WithEnvironment("PERSISTENCE_DATA_PATH", "/var/lib/weaviate")
.WithWaitStrategy(Wait.ForUnixContainer()
.UntilPortIsAvailable(WeaviateHttpPort)
.UntilPortIsAvailable(WeaviateGrpcPort)
.UntilHttpRequestIsSucceeded(request =>
request.ForPath("/v1/.well-known/ready").ForPort(WeaviateHttpPort)));

/// <inheritdoc />
protected override WeaviateBuilder Clone(IResourceConfiguration<CreateContainerParameters> resourceConfiguration)
=> Merge(DockerResourceConfiguration, new WeaviateConfiguration(resourceConfiguration));

/// <inheritdoc />
protected override WeaviateBuilder Clone(IContainerConfiguration resourceConfiguration)
=> Merge(DockerResourceConfiguration, new WeaviateConfiguration(resourceConfiguration));

/// <inheritdoc />
protected override WeaviateBuilder Merge(WeaviateConfiguration oldValue, WeaviateConfiguration newValue)
=> new(new WeaviateConfiguration(oldValue, newValue));
}
53 changes: 53 additions & 0 deletions src/Testcontainers.Weaviate/WeaviateConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
namespace Testcontainers.Weaviate;

/// <inheritdoc cref="ContainerConfiguration" />
[PublicAPI]
public sealed class WeaviateConfiguration : ContainerConfiguration
{
/// <summary>
/// Initializes a new instance of the <see cref="WeaviateConfiguration" /> class.
/// </summary>
public WeaviateConfiguration()
{
}

/// <summary>
/// Initializes a new instance of the <see cref="WeaviateConfiguration" /> class.
/// </summary>
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
public WeaviateConfiguration(IResourceConfiguration<CreateContainerParameters> resourceConfiguration)
: base(resourceConfiguration)
{
// Passes the configuration upwards to the base implementations to create an updated immutable copy.
}

/// <summary>
/// Initializes a new instance of the <see cref="WeaviateConfiguration" /> class.
/// </summary>
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
public WeaviateConfiguration(IContainerConfiguration resourceConfiguration)
: base(resourceConfiguration)
{
// Passes the configuration upwards to the base implementations to create an updated immutable copy.
}

/// <summary>
/// Initializes a new instance of the <see cref="WeaviateConfiguration" /> class.
/// </summary>
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
public WeaviateConfiguration(WeaviateConfiguration resourceConfiguration)
: this(new WeaviateConfiguration(), resourceConfiguration)
{
// Passes the configuration upwards to the base implementations to create an updated immutable copy.
}

/// <summary>
/// Initializes a new instance of the <see cref="WeaviateConfiguration" /> class.
/// </summary>
/// <param name="oldValue">The old Docker resource configuration.</param>
/// <param name="newValue">The new Docker resource configuration.</param>
public WeaviateConfiguration(WeaviateConfiguration oldValue, WeaviateConfiguration newValue)
: base(oldValue, newValue)
{
}
}
15 changes: 15 additions & 0 deletions src/Testcontainers.Weaviate/WeaviateContainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Testcontainers.Weaviate;

/// <inheritdoc cref="DockerContainer" />
[PublicAPI]
public sealed class WeaviateContainer(WeaviateConfiguration configuration) : DockerContainer(configuration)
{
/// <summary>
/// Gets the Weaviate base address.
/// </summary>
/// <returns>The Weaviate base address.</returns>
public string GetBaseAddress()
{
return new UriBuilder(Uri.UriSchemeHttp, Hostname, GetMappedPublicPort(WeaviateBuilder.WeaviateHttpPort)).ToString();
}
}
1 change: 1 addition & 0 deletions tests/Testcontainers.Weaviate.Tests/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
root = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net9.0</TargetFrameworks>
<IsPackable>false</IsPackable>
<IsPublishable>false</IsPublishable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk"/>
<PackageReference Include="coverlet.collector"/>
<PackageReference Include="xunit.runner.visualstudio"/>
<PackageReference Include="xunit"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../../src/Testcontainers.Weaviate/Testcontainers.Weaviate.csproj"/>
<ProjectReference Include="../Testcontainers.Commons/Testcontainers.Commons.csproj"/>
</ItemGroup>
</Project>
6 changes: 6 additions & 0 deletions tests/Testcontainers.Weaviate.Tests/Usings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
global using System;
global using System.Net;
global using System.Net.Http;
global using System.Threading.Tasks;
global using DotNet.Testcontainers.Commons;
global using Xunit;
26 changes: 26 additions & 0 deletions tests/Testcontainers.Weaviate.Tests/WeaviateContainerTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace Testcontainers.Weaviate;

public sealed class WeaviateContainerTest : IAsyncLifetime
{
private readonly WeaviateContainer _weaviateContainer = new WeaviateBuilder().Build();

public Task InitializeAsync() => _weaviateContainer.StartAsync();

public Task DisposeAsync() => _weaviateContainer.DisposeAsync().AsTask();

[Fact]
[Trait(nameof(DockerCli.DockerPlatform), nameof(DockerCli.DockerPlatform.Linux))]
public async Task GetSchemaReturnsHttpStatusCodeOk()
{
// Given
using var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(_weaviateContainer.GetBaseAddress());

// When
using var httpResponse = await httpClient.GetAsync("v1/schema")
.ConfigureAwait(true);

// Then
Assert.Equal(HttpStatusCode.OK, httpResponse.StatusCode);
}
}

0 comments on commit 40227bf

Please sign in to comment.