Files
agent-framework/dotnet/tests/CopilotStudio.IntegrationTests/CopilotStudioFixture.cs
T
Roger Barreto e7961571a8 .NET: Update Azure.AI.Projects 2.0.0-beta.1 (#4270)
* Update Microsoft.Agents.AI.AzureAI for Azure.AI.Projects SDK 2.0.0

- Bump Azure.AI.Projects to 2.0.0-alpha.20260213.1
- Bump Azure.AI.Projects.OpenAI to 2.0.0-alpha.20260213.1
- Bump System.ClientModel to 1.9.0 (transitive dependency)
- Switch both GetAgent and CreateAgentVersion to protocol methods
  with MEAI user-agent policy injection via RequestOptions
- Migrate 29 CREATE-path tests from FakeAgentClient to HttpHandlerAssert
  pattern for real HTTP pipeline testing
- Fix StructuredOutputDefinition constructor (BinaryData -> IDictionary)
- Fix responses endpoint path (openai/responses -> /responses)
- Add local-packages NuGet source for pre-release nupkgs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update Azure.AI.Projects to 2.0.0-beta.1 from NuGet.org

- Update Azure.AI.Projects and Azure.AI.Projects.OpenAI to 2.0.0-beta.1
- Remove local-packages NuGet source (packages now on nuget.org)
- Fix MemorySearchTool -> MemorySearchPreviewTool rename
- Fix RedTeams.CreateAsync ambiguous call
- Fix CreateAgentVersion/Async signature change (BinaryData -> string)
- Suppress AAIP001 experimental warning for WorkflowAgentDefinition

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Move s_modelWriterOptionsWire field before methods that use it

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix flaky test: prevent spurious workflow_invoke Activity on timeout wake-up

The StreamingRunEventStream run loop uses a 1-second timeout on
WaitForInputAsync. When the timeout fires before the consumer calls
StopAsync, the loop would create a spurious workflow_invoke Activity
even though no actual input was provided. This caused the
WorkflowRunActivity_IsStopped_Streaming_OffThread_MultiTurnAsync test
to intermittently fail (expecting 2 activities but finding 3).

Fix: guard the loop body with a HasUnprocessedMessages check. On
timeout wake-ups with no work, the loop waits again without creating
an activity or changing the run status.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix epoch race condition causing unit tests to hang on net10.0 and net472

The HasUnprocessedMessages guard (previous commit) correctly prevents
spurious workflow_invoke Activity creation on timeout wake-ups, but
exposed a latent race in the epoch-based signal filtering.

The race: when the run loop processes messages quickly and calls
Interlocked.Increment(ref _completionEpoch) before the consumer calls
TakeEventStreamAsync, the consumer reads the already-incremented epoch
and sets myEpoch = epoch + 1. This causes the consumer to skip the
valid InternalHaltSignal (its epoch < myEpoch) and block forever
waiting for a signal that will never arrive (since the guard prevents
spurious signal generation).

Fix: read _completionEpoch without +1. The +1 was originally needed to
filter stale signals from timeout-driven spurious loop iterations, but
those no longer exist thanks to the HasUnprocessedMessages guard.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Revert "Fix epoch race condition causing unit tests to hang on net10.0 and net472"

This reverts commit 6ce7f01be8.

* Revert "Fix flaky test: prevent spurious workflow_invoke Activity on timeout wake-up"

This reverts commit 98963e17f2.

* Skip hanging multi-turn declarative integration tests

The ValidateMultiTurnAsync tests (ConfirmInput.yaml, RequestExternalInput.yaml)
hang indefinitely in CI, blocking the merge queue. The hang is SDK-independent
(reproduces with both Azure.AI.Projects 1.2.0-beta.5 and 2.0.0-beta.1) and
is a pre-existing issue in the declarative workflow multi-turn test logic.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Remove unused using directive in IntegrationTest.cs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Restore Azure.AI.Projects 2.0.0-beta.1 version bump

The merge from main accidentally reverted the package versions back to
1.2.0-beta.5. This is the primary change of this PR.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address merge conflict

* Skip flaky WorkflowRunActivity_IsStopped_Streaming_OffThread_MultiTurnAsync test

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Skip CheckSystem test cases temporarily

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-04 11:36:39 +00:00

64 lines
2.2 KiB
C#

// Copyright (c) Microsoft. All rights reserved.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using AgentConformance.IntegrationTests;
using AgentConformance.IntegrationTests.Support;
using CopilotStudio.IntegrationTests.Support;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.CopilotStudio;
using Microsoft.Agents.CopilotStudio.Client;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using Shared.IntegrationTests;
namespace CopilotStudio.IntegrationTests;
public class CopilotStudioFixture : IAgentFixture
{
public AIAgent Agent { get; private set; } = null!;
public Task<List<ChatMessage>> GetChatHistoryAsync(AIAgent agent, AgentSession session) =>
throw new NotSupportedException("CopilotStudio doesn't allow retrieval of chat history.");
public Task DeleteSessionAsync(AgentSession session) =>
// Chat Completion does not require/support deleting threads, so this is a no-op.
Task.CompletedTask;
public Task InitializeAsync()
{
const string CopilotStudioHttpClientName = nameof(CopilotStudioAgent);
var settings = new CopilotStudioConnectionSettings(
TestConfiguration.GetRequiredValue(TestSettings.CopilotStudioTenantId),
TestConfiguration.GetRequiredValue(TestSettings.CopilotStudioAgentAppId))
{
DirectConnectUrl = TestConfiguration.GetRequiredValue(TestSettings.CopilotStudioDirectConnectUrl),
};
ServiceCollection services = new();
services
.AddSingleton(settings)
.AddSingleton<CopilotStudioTokenHandler>()
.AddHttpClient(CopilotStudioHttpClientName)
.ConfigurePrimaryHttpMessageHandler<CopilotStudioTokenHandler>();
IHttpClientFactory httpClientFactory =
services
.BuildServiceProvider()
.GetRequiredService<IHttpClientFactory>();
CopilotClient client = new(settings, httpClientFactory, NullLogger.Instance, CopilotStudioHttpClientName);
this.Agent = new CopilotStudioAgent(client);
return Task.CompletedTask;
}
public Task DisposeAsync() => Task.CompletedTask;
}