From 512a56c938b86516f43718c4bcaac1427f71621e Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Thu, 10 Apr 2025 11:45:56 -0500 Subject: [PATCH 1/4] Make IPublishingActivityProgressReporter mockable Also add a Null reporter to easily use in tests. --- .../NullPublishingActivityProgressReporter.cs | 34 +++++++++++++++++++ .../PublishingActivityProgressReporter.cs | 13 ++++--- 2 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 src/Aspire.Hosting/Publishing/NullPublishingActivityProgressReporter.cs diff --git a/src/Aspire.Hosting/Publishing/NullPublishingActivityProgressReporter.cs b/src/Aspire.Hosting/Publishing/NullPublishingActivityProgressReporter.cs new file mode 100644 index 00000000000..d0b8ebeefe8 --- /dev/null +++ b/src/Aspire.Hosting/Publishing/NullPublishingActivityProgressReporter.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; + +namespace Aspire.Hosting.Publishing; + +/// +/// Minimalistic reporter that does nothing. +/// +[Experimental("ASPIREPUBLISHERS001")] +public sealed class NullPublishingActivityProgressReporter : IPublishingActivityProgressReporter +{ + /// + public Task CreateActivityAsync(string id, string initialStatusText, bool isPrimary, CancellationToken cancellationToken) + { + var activity = new PublishingActivity(id, isPrimary); + activity.LastStatus = new PublishingActivityStatus + { + Activity = activity, + StatusText = initialStatusText, + IsComplete = false, + IsError = false + }; + + return Task.FromResult(activity); + } + + /// + public Task UpdateActivityStatusAsync(PublishingActivity publishingActivity, Func statusUpdate, CancellationToken cancellationToken) + { + return Task.CompletedTask; + } +} diff --git a/src/Aspire.Hosting/Publishing/PublishingActivityProgressReporter.cs b/src/Aspire.Hosting/Publishing/PublishingActivityProgressReporter.cs index b3592b7b6fa..eaace05f507 100644 --- a/src/Aspire.Hosting/Publishing/PublishingActivityProgressReporter.cs +++ b/src/Aspire.Hosting/Publishing/PublishingActivityProgressReporter.cs @@ -14,7 +14,12 @@ namespace Aspire.Hosting.Publishing; [Experimental("ASPIREPUBLISHERS001")] public sealed class PublishingActivity { - internal PublishingActivity(string id, bool isPrimary = false) + /// + /// Initializes a new instance of the class. + /// + /// The unique identifier for the publishing activity. + /// Indicates whether this activity is the primary activity. + public PublishingActivity(string id, bool isPrimary = false) { Id = id; IsPrimary = isPrimary; @@ -33,7 +38,7 @@ internal PublishingActivity(string id, bool isPrimary = false) /// /// The status text of the publishing activity. /// - public PublishingActivityStatus? LastStatus { get; internal set; } + public PublishingActivityStatus? LastStatus { get; set; } } /// @@ -79,7 +84,7 @@ public interface IPublishingActivityProgressReporter /// The publishing activity /// /// When an activity is created the flag indicates whether this - /// activity is the primary activity. When the primary activity is completed any laumcher + /// activity is the primary activity. When the primary activity is completed any launcher /// which is reading activities will stop listening for updates. /// Task CreateActivityAsync(string id, string initialStatusText, bool isPrimary, CancellationToken cancellationToken); @@ -152,4 +157,4 @@ public async Task UpdateActivityStatusAsync(PublishingActivity publishingActivit } internal Channel ActivityStatusUpdated { get; } = Channel.CreateUnbounded(); -} \ No newline at end of file +} From 5fe1ffa9825d4500eb04f8bff0aa67e7ac500f19 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Thu, 10 Apr 2025 11:51:53 -0500 Subject: [PATCH 2/4] Add test --- ...PublishingActivityProgressReporterTests.cs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/Aspire.Hosting.Tests/Publishing/NullPublishingActivityProgressReporterTests.cs diff --git a/tests/Aspire.Hosting.Tests/Publishing/NullPublishingActivityProgressReporterTests.cs b/tests/Aspire.Hosting.Tests/Publishing/NullPublishingActivityProgressReporterTests.cs new file mode 100644 index 00000000000..8ae8ecd4839 --- /dev/null +++ b/tests/Aspire.Hosting.Tests/Publishing/NullPublishingActivityProgressReporterTests.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#pragma warning disable ASPIREPUBLISHERS001 + +using Aspire.Hosting.Publishing; +using Xunit; + +namespace Aspire.Hosting.Tests.Publishing; + +public class NullPublishingActivityProgressReporterTests +{ + [Fact] + public async Task CanUseNullReporter() + { + var reporter = new NullPublishingActivityProgressReporter(); + var activity = await reporter.CreateActivityAsync("1", "initial", isPrimary: true, default); + await reporter.UpdateActivityStatusAsync(activity, (status) => status with { IsComplete = true }, default); + + Assert.NotNull(activity); + } +} From dfeabac2fcdbdd92355ec9a8e43bf8db6c2e8ba8 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Thu, 10 Apr 2025 12:38:19 -0500 Subject: [PATCH 3/4] Add instance singleton --- .../Publishing/NullPublishingActivityProgressReporter.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Aspire.Hosting/Publishing/NullPublishingActivityProgressReporter.cs b/src/Aspire.Hosting/Publishing/NullPublishingActivityProgressReporter.cs index d0b8ebeefe8..5dc5c746399 100644 --- a/src/Aspire.Hosting/Publishing/NullPublishingActivityProgressReporter.cs +++ b/src/Aspire.Hosting/Publishing/NullPublishingActivityProgressReporter.cs @@ -11,6 +11,15 @@ namespace Aspire.Hosting.Publishing; [Experimental("ASPIREPUBLISHERS001")] public sealed class NullPublishingActivityProgressReporter : IPublishingActivityProgressReporter { + /// + /// Gets the singleton instance of . + /// + public static NullPublishingActivityProgressReporter Instance { get; } = new NullPublishingActivityProgressReporter(); + + private NullPublishingActivityProgressReporter() + { + } + /// public Task CreateActivityAsync(string id, string initialStatusText, bool isPrimary, CancellationToken cancellationToken) { From a30a13e22eeb61ba5970c724e1b8a29e44fa10c0 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Thu, 10 Apr 2025 14:12:02 -0500 Subject: [PATCH 4/4] fixup test --- .../Publishing/NullPublishingActivityProgressReporterTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Aspire.Hosting.Tests/Publishing/NullPublishingActivityProgressReporterTests.cs b/tests/Aspire.Hosting.Tests/Publishing/NullPublishingActivityProgressReporterTests.cs index 8ae8ecd4839..7b9498ff807 100644 --- a/tests/Aspire.Hosting.Tests/Publishing/NullPublishingActivityProgressReporterTests.cs +++ b/tests/Aspire.Hosting.Tests/Publishing/NullPublishingActivityProgressReporterTests.cs @@ -13,7 +13,7 @@ public class NullPublishingActivityProgressReporterTests [Fact] public async Task CanUseNullReporter() { - var reporter = new NullPublishingActivityProgressReporter(); + var reporter = NullPublishingActivityProgressReporter.Instance; var activity = await reporter.CreateActivityAsync("1", "initial", isPrimary: true, default); await reporter.UpdateActivityStatusAsync(activity, (status) => status with { IsComplete = true }, default);