Skip to content

Commit

Permalink
Accept search attributes for dev server
Browse files Browse the repository at this point in the history
  • Loading branch information
cretz committed Jun 26, 2024
1 parent 8b430c4 commit 19f5de8
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/Temporalio/Bridge/EphemeralServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ private unsafe EphemeralServer(
public bool HasTestService { get; private init; }

/// <summary>
/// Start Temporalite.
/// Start dev server.
/// </summary>
/// <param name="runtime">Runtime to use.</param>
/// <param name="options">Options to use.</param>
/// <returns>Started server.</returns>
public static async Task<EphemeralServer> StartTemporaliteAsync(
public static async Task<EphemeralServer> StartDevServerAsync(
Runtime runtime,
Testing.WorkflowEnvironmentStartLocalOptions options)
{
Expand Down
13 changes: 12 additions & 1 deletion src/Temporalio/Bridge/OptionsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,17 @@ public static unsafe Interop.DevServerOptions ToInteropOptions(
// Use TargetHost to get IP + Port
options.ParseTargetHost(out string? ip, out int? port);
ip ??= "127.0.0.1";

// If there are search attributes, prepend them to the args
var args = options.DevServerOptions.ExtraArgs;
if (options.SearchAttributes is { } attrs && attrs.Count > 0)
{
args = attrs.
SelectMany(v => new[] { "--search-attribute", $"{v.Name}={v.ValueType}" }).
Concat(args ?? Enumerable.Empty<string>()).
ToArray();
}

return new Interop.DevServerOptions()
{
test_server = scope.Pointer(
Expand All @@ -334,7 +345,7 @@ public static unsafe Interop.DevServerOptions ToInteropOptions(
download_version = scope.ByteArray(options.DevServerOptions.DownloadVersion),
download_dest_dir = scope.ByteArray(options.DownloadDirectory),
port = (ushort)(port ?? 0),
extra_args = scope.NewlineDelimited(options.DevServerOptions.ExtraArgs),
extra_args = scope.NewlineDelimited(args),
}),
namespace_ = scope.ByteArray(options.Namespace),
ip = scope.ByteArray(ip),
Expand Down
2 changes: 1 addition & 1 deletion src/Temporalio/Testing/WorkflowEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public static async Task<WorkflowEnvironment> StartLocalAsync(
{
options ??= new();
var runtime = options.Runtime ?? TemporalRuntime.Default;
var server = await Bridge.EphemeralServer.StartTemporaliteAsync(
var server = await Bridge.EphemeralServer.StartDevServerAsync(
runtime.Runtime,
options).ConfigureAwait(false);
return await StartEphemeralAsync(server, options).ConfigureAwait(false);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
using System.Collections.Generic;
using Temporalio.Common;

namespace Temporalio.Testing
{
/// <summary>
Expand All @@ -18,6 +21,11 @@ public class WorkflowEnvironmentStartLocalOptions : Client.TemporalClientConnect
/// </summary>
public bool UI { get; set; }

/// <summary>
/// Gets or sets search attributes registered on the dev server on start.
/// </summary>
public IReadOnlyCollection<SearchAttributeKey>? SearchAttributes { get; set; }

/// <summary>
/// Gets or sets <b>unstable</b> dev server options.
/// </summary>
Expand Down
51 changes: 51 additions & 0 deletions tests/Temporalio.Tests/Testing/WorkflowEnvironmentTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace Temporalio.Tests.Testing;
using Temporalio.Activities;
using Temporalio.Api.Enums.V1;
using Temporalio.Client;
using Temporalio.Common;
using Temporalio.Exceptions;
using Temporalio.Testing;
using Temporalio.Worker;
Expand Down Expand Up @@ -199,4 +200,54 @@ await env.Client.ExecuteWorkflowAsync(
});
});
}

[Fact]
public async Task StartLocal_SearchAttributes_ProperlyRegistered()
{
// Prepare attrs
var attrBool = SearchAttributeKey.CreateBool("DotNetTemporalTestBool");
var attrDateTime = SearchAttributeKey.CreateDateTimeOffset("DotNetTemporalTestDateTime");
var attrDouble = SearchAttributeKey.CreateDouble("DotNetTemporalTestDouble");
var attrKeyword = SearchAttributeKey.CreateKeyword("DotNetTemporalTestKeyword");
var attrKeywordList = SearchAttributeKey.CreateKeywordList("DotNetTemporalTestKeywordList");
var attrLong = SearchAttributeKey.CreateLong("DotNetTemporalTestLong");
var attrText = SearchAttributeKey.CreateText("DotNetTemporalTestText");
var attrVals = new SearchAttributeCollection.Builder().
Set(attrBool, true).
Set(attrDateTime, new DateTimeOffset(2001, 1, 1, 0, 0, 0, TimeSpan.Zero)).
Set(attrDouble, 123.45).
Set(attrKeyword, "SomeKeyword").
Set(attrKeywordList, new[] { "SomeKeyword1", "SomeKeyword2" }).
Set(attrLong, 678).
Set(attrText, "SomeText").
ToSearchAttributeCollection();
var attrs = new SearchAttributeKey[]
{
attrBool, attrDateTime, attrDouble, attrKeyword, attrKeywordList, attrLong, attrText,
};

// Confirm that when used in env without SAs it fails
await using var env1 = await WorkflowEnvironment.StartLocalAsync();
var exc = await Assert.ThrowsAsync<RpcException>(
() => env1.Client.StartWorkflowAsync(
"my-workflow",
Array.Empty<object?>(),
new(id: $"wf-{Guid.NewGuid()}", taskQueue: $"tq-{Guid.NewGuid()}")
{
TypedSearchAttributes = attrVals,
}));
Assert.Contains("no mapping defined", exc.Message);

// Confirm that when used in env with SAs it succeeds
await using var env2 = await WorkflowEnvironment.StartLocalAsync(
new() { SearchAttributes = attrs });
var handle = await env2.Client.StartWorkflowAsync(
"my-workflow",
Array.Empty<object?>(),
new(id: $"wf-{Guid.NewGuid()}", taskQueue: $"tq-{Guid.NewGuid()}")
{
TypedSearchAttributes = attrVals,
});
Assert.Equal(attrVals, (await handle.DescribeAsync()).TypedSearchAttributes);
}
}

0 comments on commit 19f5de8

Please sign in to comment.