|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- // Copyright (c) Microsoft Corporation. All rights reserved.
- // LifecycleObjectTests.cs
-
- using FluentAssertions;
- using Microsoft.AutoGen.AgentChat.GroupChat;
- using Xunit;
-
- namespace Microsoft.AutoGen.AgentChat.Tests;
-
- internal sealed class LifecycleObjectFixture : LifecycleObject
- {
- public enum LifecycleState
- {
- Deinitialized,
- Initialized
- }
-
- public LifecycleState State { get; private set; }
-
- public Func<ValueTask> DeinitializeOverride { get; set; } = () => ValueTask.CompletedTask;
- public Func<ValueTask> InitializeOverride { get; set; } = () => ValueTask.CompletedTask;
-
- public Action InitializeErrorOverride { get; set; }
- public Action DeinitializeErrorOverride { get; set; }
-
- private int initializeCallCount;
- private int deinitializeCallCount;
- private int initializeErrorCount;
- private int deinitializeErrorCount;
-
- public int InitializeCallCount => this.initializeCallCount;
- public int DeinitializeCallCount => this.deinitializeCallCount;
- public int InitializeErrorCount => this.initializeErrorCount;
- public int DeinitializeErrorCount => this.deinitializeErrorCount;
-
- public LifecycleObjectFixture()
- {
- this.State = LifecycleState.Deinitialized;
-
- this.InitializeErrorOverride = base.OnInitializeError;
- this.DeinitializeErrorOverride = base.OnDeinitializeError;
- }
-
- protected override void OnInitializeError()
- {
- Interlocked.Increment(ref this.initializeErrorCount);
-
- this.InitializeErrorOverride();
- }
-
- protected override void OnDeinitializeError()
- {
- Interlocked.Increment(ref this.deinitializeErrorCount);
-
- this.DeinitializeErrorOverride();
- }
-
- protected sealed override ValueTask DeinitializeCore()
- {
- Interlocked.Increment(ref this.deinitializeCallCount);
- this.State = LifecycleState.Deinitialized;
-
- return DeinitializeOverride();
- }
-
- protected sealed override ValueTask InitializeCore()
- {
- Interlocked.Increment(ref this.initializeCallCount);
- this.State = LifecycleState.Initialized;
-
- return InitializeOverride();
- }
- }
-
- [Trait("Category", "UnitV2")]
- public class LifecycleObjectTests
- {
- /*
- We should be testing the following conditions:
- - SmokeTest: Happy path: Initialize, Deinitialize, Initialize, Deinitialize, validate states and call counts
- - Error handling: Initialize, Initialize; Deinitialize; Initialize, Deinitialize, Deinitialize
- */
-
- [Fact]
- public async Task InitializeAndDeinitialize_SucceedsTwice()
- {
- // Arrange
- LifecycleObjectFixture fixture = new();
-
- // Validate preconditions
- fixture.State.Should().Be(LifecycleObjectFixture.LifecycleState.Deinitialized, "LifecycleObject should be in Deinitialized state initially");
- fixture.InitializeCallCount.Should().Be(0, "Initialize should not have been called yet");
- fixture.DeinitializeCallCount.Should().Be(0, "Deinitialize should not have been called yet");
- fixture.InitializeErrorCount.Should().Be(0, "there should be no initialization errors");
- fixture.DeinitializeErrorCount.Should().Be(0, "there should be no deinitialization errors");
-
- // Act
- await fixture.InitializeAsync();
-
- // Validate postconditions 1
- fixture.State.Should().Be(LifecycleObjectFixture.LifecycleState.Initialized, "LifecycleObject should be in Initialized state after Initialize");
- fixture.InitializeCallCount.Should().Be(1, "Initialize should have been called once");
- fixture.DeinitializeCallCount.Should().Be(0, "Deinitialize should not have been called yet");
- fixture.InitializeErrorCount.Should().Be(0, "there should be no initialization errors");
- fixture.DeinitializeErrorCount.Should().Be(0, "there should be no deinitialization errors");
-
- // Act 2
- await fixture.DeinitializeAsync();
-
- // Validate postconditions 2
- fixture.State.Should().Be(LifecycleObjectFixture.LifecycleState.Deinitialized, "LifecycleObject should be in Deinitialized state after Deinitialize");
- fixture.InitializeCallCount.Should().Be(1, "Initialize should have been called once");
- fixture.DeinitializeCallCount.Should().Be(1, "Deinitialize should have been called once");
- fixture.InitializeErrorCount.Should().Be(0, "there should be no initialization errors");
- fixture.DeinitializeErrorCount.Should().Be(0, "there should be no deinitialization errors");
-
- // Act 3
-
- await fixture.InitializeAsync();
-
- // Validate postconditions 3
-
- fixture.State.Should().Be(LifecycleObjectFixture.LifecycleState.Initialized, "LifecycleObject should be in Initialized state after Initialize");
- fixture.InitializeCallCount.Should().Be(2, "Initialize should have been called twice");
- fixture.DeinitializeCallCount.Should().Be(1, "Deinitialize should have been called once");
- fixture.InitializeErrorCount.Should().Be(0, "there should be no initialization errors");
- fixture.DeinitializeErrorCount.Should().Be(0, "there should be no deinitialization errors");
-
- // Act 4
-
- await fixture.DeinitializeAsync();
-
- // Validate postconditions 4
-
- fixture.State.Should().Be(LifecycleObjectFixture.LifecycleState.Deinitialized, "LifecycleObject should be in Deinitialized state after Deinitialize");
- fixture.InitializeCallCount.Should().Be(2, "Initialize should have been called twice");
- fixture.DeinitializeCallCount.Should().Be(2, "Deinitialize should have been called twice");
- fixture.InitializeErrorCount.Should().Be(0, "there should be no initialization errors");
- fixture.DeinitializeErrorCount.Should().Be(0, "there should be no deinitialization errors");
- }
-
- [Fact]
- public async Task Initialize_FailsWhenInitialized()
- {
- // Testing two things: We should expect InvalidOperationException by default, and that we called into the override
-
- // Arrange
- LifecycleObjectFixture fixture = new();
- await fixture.InitializeAsync();
-
- // Act
- Func<Task> secondInitialization = async () => await fixture.InitializeAsync();
-
- // Assert
- await secondInitialization.Should().ThrowAsync<InvalidOperationException>("LifecycleObject.InitializeAsync should throw InvalidOperationException when initialized");
-
- fixture.InitializeCallCount.Should().Be(1, "Initialize should have been called once successfully");
- fixture.InitializeErrorCount.Should().Be(1, "there should be one initialization error");
- fixture.DeinitializeCallCount.Should().Be(0, "Deinitialize should not have been called yet");
- fixture.DeinitializeErrorCount.Should().Be(0, "there should be no deinitialization errors");
- }
-
- [Fact]
- public async Task Deinitialize_FailsWhenNotInitialized()
- {
- // Arrange
- LifecycleObjectFixture fixture = new();
-
- // Act
- Func<Task> deinitialization = async () => await fixture.DeinitializeAsync();
-
- // Assert
- await deinitialization.Should().ThrowAsync<InvalidOperationException>("LifecycleObject.DeinitializeAsync should throw InvalidOperationException when not initialized");
-
- fixture.InitializeCallCount.Should().Be(0, "Initialize should not have been called yet");
- fixture.InitializeErrorCount.Should().Be(0, "there should be no initialization errors");
- fixture.DeinitializeCallCount.Should().Be(0, "Deinitialize should not have been called successfully yet");
- fixture.DeinitializeErrorCount.Should().Be(1, "there should be one deinitialization error");
-
- // Act 2
- await fixture.InitializeAsync();
- await fixture.DeinitializeAsync();
-
- Func<Task> secondDeinitialization = async () => await fixture.DeinitializeAsync();
-
- // Assert 2
- await secondDeinitialization.Should().ThrowAsync<InvalidOperationException>("LifecycleObject.DeinitializeAsync should throw InvalidOperationException when not initialized");
-
- fixture.InitializeCallCount.Should().Be(1, "Initialize should have been called once successfully");
- fixture.InitializeErrorCount.Should().Be(0, "there should be no initialization errors");
- fixture.DeinitializeCallCount.Should().Be(1, "Deinitialize should have been called successfully once");
- fixture.DeinitializeErrorCount.Should().Be(2, "there should be two deinitialization errors");
- }
- }
|