| File: ResourceBuilderLifetimeTests.cs | Web Access |
| Project: src\tests\Aspire.Hosting.Tests\Aspire.Hosting.Tests.csproj (Aspire.Hosting.Tests) |
// 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 ASPIREPERSISTENCE001 // Resource lifetime APIs are experimental. using System.Diagnostics; using Aspire.Hosting.Dcp; using Aspire.Hosting.Utils; namespace Aspire.Hosting.Tests; [Trait("Partition", "2")] public class ResourceBuilderLifetimeTests { [Fact] public void WithPersistentLifetimeAddsPersistenceAnnotation() { using var builder = TestDistributedApplicationBuilder.Create(); var container = builder.AddContainer("container", "image") .WithPersistentLifetime(); var annotation = container.Resource.Annotations.OfType<PersistenceAnnotation>().Single(); Assert.Equal(PersistenceMode.Persistent, annotation.Mode); } [Fact] public void WithPersistentLifetimeRejectsUnsupportedResourceTypes() { using var builder = TestDistributedApplicationBuilder.Create(); var parameter = builder.AddParameter("parameter"); void ConfigureLifetime() => parameter.WithPersistentLifetime(); var exception = Assert.Throws<InvalidOperationException>((Action)ConfigureLifetime); Assert.Contains("does not support lifetime configuration", exception.Message); } [Fact] public void WithPersistentLifetimeReplacesPersistenceAnnotation() { using var builder = TestDistributedApplicationBuilder.Create(); var container = builder.AddContainer("container", "image") .WithParentProcessLifetime(Environment.ProcessId) .WithPersistentLifetime(); var annotation = container.Resource.Annotations.OfType<PersistenceAnnotation>().Single(); Assert.Equal(PersistenceMode.Persistent, annotation.Mode); Assert.Null(annotation.ParentProcessId); Assert.Null(annotation.ParentProcessTimestamp); } [Fact] public void WithParentProcessLifetimeReplacesExistingPersistenceAnnotation() { using var builder = TestDistributedApplicationBuilder.Create(); var container = builder.AddContainer("container", "image") .WithPersistentLifetime(); container.WithParentProcessLifetime(Environment.ProcessId); var annotation = Assert.Single(container.Resource.Annotations.OfType<PersistenceAnnotation>()); Assert.Equal(PersistenceMode.ParentProcess, annotation.Mode); Assert.Equal(Environment.ProcessId, annotation.ParentProcessId); Assert.NotNull(annotation.ParentProcessTimestamp); } [Fact] public void WithLifetimeOfMatchesSourceResourceLifetime() { using var builder = TestDistributedApplicationBuilder.Create(); var source = builder.AddContainer("source", "image") .WithPersistentLifetime(); var container = builder.AddContainer("container", "image") .WithSessionLifetime() .WithLifetimeOf(source); Assert.Equal(Lifetime.Persistent, container.Resource.GetLifetimeType()); var annotation = Assert.Single(container.Resource.Annotations.OfType<PersistenceAnnotation>()); Assert.Equal(PersistenceMode.Resource, annotation.Mode); Assert.Same(source.Resource, annotation.SourceResource); source.WithSessionLifetime(); Assert.Equal(Lifetime.Session, container.Resource.GetLifetimeType()); } [Fact] public void WithLifetimeOfMatchesSourceParentProcessLifetime() { using var builder = TestDistributedApplicationBuilder.Create(); using var parentProcess = Process.GetCurrentProcess(); var parentProcessIdentity = DcpProcessMonitor.GetMonitorProcessIdentity(parentProcess); var source = builder.AddContainer("source", "image") .WithParentProcessLifetime(parentProcess.Id); var container = builder.AddContainer("container", "image") .WithLifetimeOf(source); Assert.True(container.Resource.TryGetParentProcessLifetime(out var parentProcessId, out var parentProcessTimestamp)); Assert.Equal(parentProcessIdentity.ProcessId, parentProcessId); Assert.Equal(parentProcessIdentity.Timestamp, parentProcessTimestamp); source.WithSessionLifetime(); Assert.False(container.Resource.TryGetParentProcessLifetime(out _, out _)); } [Fact] public void ExplicitLifetimeOverridesWithLifetimeOf() { using var builder = TestDistributedApplicationBuilder.Create(); var source = builder.AddContainer("source", "image") .WithSessionLifetime(); var container = builder.AddContainer("container", "image") .WithLifetimeOf(source) .WithPersistentLifetime(); source.WithSessionLifetime(); Assert.Equal(Lifetime.Persistent, container.Resource.GetLifetimeType()); } [Fact] public void WithLifetimeOfRejectsUnsupportedResourceTypes() { using var builder = TestDistributedApplicationBuilder.Create(); var parameter = builder.AddParameter("parameter"); var container = builder.AddContainer("container", "image"); void ConfigureLifetime() => parameter.WithLifetimeOf(container); var exception = Assert.Throws<InvalidOperationException>((Action)ConfigureLifetime); Assert.Contains("does not support lifetime configuration", exception.Message); } [Fact] public void WithLifetimeOfDetectsCircularReferences() { using var builder = TestDistributedApplicationBuilder.Create(); var containerA = builder.AddContainer("container-a", "image"); var containerB = builder.AddContainer("container-b", "image") .WithLifetimeOf(containerA); containerA.WithLifetimeOf(containerB); var exception = Assert.Throws<InvalidOperationException>(() => containerA.Resource.GetLifetimeType()); Assert.Contains("circular lifetime reference", exception.Message); } [Fact] public void WithSessionLifetimeReplacesPersistenceAnnotation() { using var builder = TestDistributedApplicationBuilder.Create(); var container = builder.AddContainer("container", "image") .WithParentProcessLifetime(Environment.ProcessId) .WithSessionLifetime(); var annotation = container.Resource.Annotations.OfType<PersistenceAnnotation>().Single(); Assert.Equal(PersistenceMode.Session, annotation.Mode); Assert.Null(annotation.ParentProcessId); Assert.Null(annotation.ParentProcessTimestamp); } }