Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/dotnet-build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ jobs:
- name: Setup dotnet
uses: actions/[email protected]
with:
global-json-file: ${{ github.workspace }}/dotnet/global.json
global-json-file: ${{ github.workspace }}/global.json
- name: Build dotnet solutions
shell: bash
run: |
Expand Down Expand Up @@ -133,7 +133,7 @@ jobs:

# Check if the project supports the target framework
if [[ "$target_frameworks" == *"${{ matrix.targetFramework }}"* ]]; then
dotnet test -f ${{ matrix.targetFramework }} -c ${{ matrix.configuration }} $project --no-build -v Normal --logger trx --collect:"XPlat Code Coverage" --results-directory:"TestResults/Coverage/" -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.ExcludeByAttribute=GeneratedCodeAttribute,CompilerGeneratedAttribute,ExcludeFromCodeCoverageAttribute
dotnet test -f ${{ matrix.targetFramework }} -c ${{ matrix.configuration }} --project $project --no-progress --no-build -v Normal --report-trx --results-directory "TestResults/Coverage/" --coverage --coverage-output-format cobertura --coverage-settings "${{ github.workspace }}/dotnet/coverage.config"
else
echo "Skipping $project - does not support target framework ${{ matrix.targetFramework }} (supports: $target_frameworks)"
fi
Expand Down Expand Up @@ -170,7 +170,7 @@ jobs:

# Check if the project supports the target framework
if [[ "$target_frameworks" == *"${{ matrix.targetFramework }}"* ]]; then
dotnet test -f ${{ matrix.targetFramework }} -c ${{ matrix.configuration }} $project --no-build -v Normal --logger trx
dotnet test -f ${{ matrix.targetFramework }} -c ${{ matrix.configuration }} --project $project --no-progress --no-build -v Normal --report-trx
else
echo "Skipping $project - does not support target framework ${{ matrix.targetFramework }} (supports: $target_frameworks)"
fi
Expand All @@ -196,7 +196,7 @@ jobs:
- name: Generate test reports
uses: danielpalme/[email protected]
with:
reports: "./TestResults/Coverage/**/coverage.cobertura.xml"
reports: "./TestResults/Coverage/**/*.cobertura.xml"
targetdir: "./TestResults/Reports"
reporttypes: "HtmlInline;JsonSummary"

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/dotnet-format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
fail-fast: false
matrix:
include:
- { dotnet: "9.0", configuration: Release, os: ubuntu-latest }
- { dotnet: "10.0", configuration: Release, os: ubuntu-latest }

runs-on: ${{ matrix.os }}
env:
Expand Down
1 change: 1 addition & 0 deletions dotnet/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ dotnet_diagnostic.VSTHRD111.severity = none # Use .ConfigureAwait(bool) is hidde

dotnet_diagnostic.xUnit1004.severity = none # Test methods should not be skipped. Remove the Skip property to start running the test again.
dotnet_diagnostic.xUnit1042.severity = none # Untyped data rows
dotnet_diagnostic.xUnit1051.severity = none

