Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/Dapr.Testcontainers/Common/Options/DaprRuntimeOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// ------------------------------------------------------------------------

using System;
using System.Collections.Generic;

namespace Dapr.Testcontainers.Common.Options;

Expand All @@ -21,6 +22,7 @@ namespace Dapr.Testcontainers.Common.Options;
public sealed record DaprRuntimeOptions
{
private const string DEFAULT_VERSION_ENVVAR_NAME = "DAPR_RUNTIME_VERSION";
private readonly Dictionary<string, string> environmentVariables = new(StringComparer.Ordinal);
private static readonly string[] CiEnvironmentSignals =
[
"CI",
Expand Down Expand Up @@ -73,6 +75,11 @@ public DaprRuntimeOptions(string version = "latest")
/// The Dapr API token used to secure communications with the sidecar.
/// </summary>
public string? DaprApiToken { get; private set; }

/// <summary>
/// Environment variables to set on the Dapr runtime container.
/// </summary>
public IReadOnlyDictionary<string, string> EnvironmentVariables => environmentVariables;

/// <summary>
/// The level of Dapr logs to show.
Expand Down Expand Up @@ -149,6 +156,20 @@ public DaprRuntimeOptions WithDaprApiToken(string daprApiToken)
return this;
}

/// <summary>
/// Sets an environment variable on the Dapr runtime container.
/// </summary>
/// <param name="name">The environment variable name.</param>
/// <param name="value">The environment variable value.</param>
public DaprRuntimeOptions WithEnvironmentVariable(string name, string value)
{
ArgumentException.ThrowIfNullOrWhiteSpace(name);
ArgumentNullException.ThrowIfNull(value);

environmentVariables[name] = value;
return this;
}

/// <summary>
/// Enables container log capture to files.
/// </summary>
Expand Down
5 changes: 5 additions & 0 deletions src/Dapr.Testcontainers/Containers/Dapr/DaprdContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ public DaprdContainer(
containerBuilder = containerBuilder.WithOutputConsumer(_logAttachment.OutputConsumer);
}

foreach (var (name, value) in options.EnvironmentVariables)
{
containerBuilder = containerBuilder.WithEnvironment(name, value);
}

// Put the API token in an envvar so it can be picked up by the Dapr runtime at startup
if (!string.IsNullOrWhiteSpace(options.DaprApiToken))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
using Dapr.DistributedLock.Extensions;
using Dapr.DistributedLock.Models;
using Dapr.Testcontainers.Common;
using Dapr.Testcontainers.Common.Options;
using Dapr.Testcontainers.Harnesses;
using Grpc.Core;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

Expand All @@ -16,11 +18,17 @@ public async Task ShouldAcquireAndReleaseLock()
var componentsDir = TestDirectoryManager.CreateTestDirectory("distributedlock-components");
var resourceId = $"resource-{Guid.NewGuid():N}";
var owner = $"owner-{Guid.NewGuid():N}";
var daprApiToken = $"distributed-lock-token-{Guid.NewGuid():N}";
var options = new DaprRuntimeOptions()
.WithEnvironmentVariable("DAPR_API_TOKEN", daprApiToken);

await using var environment = await DaprTestEnvironment.CreateWithPooledNetworkAsync(cancellationToken: TestContext.Current.CancellationToken);
await environment.StartAsync(TestContext.Current.CancellationToken);

var harness = new DaprHarnessBuilder(componentsDir).BuildDistributedLock();
var harness = new DaprHarnessBuilder(componentsDir)
.WithEnvironment(environment)
.WithOptions(options)
.BuildDistributedLock();
await using var testApp = await DaprHarnessBuilder.ForHarness(harness)
.ConfigureServices(builder =>
{
Expand All @@ -30,13 +38,27 @@ public async Task ShouldAcquireAndReleaseLock()
var grpcEndpoint = config["DAPR_GRPC_ENDPOINT"];
if (!string.IsNullOrEmpty(grpcEndpoint))
clientBuilder.UseGrpcEndpoint(grpcEndpoint);
clientBuilder.UseDaprApiToken(daprApiToken);
});
})
.BuildAndStartAsync();

const string componentName = DistributedLockHarness.DistributedLockComponentName;
Assert.NotNull(componentName);

using var unauthenticatedClient = new DaprDistributedLockBuilder()
.UseGrpcEndpoint($"http://127.0.0.1:{harness.DaprGrpcPort}")
.Build();
var unauthenticatedException = await Assert.ThrowsAsync<DaprException>(
() => unauthenticatedClient.TryLockAsync(
componentName,
$"unauthenticated-{resourceId}",
owner,
expiryInSeconds: 10,
cancellationToken: TestContext.Current.CancellationToken));
var rpcException = Assert.IsType<RpcException>(unauthenticatedException.InnerException);
Assert.Equal(StatusCode.Unauthenticated, rpcException.StatusCode);

using var scope = testApp.CreateScope();
var client = scope.ServiceProvider.GetRequiredService<DaprDistributedLockClient>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,27 @@ public void ShouldEnableContainerLogsForCiDebugLogging()
}
}

[Fact]
public void ShouldSetEnvironmentVariable()
{
var options = new DaprRuntimeOptions()
.WithEnvironmentVariable("REDIS_HOST", "redis:6379")
.WithEnvironmentVariable("REDIS_PASSWORD", "password");

Assert.Equal("redis:6379", options.EnvironmentVariables["REDIS_HOST"]);
Assert.Equal("password", options.EnvironmentVariables["REDIS_PASSWORD"]);
}

[Fact]
public void ShouldOverwriteEnvironmentVariable()
{
var options = new DaprRuntimeOptions()
.WithEnvironmentVariable("REDIS_HOST", "redis:6379")
.WithEnvironmentVariable("REDIS_HOST", "redis:6380");

Assert.Equal("redis:6380", options.EnvironmentVariables["REDIS_HOST"]);
}

public void Dispose()
{
// Clear this variable
Expand Down
Loading