Skip to content

Commit

Permalink
Increase code coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
stephentoub committed Dec 3, 2024
1 parent d2efdba commit 4f3ab61
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<PropertyGroup>
<Stage>preview</Stage>
<SuppressFinalPackageVersion>true</SuppressFinalPackageVersion>
<MinCodeCoverage>83</MinCodeCoverage>
<MinCodeCoverage>91</MinCodeCoverage>
<MinMutationScore>0</MinMutationScore>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Microsoft.Extensions.AI;

public sealed class TestEmbeddingGenerator : IEmbeddingGenerator<string, Embedding<float>>
{
public EmbeddingGeneratorMetadata Metadata { get; } = new();
public EmbeddingGeneratorMetadata Metadata { get; set; } = new();

public Func<IEnumerable<string>, EmbeddingGenerationOptions?, CancellationToken, Task<GeneratedEmbeddings<Embedding<float>>>>? GenerateAsyncCallback { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,24 @@ public void DoesNotAllowFactoriesToReturnNull()
Assert.Contains("entry at index 0", ex.Message);
}

[Fact]
public void UsesEmptyServiceProviderWhenNoServicesProvided()
{
using var innerClient = new TestChatClient();
ChatClientBuilder builder = new(innerClient);
builder.Use((innerClient, serviceProvider) =>
{
Assert.Null(serviceProvider.GetService(typeof(object)));

var keyedServiceProvider = Assert.IsAssignableFrom<IKeyedServiceProvider>(serviceProvider);
Assert.Null(keyedServiceProvider.GetKeyedService(typeof(object), "key"));
Assert.Throws<InvalidOperationException>(() => keyedServiceProvider.GetRequiredKeyedService(typeof(object), "key"));

return innerClient;
});
builder.Build();
}

private sealed class InnerClientCapturingChatClient(string name, IChatClient innerClient) : DelegatingChatClient(innerClient)
{
#pragma warning disable S3604 // False positive: Member initializer values should not be redundant
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ async static IAsyncEnumerable<StreamingChatCompletionUpdate> CallbackAsync(
};
}

var chatClient = innerClient
using var chatClient = innerClient
.AsBuilder()
.UseOpenTelemetry(loggerFactory, sourceName, configure: instance =>
{
Expand Down Expand Up @@ -125,6 +125,7 @@ async static IAsyncEnumerable<StreamingChatCompletionUpdate> CallbackAsync(
PresencePenalty = 5.0f,
ResponseFormat = ChatResponseFormat.Json,
Temperature = 6.0f,
Seed = 42,
StopSequences = ["hello", "world"],
AdditionalProperties = new()
{
Expand Down Expand Up @@ -166,6 +167,7 @@ async static IAsyncEnumerable<StreamingChatCompletionUpdate> CallbackAsync(
Assert.Equal("""["hello", "world"]""", activity.GetTagItem("gen_ai.request.stop_sequences"));
Assert.Equal("value1", activity.GetTagItem("gen_ai.testservice.request.service_tier"));
Assert.Equal("value2", activity.GetTagItem("gen_ai.testservice.request.something_else"));
Assert.Equal(42L, activity.GetTagItem("gen_ai.testservice.request.seed"));

Assert.Equal("id123", activity.GetTagItem("gen_ai.response.id"));
Assert.Equal("""["stop"]""", activity.GetTagItem("gen_ai.response.finish_reasons"));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Testing;
using OpenTelemetry.Trace;
using Xunit;

namespace Microsoft.Extensions.AI;

public class OpenTelemetryEmbeddingGeneratorTests
{
[Fact]
public async Task ExpectedInformationLogged_Async()
{
var sourceName = Guid.NewGuid().ToString();
var activities = new List<Activity>();
using var tracerProvider = OpenTelemetry.Sdk.CreateTracerProviderBuilder()
.AddSource(sourceName)
.AddInMemoryExporter(activities)
.Build();

var collector = new FakeLogCollector();
using ILoggerFactory loggerFactory = LoggerFactory.Create(b => b.AddProvider(new FakeLoggerProvider(collector)));

using var innerGenerator = new TestEmbeddingGenerator
{
Metadata = new("testservice", new Uri("http://localhost:12345/something"), "amazingmodel", 384),
GenerateAsyncCallback = async (values, options, cancellationToken) =>
{
await Task.Yield();
return new GeneratedEmbeddings<Embedding<float>>([new Embedding<float>(new float[] { 1, 2, 3 })])
{
Usage = new()
{
InputTokenCount = 10,
TotalTokenCount = 10,
},
AdditionalProperties = new()
{
["system_fingerprint"] = "abcdefgh",
["AndSomethingElse"] = "value2",
}
};
},
};

using var generator = innerGenerator
.AsBuilder()
.UseOpenTelemetry(loggerFactory, sourceName)
.Build();

var options = new EmbeddingGenerationOptions
{
ModelId = "replacementmodel",
AdditionalProperties = new()
{
["service_tier"] = "value1",
["SomethingElse"] = "value2",
},
};

await generator.GenerateEmbeddingVectorAsync("hello", options);

var activity = Assert.Single(activities);

Assert.NotNull(activity.Id);
Assert.NotEmpty(activity.Id);

Assert.Equal("http://localhost:12345/something", activity.GetTagItem("server.address"));
Assert.Equal(12345, (int)activity.GetTagItem("server.port")!);

Assert.Equal("embeddings replacementmodel", activity.DisplayName);
Assert.Equal("testservice", activity.GetTagItem("gen_ai.system"));

Assert.Equal("replacementmodel", activity.GetTagItem("gen_ai.request.model"));
Assert.Equal("value1", activity.GetTagItem("gen_ai.testservice.request.service_tier"));
Assert.Equal("value2", activity.GetTagItem("gen_ai.testservice.request.something_else"));

Assert.Equal(10, activity.GetTagItem("gen_ai.response.input_tokens"));
Assert.Equal("abcdefgh", activity.GetTagItem("gen_ai.testservice.response.system_fingerprint"));
Assert.Equal("value2", activity.GetTagItem("gen_ai.testservice.response.and_something_else"));

Assert.True(activity.Duration.TotalMilliseconds > 0);
}
}

0 comments on commit 4f3ab61

Please sign in to comment.