From fca1de9279920629d35c5c73de2c8794b77f451a Mon Sep 17 00:00:00 2001 From: Griffin Bassman Date: Thu, 30 Jan 2025 15:02:44 -0500 Subject: [PATCH] feat: dotnet AgentId and MetaData tests (#5271) --- .../Microsoft.AutoGen/Contracts/AgentId.cs | 14 +++ .../AgentIdTests.cs | 109 ++++++++++++++++++ .../AgentMetaDataTests.cs | 20 ++++ 3 files changed, 143 insertions(+) create mode 100644 dotnet/test/Microsoft.AutoGen.Core.Tests/AgentIdTests.cs create mode 100644 dotnet/test/Microsoft.AutoGen.Core.Tests/AgentMetaDataTests.cs diff --git a/dotnet/src/Microsoft.AutoGen/Contracts/AgentId.cs b/dotnet/src/Microsoft.AutoGen/Contracts/AgentId.cs index 28d4a8af4ffe..3098547231ac 100644 --- a/dotnet/src/Microsoft.AutoGen/Contracts/AgentId.cs +++ b/dotnet/src/Microsoft.AutoGen/Contracts/AgentId.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Text.RegularExpressions; namespace Microsoft.AutoGen.Contracts; @@ -16,6 +17,9 @@ namespace Microsoft.AutoGen.Contracts; [DebuggerDisplay($"AgentId(type=\"{nameof(Type)}\", key=\"{nameof(Key)}\")")] public struct AgentId { + private static readonly Regex TypeRegex = new(@"^[a-zA-Z_][a-zA-Z0-9_]*$", RegexOptions.Compiled); + private static readonly Regex KeyRegex = new(@"^[\x20-\x7E]+$", RegexOptions.Compiled); // ASCII 32-126 + /// /// An identifier that associates an agent with a specific factory function. /// Strings may only be composed of alphanumeric letters (a-z) and (0-9), or underscores (_). @@ -35,6 +39,16 @@ public struct AgentId /// Agent instance identifier. public AgentId(string type, string key) { + if (string.IsNullOrWhiteSpace(type) || !TypeRegex.IsMatch(type)) + { + throw new ArgumentException($"Invalid AgentId type: '{type}'. Must be alphanumeric (a-z, 0-9, _) and cannot start with a number or contain spaces."); + } + + if (string.IsNullOrWhiteSpace(key) || !KeyRegex.IsMatch(key)) + { + throw new ArgumentException($"Invalid AgentId key: '{key}'. Must only contain ASCII characters 32-126."); + } + Type = type; Key = key; } diff --git a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentIdTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentIdTests.cs new file mode 100644 index 000000000000..974e9334a18a --- /dev/null +++ b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentIdTests.cs @@ -0,0 +1,109 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// AgentIdTests.cs +using FluentAssertions; +using Microsoft.AutoGen.Contracts; +using Xunit; + +namespace Microsoft.AutoGen.Core.Tests; + +public class AgentIdTests() +{ + [Fact] + public void AgentIdShouldInitializeCorrectlyTest() + { + var agentId = new AgentId("TestType", "TestKey"); + + agentId.Type.Should().Be("TestType"); + agentId.Key.Should().Be("TestKey"); + } + + [Fact] + public void AgentIdShouldConvertFromTupleTest() + { + var agentTuple = ("TupleType", "TupleKey"); + var agentId = new AgentId(agentTuple); + + agentId.Type.Should().Be("TupleType"); + agentId.Key.Should().Be("TupleKey"); + } + + [Fact] + public void AgentIdShouldParseFromStringTest() + { + var agentId = AgentId.FromStr("ParsedType/ParsedKey"); + + agentId.Type.Should().Be("ParsedType"); + agentId.Key.Should().Be("ParsedKey"); + } + + [Fact] + public void AgentIdShouldCompareEqualityCorrectlyTest() + { + var agentId1 = new AgentId("SameType", "SameKey"); + var agentId2 = new AgentId("SameType", "SameKey"); + var agentId3 = new AgentId("DifferentType", "DifferentKey"); + + agentId1.Should().Be(agentId2); + agentId1.Should().NotBe(agentId3); + (agentId1 == agentId2).Should().BeTrue(); + (agentId1 != agentId3).Should().BeTrue(); + } + + [Fact] + public void AgentIdShouldGenerateCorrectHashCodeTest() + { + var agentId1 = new AgentId("HashType", "HashKey"); + var agentId2 = new AgentId("HashType", "HashKey"); + var agentId3 = new AgentId("DifferentType", "DifferentKey"); + + agentId1.GetHashCode().Should().Be(agentId2.GetHashCode()); + agentId1.GetHashCode().Should().NotBe(agentId3.GetHashCode()); + } + + [Fact] + public void AgentIdShouldConvertExplicitlyFromStringTest() + { + var agentId = (AgentId)"ConvertedType/ConvertedKey"; + + agentId.Type.Should().Be("ConvertedType"); + agentId.Key.Should().Be("ConvertedKey"); + } + + [Fact] + public void AgentIdShouldReturnCorrectToStringTest() + { + var agentId = new AgentId("ToStringType", "ToStringKey"); + + agentId.ToString().Should().Be("ToStringType/ToStringKey"); + } + + [Fact] + public void AgentIdShouldCompareInequalityCorrectlyTest() + { + var agentId1 = new AgentId("Type1", "Key1"); + var agentId2 = new AgentId("Type2", "Key2"); + + (agentId1 != agentId2).Should().BeTrue(); + } + + [Fact] + public void AgentIdShouldRejectInvalidNamesTest() + { + // Invalid: 'Type' cannot start with a number and must only contain a-z, 0-9, or underscores. + Action invalidType = () => new AgentId("123InvalidType", "ValidKey"); + invalidType.Should().Throw("Agent type cannot start with a number and must only contain alphanumeric letters or underscores."); + + Action invalidTypeWithSpaces = () => new AgentId("Invalid Type", "ValidKey"); + invalidTypeWithSpaces.Should().Throw("Agent type cannot contain spaces."); + + Action invalidTypeWithSpecialChars = () => new AgentId("Invalid@Type", "ValidKey"); + invalidTypeWithSpecialChars.Should().Throw("Agent type cannot contain special characters."); + + // Invalid: 'Key' must contain only ASCII characters 32 (space) to 126 (~). + Action invalidKey = () => new AgentId("ValidType", "InvalidKey💀"); + invalidKey.Should().Throw("Agent key must only contain ASCII characters between 32 (space) and 126 (~)."); + + Action validCase = () => new AgentId("Valid_Type", "Valid_Key_123"); + validCase.Should().NotThrow("This is a correctly formatted AgentId."); + } +} diff --git a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentMetaDataTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentMetaDataTests.cs new file mode 100644 index 000000000000..c4f0b7b0e606 --- /dev/null +++ b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentMetaDataTests.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// AgentMetaDataTests.cs +using FluentAssertions; +using Microsoft.AutoGen.Contracts; +using Xunit; + +namespace Microsoft.AutoGen.Core.Tests; + +public class AgentMetadataTests() +{ + [Fact] + public void AgentMetadataShouldInitializeCorrectlyTest() + { + var metadata = new AgentMetadata("TestType", "TestKey", "TestDescription"); + + metadata.Type.Should().Be("TestType"); + metadata.Key.Should().Be("TestKey"); + metadata.Description.Should().Be("TestDescription"); + } +}