diff --git a/src/Proto.Actor/InternalsVisibleTo.cs b/src/Proto.Actor/InternalsVisibleTo.cs index ae439a5cbb..4d09680550 100644 --- a/src/Proto.Actor/InternalsVisibleTo.cs +++ b/src/Proto.Actor/InternalsVisibleTo.cs @@ -8,4 +8,5 @@ [assembly: InternalsVisibleTo("Proto.Cluster")] [assembly: InternalsVisibleTo("Proto.Remote")] -[assembly: InternalsVisibleTo("Proto.OpenTelemetry.Tests")] \ No newline at end of file +[assembly: InternalsVisibleTo("Proto.OpenTelemetry.Tests")] +[assembly: InternalsVisibleTo("Proto.Actor.Tests")] diff --git a/tests/Proto.Actor.Tests/ActorMetricsTests.cs b/tests/Proto.Actor.Tests/ActorMetricsTests.cs new file mode 100644 index 0000000000..e94a066d4b --- /dev/null +++ b/tests/Proto.Actor.Tests/ActorMetricsTests.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using System.Diagnostics.Metrics; +using Proto.Metrics; +using Xunit; + +namespace Proto.Tests; + +public class ActorMetricsTests +{ + [Fact] + public void CounterProducesMeasurement() + { + var measurements = new List(); + using var listener = new MeterListener(); + listener.InstrumentPublished = (instrument, l) => + { + if (instrument.Name == ActorMetrics.ActorSpawnCount.Name) + { + l.EnableMeasurementEvents(instrument); + } + }; + listener.SetMeasurementEventCallback((instrument, value, tags, state) => measurements.Add(value)); + listener.Start(); + + ActorMetrics.ActorSpawnCount.Add(5); + + Assert.Contains(5, measurements); + } +} diff --git a/tests/Proto.Actor.Tests/DeduplicationContextTests.cs b/tests/Proto.Actor.Tests/DeduplicationContextTests.cs new file mode 100644 index 0000000000..ad3ee2932f --- /dev/null +++ b/tests/Proto.Actor.Tests/DeduplicationContextTests.cs @@ -0,0 +1,43 @@ +using System; +using System.Threading.Tasks; +using Proto.Deduplication; +using Proto; +using Xunit; + +namespace Proto.Tests; + +public class DeduplicationContextTests +{ + [Fact] + public async Task DuplicatesAreIgnored() + { + await using var system = new ActorSystem(); + var context = system.Root; + var count = 0; + + var props = Props.FromFunc(ctx => + { + if (ctx.Message is string) + { + count++; + } + return Task.CompletedTask; + }).WithContextDecorator(c => new DeduplicationContext( + c, + TimeSpan.FromSeconds(5), + (MessageEnvelope env, out string? key) => + { + key = env.Message as string; + return key != null; + } + )); + + var pid = context.Spawn(props); + context.Send(pid, "one"); + context.Send(pid, "one"); + context.Send(pid, "two"); + await Task.Delay(100); + + Assert.Equal(2, count); + } +} diff --git a/tests/Proto.Actor.Tests/FunctionActorTests.cs b/tests/Proto.Actor.Tests/FunctionActorTests.cs new file mode 100644 index 0000000000..36ab248b2f --- /dev/null +++ b/tests/Proto.Actor.Tests/FunctionActorTests.cs @@ -0,0 +1,30 @@ +using System.Threading.Tasks; +using Xunit; + +namespace Proto.Tests; + +public class FunctionActorTests +{ + [Fact] + public async Task FunctionActorHandlesMessages() + { + await using var system = new ActorSystem(); + var context = system.Root; + var received = false; + + var props = Props.FromFunc(ctx => + { + if (ctx.Message is string) + { + received = true; + } + return Task.CompletedTask; + }); + + var pid = context.Spawn(props); + context.Send(pid, "hello"); + await Task.Delay(50); + + Assert.True(received); + } +} diff --git a/tests/Proto.Actor.Tests/ObservableGaugeWrapperTests.cs b/tests/Proto.Actor.Tests/ObservableGaugeWrapperTests.cs new file mode 100644 index 0000000000..d515c5aa55 --- /dev/null +++ b/tests/Proto.Actor.Tests/ObservableGaugeWrapperTests.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.Metrics; +using System.Linq; +using Proto.Metrics; +using Xunit; + +namespace Proto.Tests; + +public class ObservableGaugeWrapperTests +{ + [Fact] + public void ObserverManagementWorks() + { + var gauge = new ObservableGaugeWrapper(); + Func>> obs1 = () => new[] { new Measurement(1) }; + Func>> obs2 = () => new[] { new Measurement(2) }; + + gauge.AddObserver(obs1); + gauge.AddObserver(obs2); + + var values = gauge.Observe().Select(m => m.Value).ToArray(); + Assert.Contains(1, values); + Assert.Contains(2, values); + + gauge.RemoveObserver(obs1); + values = gauge.Observe().Select(m => m.Value).ToArray(); + Assert.DoesNotContain(1, values); + Assert.Contains(2, values); + } +}