dotnet_diagnostic.RCS1032.severity = none # Remove redundant parentheses.
dotnet_diagnostic.RCS1074.severity = none # Remove redundant constructor.
Expand Down
14 changes: 7 additions & 7 deletions dotnet/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,13 @@
<!-- Test -->
<PackageVersion Include="FluentAssertions" Version="8.8.0" />
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="9.0.11" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.0" />
<PackageVersion Include="Moq" Version="[4.18.4]" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.abstractions" Version="2.0.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.3" />
<PackageVersion Include="xretry" Version="1.9.0" />
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
<PackageVersion Include="xunit.v3.mtp-v2" Version="3.2.0" />
<PackageVersion Include="xunit.v3.extensibility.core" Version="3.2.0" />
<PackageVersion Include="xunit.v3.assert" Version="3.2.0" />
<PackageVersion Include="xretry.v3" Version="1.0.0-rc2" />
<PackageVersion Include="Microsoft.Testing.Extensions.TrxReport" Version="2.0.2" />
<PackageVersion Include="Microsoft.Testing.Extensions.CodeCoverage" Version="18.1.0" />
<!-- Symbols -->
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<!-- Toolset -->
Expand All @@ -139,7 +139,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageVersion Include="xunit.analyzers" Version="1.23.0" />
<PackageVersion Include="xunit.analyzers" Version="1.25.0" />
<PackageReference Include="xunit.analyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
14 changes: 14 additions & 0 deletions dotnet/coverage.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Configuration>
<CodeCoverage>
<!-- Match attributes on any code element: -->
<Attributes>
<Exclude>
<!-- Don't forget "Attribute" at the end of the name -->
<Attribute>^System\.CodeDom\.Compiler\.GeneratedCodeAttribute$</Attribute>
<Attribute>^System\.Diagnostics\.CodeAnalysis\.ExcludeFromCodeCoverageAttribute$</Attribute>
<Attribute>^System\.Runtime\.CompilerServices\.CompilerGeneratedAttribute$</Attribute>
</Exclude>
</Attributes>
</CodeCoverage>
</Configuration>
7 changes: 0 additions & 7 deletions dotnet/global.json
Copy link
Member

@rogerbarreto rogerbarreto Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is global moved to the repo root? This is a dotnet specific setting

Suggest not changing it to .Net 10 as this is not the purpose of the PR.

Copy link
Member Author

@Youssef1313 Youssef1313 Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The move to repo root is to allow running dotnet test --project dotnet/path/to/csproj as done in CI. Otherwise, the .NET CLI won't be able to find the global.json and then you have to cd dotnet first before invoking dotnet test. (also if you moved from GH Actions to Azure Pipelines and used DotnetCoreCLI task, it looks for global.json at root as well)

The switch to .NET 10 is kinda related, as that's what works best with xunit.v3 and Microsoft.Testing.Platform v2.

I'm fine getting a PR for updating to .NET 10 first separately though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Copy link
Contributor

@DeagleGross DeagleGross Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But you have changed the CI as well to point to a different location:

global-json-file: ${{ github.workspace }}/global.json

instead of

global-json-file: ${{ github.workspace }}/dotnet/global.json

I dont think there is a problem with having global.json under dotnet/ directory, can we rollback this change? It seems strange to have a dotnet related artifact in the repo root

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The global-json-file in YML is aligned with the change.

Having it under dotnet/ is really problematic as it means you cannot invoke dotnet test from repo root.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFrameworks>$(ProjectsTargetFrameworks)</TargetFrameworks>
<IsTestProject>false</IsTestProject>
<IsTestUtilityProject>true</IsTestUtilityProject>
</PropertyGroup>

