Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ namespace OpenFeature.Contrib.Providers.Flagd.Test.Resolver.Rpc;

public class RpcResolverTests
{
private const int TestTimeoutMilliseconds = 10_000;

[Fact]
public async Task HandleEvents_CallsFlagdProviderEventHandler()
{
Expand Down Expand Up @@ -53,19 +55,21 @@ public async Task HandleEvents_CallsFlagdProviderEventHandler()
}
};

var autoResetEvent = new AutoResetEvent(false);
var mockGrpcClient = SetupGrpcStream(responses);

var config = new FlagdConfig();

FlagdProviderEvent flagdProviderEvent = null;
var resolver = new RpcResolver(mockGrpcClient, config, null, ctx => flagdProviderEvent = ctx);
var resolver = new RpcResolver(mockGrpcClient, config, null, ctx => { flagdProviderEvent = ctx; autoResetEvent.Set(); });

// Act
await resolver.Init();

// Assert
await Utils.AssertUntilAsync((ct) => { Assert.NotNull(flagdProviderEvent); return Task.CompletedTask; });
Assert.True(autoResetEvent.WaitOne(TestTimeoutMilliseconds));

Assert.NotNull(flagdProviderEvent);
Assert.Equal(Constant.ProviderEventTypes.ProviderReady, flagdProviderEvent.EventType);
Assert.Contains("key1", flagdProviderEvent.FlagsChanged);
Assert.Contains("key1", flagdProviderEvent.FlagsChanged);
Expand All @@ -90,19 +94,21 @@ public async Task HandleEvents_WithNoFlags_CallsFlagdProviderEventHandler()
}
};

var autoResetEvent = new AutoResetEvent(false);
var mockGrpcClient = SetupGrpcStream(responses);

var config = new FlagdConfig();

FlagdProviderEvent flagdProviderEvent = null;
var resolver = new RpcResolver(mockGrpcClient, config, null, ctx => flagdProviderEvent = ctx);
var resolver = new RpcResolver(mockGrpcClient, config, null, ctx => { flagdProviderEvent = ctx; autoResetEvent.Set(); });

// Act
await resolver.Init();

// Assert
await Utils.AssertUntilAsync((ct) => { Assert.NotNull(flagdProviderEvent); return Task.CompletedTask; });
Assert.True(autoResetEvent.WaitOne(TestTimeoutMilliseconds));

Assert.NotNull(flagdProviderEvent);
Assert.Equal(Constant.ProviderEventTypes.ProviderReady, flagdProviderEvent.EventType);
Assert.Empty(flagdProviderEvent.FlagsChanged);
Assert.Equal(Structure.Empty, flagdProviderEvent.SyncMetadata);
Expand All @@ -128,19 +134,21 @@ public async Task HandleEvents_WhenConfigChanged_CallsFlagdProviderEventHandler(
}
};

var autoResetEvent = new AutoResetEvent(false);
var mockGrpcClient = SetupGrpcStream(responses);

var config = new FlagdConfig();

FlagdProviderEvent flagdProviderEvent = null;
var resolver = new RpcResolver(mockGrpcClient, config, null, ctx => flagdProviderEvent = ctx);
var resolver = new RpcResolver(mockGrpcClient, config, null, ctx => { flagdProviderEvent = ctx; autoResetEvent.Set(); });

// Act
await resolver.Init();

// Assert
await Utils.AssertUntilAsync((ct) => { Assert.NotNull(flagdProviderEvent); return Task.CompletedTask; });
Assert.True(autoResetEvent.WaitOne(TestTimeoutMilliseconds));

Assert.NotNull(flagdProviderEvent);
Assert.Equal(Constant.ProviderEventTypes.ProviderConfigurationChanged, flagdProviderEvent.EventType);
Assert.Contains("key1", flagdProviderEvent.FlagsChanged);
Assert.Equal(Structure.Empty, flagdProviderEvent.SyncMetadata);
Expand All @@ -166,29 +174,28 @@ public async Task HandleEvents_PurgesCache()
}
};

var autoResetEvent = new AutoResetEvent(false);
var mockGrpcClient = SetupGrpcStream(responses);

var config = new FlagdConfig()
{
CacheEnabled = true
};

var purgedCalled = false;
var mockCache = Substitute.For<ICache<string, object>>();
mockCache.TryGet(Arg.Is<string>(s => s == "key1")).Returns(null);
mockCache.Add(Arg.Is<string>(s => s == "key1"), Arg.Any<object>());
mockCache.When(x => x.Purge()).Do(_ => purgedCalled = true);
mockCache.When(x => x.Purge()).Do(_ => { autoResetEvent.Set(); });

FlagdProviderEvent flagdProviderEvent = null;
var resolver = new RpcResolver(mockGrpcClient, config, mockCache, ctx => flagdProviderEvent = ctx);
var resolver = new RpcResolver(mockGrpcClient, config, mockCache, ctx => { });

// Act
await resolver.Init();

// Assert
await Utils.AssertUntilAsync((ct) => { Assert.NotNull(flagdProviderEvent); return Task.CompletedTask; });
Assert.True(autoResetEvent.WaitOne(TestTimeoutMilliseconds));

Assert.True(purgedCalled);
mockCache.Received().Purge();
}

[Fact]
Expand All @@ -211,29 +218,28 @@ public async Task HandleEvents_WhenConfigChanged_DeletesCacheItem()
}
};

var autoResetEvent = new AutoResetEvent(false);
var mockGrpcClient = SetupGrpcStream(responses);

var config = new FlagdConfig()
{
CacheEnabled = true
};

var deletedCalled = false;
var mockCache = Substitute.For<ICache<string, object>>();
mockCache.TryGet(Arg.Is<string>(s => s == "key1")).Returns(null);
mockCache.Add(Arg.Is<string>(s => s == "key1"), Arg.Any<object>());
mockCache.When(x => x.Delete("key1")).Do(_ => deletedCalled = true);
mockCache.When(x => x.Delete("key1")).Do(_ => { autoResetEvent.Set(); });

FlagdProviderEvent flagdProviderEvent = null;
var resolver = new RpcResolver(mockGrpcClient, config, mockCache, ctx => flagdProviderEvent = ctx);
var resolver = new RpcResolver(mockGrpcClient, config, mockCache, ctx => { });

// Act
await resolver.Init();

// Assert
await Utils.AssertUntilAsync((ct) => { Assert.NotNull(flagdProviderEvent); return Task.CompletedTask; });
Assert.True(autoResetEvent.WaitOne(TestTimeoutMilliseconds));

Assert.True(deletedCalled);
mockCache.Received().Delete("key1");
}

private static Service.ServiceClient SetupGrpcStream(List<EventStreamResponse> responses)
Expand All @@ -246,7 +252,8 @@ private static Service.ServiceClient SetupGrpcStream(List<EventStreamResponse> r
asyncStreamReader.Current.Returns(_ => enumerator.Current);

var grpcEventStreamResp = new AsyncServerStreamingCall<EventStreamResponse>(asyncStreamReader, null, null, null, null, null);
mockGrpcClient.EventStream(Arg.Any<EventStreamRequest>(), null, null, CancellationToken.None).Returns(grpcEventStreamResp);
mockGrpcClient.EventStream(Arg.Any<EventStreamRequest>(), null, null, CancellationToken.None)
.Returns(grpcEventStreamResp);

return mockGrpcClient;
}
Expand Down