diff --git a/src/Testcontainers.Ollama/OllamaBuilder.cs b/src/Testcontainers.Ollama/OllamaBuilder.cs index 18672fd19..3a0323ee0 100644 --- a/src/Testcontainers.Ollama/OllamaBuilder.cs +++ b/src/Testcontainers.Ollama/OllamaBuilder.cs @@ -4,6 +4,31 @@ namespace Testcontainers.Ollama [PublicAPI] public sealed class OllamaBuilder : ContainerBuilder { + /// + /// Gets the default port of the Ollama API. + /// + public const int DefaultPort = 11434; + + /// + /// Default image name and version tag. + /// + public const string OllamaImage = "ollama/ollama:0.1.22"; + + /// + /// Default volume path. + /// + public const string DefaultVolumePath = "/root/.ollama"; + + /// + /// Default volume name. + /// + public const string DefaultVolumeName = "ollama-volume"; + + /// + /// The default model name for the OllamaBuilder. + /// + public const string DefaultModelName = OllamaModels.Llama2; + /// /// Initializes a new instance of the class. /// @@ -54,9 +79,9 @@ protected override void Validate() protected override OllamaBuilder Init() { return base.Init() - .WithImage(new DockerImage(OllamaConfiguration.ImageName)) - .WithPortBinding(OllamaConfiguration.DefaultPort, true) - .WithVolumeMount(OllamaConfiguration.DefaultVolumeName, OllamaConfiguration.DefaultVolumePath) + .WithImage(new DockerImage(OllamaImage)) + .WithPortBinding(DefaultPort, true) + .WithVolumeMount(DefaultVolumeName, DefaultVolumePath) ; } @@ -90,7 +115,7 @@ protected override OllamaBuilder Merge(OllamaConfiguration oldValue, OllamaConfi /// public OllamaBuilder WithModelName(string name) { - return Merge(DockerResourceConfiguration, new OllamaConfiguration(DockerResourceConfiguration) {ModelName = name}); + return Merge(DockerResourceConfiguration, new OllamaConfiguration(DockerResourceConfiguration, new OllamaConfiguration(modelName: name))); } } } \ No newline at end of file diff --git a/src/Testcontainers.Ollama/OllamaConfiguration.cs b/src/Testcontainers.Ollama/OllamaConfiguration.cs index d3eb7e544..52abab44f 100644 --- a/src/Testcontainers.Ollama/OllamaConfiguration.cs +++ b/src/Testcontainers.Ollama/OllamaConfiguration.cs @@ -5,15 +5,14 @@ namespace Testcontainers.Ollama public sealed class OllamaConfiguration : ContainerConfiguration { /// - /// Initializes a new instance of the class. + /// The OllamaConfiguration class represents the configuration for an Ollama container. /// - /// - /// - /// - /// - public OllamaConfiguration(string modelName = null, string schema = null, int? port = null) + public OllamaConfiguration(string modelName = null, string volumePath = null, string volumeName = null, int? port = null) { - ModelName = modelName; + ModelName = modelName ?? string.Empty; + VolumePath = volumePath ?? OllamaBuilder.DefaultVolumePath; + VolumeName = volumeName ?? OllamaBuilder.DefaultVolumeName; + Port = port ?? OllamaBuilder.DefaultPort; } /// @@ -55,31 +54,29 @@ public OllamaConfiguration(OllamaConfiguration oldValue, OllamaConfiguration new : base(oldValue, newValue) { ModelName = BuildConfiguration.Combine(oldValue.ModelName, newValue.ModelName); + VolumePath = BuildConfiguration.Combine(oldValue.VolumePath, newValue.VolumePath); + VolumeName = BuildConfiguration.Combine(oldValue.VolumeName, newValue.VolumeName); + Port = BuildConfiguration.Combine(oldValue.Port, newValue.Port); } - - /// - /// Name of the model to use. - /// - public string ModelName { get; set; } = OllamaModels.Llama2; - + /// - /// Gets the default port of the Ollama API. + /// Represents the configuration for the Ollama container. /// - public const int DefaultPort = 11434; - + public string ModelName { get; set; } + /// - /// Default image name. + /// The OllamaConfiguration class represents the configuration for an Ollama container. /// - public const string ImageName = "ollama/ollama:latest"; - + public string VolumePath { get; set; } + /// - /// Default volume path. + /// Gets or sets the name of the volume associated with the Ollama container. /// - public const string DefaultVolumePath = "/root/.ollama"; - + public string VolumeName { get; set; } + /// - /// Default volume name. + /// The class represents the configuration for an Ollama container port. /// - public const string DefaultVolumeName = "ollama-volume"; + public int Port { get; set; } } } \ No newline at end of file diff --git a/src/Testcontainers.Ollama/OllamaContainer.cs b/src/Testcontainers.Ollama/OllamaContainer.cs index 826aceff1..53113a052 100644 --- a/src/Testcontainers.Ollama/OllamaContainer.cs +++ b/src/Testcontainers.Ollama/OllamaContainer.cs @@ -1,3 +1,5 @@ +using System.Threading; + namespace Testcontainers.Ollama { /// @@ -12,24 +14,29 @@ public sealed class OllamaContainer : DockerContainer public OllamaContainer(OllamaConfiguration configuration, ILogger logger) : base(configuration, logger) { - ModelName = configuration.ModelName; - ImageName = OllamaConfiguration.ImageName; + Configuration = configuration; + } + + public OllamaConfiguration Configuration { get; private set; } + + public Task Run(CancellationToken ct = default) + { + return Run(Configuration.ModelName, ct); } /// /// Starts the Ollama container. /// - public async Task StartOllamaAsync() + public Task Run(string modelName, CancellationToken ct = default) { - if (State!= TestcontainersStates.Created && State != TestcontainersStates.Running) { - throw new InvalidOperationException("Cannot start a container that has not been created."); + ModelName = modelName; + if (State!= TestcontainersStates.Created && State != TestcontainersStates.Running) { + ThrowIfResourceNotFound(); } - Task.WaitAll(ExecAsync(new List() - { + + return ExecAsync(new List() { "ollama", "run", ModelName, - })); - - await Task.CompletedTask; + }, ct); } /// @@ -37,7 +44,7 @@ public async Task StartOllamaAsync() /// /// The base URL of the Ollama API. /// http://localhost:5000/api - public string GetBaseUrl() => $"http://{Hostname}:{GetMappedPublicPort(OllamaConfiguration.DefaultPort)}/api"; + public string GetBaseUrl() => $"http://{Hostname}:{GetMappedPublicPort(OllamaBuilder.DefaultPort)}/api"; /// /// Gets the name of the Docker image to use. @@ -47,6 +54,6 @@ public async Task StartOllamaAsync() /// /// Gets the name of the model to run. /// - public string ModelName { get; } + public string ModelName { get; private set; } } } \ No newline at end of file diff --git a/tests/Testcontainers.Commons/TestOutputHelperExtensions.cs b/tests/Testcontainers.Commons/TestOutputHelperExtensions.cs deleted file mode 100644 index 4dbb8f490..000000000 --- a/tests/Testcontainers.Commons/TestOutputHelperExtensions.cs +++ /dev/null @@ -1,22 +0,0 @@ -#nullable enable -using System.Text.Json; -using System.Text.Json.Serialization; -using Xunit.Abstractions; - -namespace DotNet.Testcontainers.Commons -{ - public static class TestOutputHelperExtensions - { - public static void WriteJson(this ITestOutputHelper testOutputHelper, T source, JsonSerializerOptions? jsonSerializerOptions = null) - { - jsonSerializerOptions ??= new JsonSerializerOptions - { - WriteIndented = true, - Converters = { new JsonStringEnumConverter()}, - MaxDepth = 64, - }; - var json = JsonSerializer.Serialize(source, jsonSerializerOptions); - testOutputHelper.WriteLine(json); - } - } -} \ No newline at end of file diff --git a/tests/Testcontainers.Commons/TestOutputLogger.cs b/tests/Testcontainers.Commons/TestOutputLogger.cs deleted file mode 100644 index 7796c31a2..000000000 --- a/tests/Testcontainers.Commons/TestOutputLogger.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Microsoft.Extensions.Logging; -using Xunit.Abstractions; - -namespace DotNet.Testcontainers.Commons; - -public class TestOutputLogger : ILogger -{ - private readonly string _categoryName; - private readonly LogLevel _logLevel; - private readonly ITestOutputHelper _testOutputHelper; - - public TestOutputLogger(string categoryName, ITestOutputHelper testOutputHelper, LogLevel logLevel = LogLevel.Information) - { - _categoryName = categoryName; - _testOutputHelper = testOutputHelper; - _logLevel = logLevel; - } - - /// - public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) - { - if (!IsEnabled(logLevel)) - return; - - if (formatter == null) - throw new ArgumentNullException(nameof(formatter)); - - var message = formatter(state, exception); - if (string.IsNullOrEmpty(message)) - { - return; - } - - _testOutputHelper.WriteLine($"{logLevel}: {_categoryName}: {message}"); - } - - /// - public bool IsEnabled(LogLevel logLevel) - { - return logLevel >= _logLevel; - } - - /// - public IDisposable BeginScope(TState state) - { - return null!; - } - -} \ No newline at end of file diff --git a/tests/Testcontainers.Commons/Testcontainers.Commons.csproj b/tests/Testcontainers.Commons/Testcontainers.Commons.csproj index 4810e26a0..0fce12a00 100644 --- a/tests/Testcontainers.Commons/Testcontainers.Commons.csproj +++ b/tests/Testcontainers.Commons/Testcontainers.Commons.csproj @@ -8,7 +8,6 @@ - diff --git a/tests/Testcontainers.Ollama.Tests/OllamaContainerTests.cs b/tests/Testcontainers.Ollama.Tests/OllamaContainerTests.cs index 55641c4ec..e9a9f7b39 100644 --- a/tests/Testcontainers.Ollama.Tests/OllamaContainerTests.cs +++ b/tests/Testcontainers.Ollama.Tests/OllamaContainerTests.cs @@ -2,20 +2,15 @@ namespace Testcontainers.Ollama.Tests { public class OllamaContainerTests : IAsyncLifetime { - private readonly ITestOutputHelper _testOutputHelper; private OllamaContainer _ollamaContainer; - public OllamaContainerTests(ITestOutputHelper testOutputHelper) - { - _testOutputHelper = testOutputHelper; - } - public async Task InitializeAsync() { - TestcontainersSettings.Logger = new TestOutputLogger(nameof(OllamaContainerTests), _testOutputHelper); - _ollamaContainer = new OllamaBuilder().Build(); + _ollamaContainer = new OllamaBuilder() + .OllamaConfig(new OllamaConfiguration(OllamaModels.Llama2)) + .Build(); await _ollamaContainer.StartAsync(); - await _ollamaContainer.StartOllamaAsync(); + await _ollamaContainer.Run(); } public async Task DisposeAsync() @@ -41,8 +36,6 @@ public async Task OllamaContainerReturnsSuccessful() var response = await client.SendChat(chatRequest, stream => { }); response = response.ToList(); - _testOutputHelper.WriteJson(response); - Assert.True(response.Any()); } } diff --git a/tests/Testcontainers.Ollama.Tests/Usings.cs b/tests/Testcontainers.Ollama.Tests/Usings.cs index e8ee5c203..e610c15c9 100644 --- a/tests/Testcontainers.Ollama.Tests/Usings.cs +++ b/tests/Testcontainers.Ollama.Tests/Usings.cs @@ -1,7 +1,6 @@ global using System.Threading.Tasks; global using DotNet.Testcontainers.Commons; global using Xunit; -global using Xunit.Abstractions; global using System.Collections.Generic; global using System.Linq; global using DotNet.Testcontainers.Configurations;