<ItemGroup>
Expand Down
10 changes: 8 additions & 2 deletions dotnet/tests/AgentConformance.IntegrationTests/AgentTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,17 @@ public abstract class AgentTests<TAgentFixture>(Func<TAgentFixture> createAgentF
{
protected TAgentFixture Fixture { get; private set; } = default!;

public Task InitializeAsync()
public ValueTask InitializeAsync()
{
this.Fixture = createAgentFixture();
return this.Fixture.InitializeAsync();
}

public Task DisposeAsync() => this.Fixture.DisposeAsync();
public async ValueTask DisposeAsync()
{
await this.Fixture.DisposeAsync();

// https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1816
GC.SuppressFinalize(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -144,17 +144,18 @@ private async Task DeleteResponseChainAsync(string lastResponseId)
}
}

public Task DisposeAsync()
public async ValueTask DisposeAsync()
{
if (this._client is not null && this._agent is not null)
{
return this._client.Agents.DeleteAgentAsync(this._agent.Name);
await this._client.Agents.DeleteAgentAsync(this._agent.Name);
}

return Task.CompletedTask;
// https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1816
GC.SuppressFinalize(this);
}

public async Task InitializeAsync()
public async ValueTask InitializeAsync()
{
this._client = new(new Uri(s_config.Endpoint), new AzureCliCredential());
this._agent = await this.CreateChatClientAgentAsync();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TargetFrameworks>$(ProjectsTargetFrameworks)</TargetFrameworks>
<TargetFrameworks Condition="'$(Configuration)' == 'Debug'">$(ProjectsDebugTargetFrameworks)</TargetFrameworks>
<InjectSharedIntegrationTestCode>True</InjectSharedIntegrationTestCode>
<OutputType>Exe</OutputType>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TargetFrameworks>$(ProjectsTargetFrameworks)</TargetFrameworks>
<TargetFrameworks Condition="'$(Configuration)' == 'Debug'">$(ProjectsDebugTargetFrameworks)</TargetFrameworks>
<InjectSharedIntegrationTestCode>True</InjectSharedIntegrationTestCode>
<OutputType>Exe</OutputType>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) Microsoft. All rights reserved.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using AgentConformance.IntegrationTests;
Expand Down Expand Up @@ -86,17 +87,18 @@ public Task DeleteThreadAsync(AgentThread thread)
return Task.CompletedTask;
}

public Task DisposeAsync()
public async ValueTask DisposeAsync()
{
if (this._persistentAgentsClient is not null && this._agent is not null)
{
return this._persistentAgentsClient.Administration.DeleteAgentAsync(this._agent.Id);
await this._persistentAgentsClient.Administration.DeleteAgentAsync(this._agent.Id);
}

return Task.CompletedTask;
// https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1816
GC.SuppressFinalize(this);
}

public async Task InitializeAsync()
public async ValueTask InitializeAsync()
{
this._persistentAgentsClient = new(s_config.Endpoint, new AzureCliCredential());
this._agent = await this.CreateChatClientAgentAsync();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<TargetFrameworks Condition="'$(Configuration)' == 'Debug'">$(ProjectsDebugTargetFrameworks)</TargetFrameworks>
<InjectSharedIntegrationTestCode>True</InjectSharedIntegrationTestCode>
<InjectSharedThrow>true</InjectSharedThrow>
<OutputType>Exe</OutputType>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public Task DeleteThreadAsync(AgentThread thread) =>
// Chat Completion does not require/support deleting threads, so this is a no-op.
Task.CompletedTask;

public Task InitializeAsync()
public ValueTask InitializeAsync()
{
const string CopilotStudioHttpClientName = nameof(CopilotStudioAgent);

Expand All @@ -54,8 +54,13 @@ public Task InitializeAsync()

this.Agent = new CopilotStudioAgent(client);

return Task.CompletedTask;
return default;
}

public Task DisposeAsync() => Task.CompletedTask;
public ValueTask DisposeAsync()
{
// https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1816
GC.SuppressFinalize(this);
return default;
}
}
15 changes: 8 additions & 7 deletions dotnet/tests/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,25 @@

<PropertyGroup>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<UseMicrosoftTestingPlatformRunner>true</UseMicrosoftTestingPlatformRunner>
<IsAotCompatible>false</IsAotCompatible>
<ProjectsTargetFrameworks>net472;net9.0</ProjectsTargetFrameworks>
<UserSecretsId>b7762d10-e29b-4bb1-8b74-b6d69a667dd4</UserSecretsId>
<NoWarn>$(NoWarn);Moq1410;xUnit2023</NoWarn>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Moq" />
<PackageReference Include="xRetry" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.visualstudio" />
<PackageReference Include="xRetry.v3" />
<PackageReference Include="xunit.v3.mtp-v2" Condition="'$(IsTestUtilityProject)'!='true'" />
<PackageReference Include="Microsoft.Testing.Extensions.TrxReport" Condition="'$(IsTestUtilityProject)'!='true'" />
<PackageReference Include="Microsoft.Testing.Extensions.CodeCoverage" Condition="'$(IsTestUtilityProject)'!='true'" />
<PackageReference Include="xunit.v3.extensibility.core" Condition="'$(IsTestUtilityProject)'=='true'" />
<PackageReference Include="xunit.v3.assert" Condition="'$(IsTestUtilityProject)'=='true'" />
</ItemGroup>

<ItemGroup>
<Using Include="xRetry" />
<Using Include="xRetry.v3" />
<Using Include="Xunit" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<PropertyGroup>
<TargetFrameworks>$(ProjectsTargetFrameworks)</TargetFrameworks>
<OutputType>Exe</OutputType>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<PropertyGroup>
<TargetFrameworks>$(ProjectsTargetFrameworks)</TargetFrameworks>
<OutputType>Exe</OutputType>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,22 @@ public void InvokingContext_Constructor_ThrowsForNullMessages()
Assert.Throws<ArgumentNullException>(() => new AIContextProvider.InvokingContext(null!));
}

[Fact]
public void InvokingContext_Constructor_DoesNotThrowForEmptyMessages()
{
var context = new AIContextProvider.InvokingContext([]);
Assert.Empty(context.RequestMessages);
}

[Fact]
public void InvokingContext_Constructor_DoesNotThrowForSingleMessages()
{
var expected = new ChatMessage(ChatRole.User, "Message content");
var context = new AIContextProvider.InvokingContext([expected]);
var actual = Assert.Single(context.RequestMessages);
Assert.Equal(expected, actual);
}

[Fact]
public void InvokedContext_Constructor_ThrowsForNullMessages()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,28 @@ public void CloningConstructorCopiesProperties()
Assert.Equal(42, clone.AdditionalProperties["key2"]);
}

[Fact]
public void CloningConstructorWithNullProperties()
{
// Arrange
var options = new AgentRunOptions
{
ContinuationToken = new object(),
AllowBackgroundResponses = true,
AdditionalProperties = null,
};

// Act
var clone = new AgentRunOptions(options);

// Assert
Assert.NotNull(clone);
Assert.Same(options.ContinuationToken, clone.ContinuationToken);
Assert.Equal(options.AllowBackgroundResponses, clone.AllowBackgroundResponses);
Assert.Null(clone.AdditionalProperties);
Assert.Null(options.AdditionalProperties);
}

[Fact]
public void CloningConstructorThrowsIfNull() =>
// Act & Assert
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<PropertyGroup>
<TargetFrameworks>$(ProjectsTargetFrameworks)</TargetFrameworks>
<NoWarn>$(NoWarn);MEAI001</NoWarn>
<OutputType>Exe</OutputType>
</PropertyGroup>

<PropertyGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<PropertyGroup>
<TargetFrameworks>$(ProjectsTargetFrameworks)</TargetFrameworks>
<OutputType>Exe</OutputType>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<PropertyGroup>
<TargetFrameworks>$(ProjectsTargetFrameworks)</TargetFrameworks>
<OutputType>Exe</OutputType>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using Microsoft.DurableTask.Entities;
using Microsoft.Extensions.Configuration;
using OpenAI;
using Xunit.Abstractions;

namespace Microsoft.Agents.AI.DurableTask.IntegrationTests;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Configuration;
using OpenAI;
using Xunit.Abstractions;

namespace Microsoft.Agents.AI.DurableTask.IntegrationTests;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

using System.Collections.Concurrent;
using Microsoft.Extensions.Logging;
using Xunit.Abstractions;

namespace Microsoft.Agents.AI.DurableTask.IntegrationTests.Logging;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

using System.Collections.Concurrent;
using Microsoft.Extensions.Logging;
using Xunit.Abstractions;

namespace Microsoft.Agents.AI.DurableTask.IntegrationTests.Logging;

Expand Down
Loading
Loading