Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Suppressing errors for Test projects under dotnet folder
[*.cs]
dotnet_diagnostic.CA2007.severity = none # Do not directly await a Task
dotnet_diagnostic.VSTHRD111.severity = none # Use .ConfigureAwait(bool) is hidden by default, set to none to prevent IDE from changing on autosave
dotnet_diagnostic.CS1591.severity = none # Missing XML comment for publicly visible type or member
dotnet_diagnostic.IDE1006.severity = warning # Naming rule violations
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
// Copyright (c) Microsoft. All rights reserved.

using System;
using System.Collections.Generic;
using System.Text.Json;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.AzureOpenAI;

namespace SemanticKernel.Connectors.AzureOpenAI.UnitTests;

/// <summary>
/// Unit tests of AzureOpenAIPromptExecutionSettingsTests
/// </summary>
public class AzureOpenAIPromptExecutionSettingsTests
{
[Fact]
public void ItCreatesOpenAIExecutionSettingsWithCorrectDefaults()
{
// Arrange
// Act
AzureOpenAIPromptExecutionSettings executionSettings = AzureOpenAIPromptExecutionSettings.FromExecutionSettings(null, 128);

// Assert
Assert.NotNull(executionSettings);
Assert.Equal(1, executionSettings.Temperature);
Assert.Equal(1, executionSettings.TopP);
Assert.Equal(0, executionSettings.FrequencyPenalty);
Assert.Equal(0, executionSettings.PresencePenalty);
Assert.Equal(1, executionSettings.ResultsPerPrompt);
Assert.Null(executionSettings.StopSequences);
Assert.Null(executionSettings.TokenSelectionBiases);
Assert.Null(executionSettings.TopLogprobs);
Assert.Null(executionSettings.Logprobs);
Assert.Null(executionSettings.AzureChatExtensionsOptions);
Assert.Equal(128, executionSettings.MaxTokens);
}

[Fact]
public void ItUsesExistingOpenAIExecutionSettings()
{
// Arrange
AzureOpenAIPromptExecutionSettings actualSettings = new()
{
Temperature = 0.7,
TopP = 0.7,
FrequencyPenalty = 0.7,
PresencePenalty = 0.7,
ResultsPerPrompt = 2,
StopSequences = new string[] { "foo", "bar" },
ChatSystemPrompt = "chat system prompt",
MaxTokens = 128,
Logprobs = true,
TopLogprobs = 5,
TokenSelectionBiases = new Dictionary<int, int>() { { 1, 2 }, { 3, 4 } },
};

// Act
AzureOpenAIPromptExecutionSettings executionSettings = AzureOpenAIPromptExecutionSettings.FromExecutionSettings(actualSettings);

// Assert
Assert.NotNull(executionSettings);
Assert.Equal(actualSettings, executionSettings);
}

[Fact]
public void ItCanUseOpenAIExecutionSettings()
{
// Arrange
PromptExecutionSettings actualSettings = new()
{
ExtensionData = new Dictionary<string, object>() {
{ "max_tokens", 1000 },
{ "temperature", 0 }
}
};

// Act
AzureOpenAIPromptExecutionSettings executionSettings = AzureOpenAIPromptExecutionSettings.FromExecutionSettings(actualSettings, null);

// Assert
Assert.NotNull(executionSettings);
Assert.Equal(1000, executionSettings.MaxTokens);
Assert.Equal(0, executionSettings.Temperature);
}

[Fact]
public void ItCreatesOpenAIExecutionSettingsFromExtraPropertiesSnakeCase()
{
// Arrange
PromptExecutionSettings actualSettings = new()
{
ExtensionData = new Dictionary<string, object>()
{
{ "temperature", 0.7 },
{ "top_p", 0.7 },
{ "frequency_penalty", 0.7 },
{ "presence_penalty", 0.7 },
{ "results_per_prompt", 2 },
{ "stop_sequences", new [] { "foo", "bar" } },
{ "chat_system_prompt", "chat system prompt" },
{ "max_tokens", 128 },
{ "token_selection_biases", new Dictionary<int, int>() { { 1, 2 }, { 3, 4 } } },
{ "seed", 123456 },
{ "logprobs", true },
{ "top_logprobs", 5 },
}
};

// Act
AzureOpenAIPromptExecutionSettings executionSettings = AzureOpenAIPromptExecutionSettings.FromExecutionSettings(actualSettings, null);

// Assert
AssertExecutionSettings(executionSettings);
}

[Fact]
public void ItCreatesOpenAIExecutionSettingsFromExtraPropertiesAsStrings()
{
// Arrange
PromptExecutionSettings actualSettings = new()
{
ExtensionData = new Dictionary<string, object>()
{
{ "temperature", "0.7" },
{ "top_p", "0.7" },
{ "frequency_penalty", "0.7" },
{ "presence_penalty", "0.7" },
{ "results_per_prompt", "2" },
{ "stop_sequences", new [] { "foo", "bar" } },
{ "chat_system_prompt", "chat system prompt" },
{ "max_tokens", "128" },
{ "token_selection_biases", new Dictionary<string, string>() { { "1", "2" }, { "3", "4" } } },
{ "seed", 123456 },
{ "logprobs", true },
{ "top_logprobs", 5 }
}
};

// Act
AzureOpenAIPromptExecutionSettings executionSettings = AzureOpenAIPromptExecutionSettings.FromExecutionSettings(actualSettings, null);

// Assert
AssertExecutionSettings(executionSettings);
}

[Fact]
public void ItCreatesOpenAIExecutionSettingsFromJsonSnakeCase()
{
// Arrange
var json = """
{
"temperature": 0.7,
"top_p": 0.7,
"frequency_penalty": 0.7,
"presence_penalty": 0.7,
"results_per_prompt": 2,
"stop_sequences": [ "foo", "bar" ],
"chat_system_prompt": "chat system prompt",
"token_selection_biases": { "1": 2, "3": 4 },
"max_tokens": 128,
"seed": 123456,
"logprobs": true,
"top_logprobs": 5
}
""";
var actualSettings = JsonSerializer.Deserialize<PromptExecutionSettings>(json);

// Act
AzureOpenAIPromptExecutionSettings executionSettings = AzureOpenAIPromptExecutionSettings.FromExecutionSettings(actualSettings);

// Assert
AssertExecutionSettings(executionSettings);
}

[Theory]
[InlineData("", "")]
[InlineData("System prompt", "System prompt")]
public void ItUsesCorrectChatSystemPrompt(string chatSystemPrompt, string expectedChatSystemPrompt)
{
// Arrange & Act
var settings = new AzureOpenAIPromptExecutionSettings { ChatSystemPrompt = chatSystemPrompt };

// Assert
Assert.Equal(expectedChatSystemPrompt, settings.ChatSystemPrompt);
}

[Fact]
public void PromptExecutionSettingsCloneWorksAsExpected()
{
// Arrange
string configPayload = """
{
"max_tokens": 60,
"temperature": 0.5,
"top_p": 0.0,
"presence_penalty": 0.0,
"frequency_penalty": 0.0
}
""";
var executionSettings = JsonSerializer.Deserialize<AzureOpenAIPromptExecutionSettings>(configPayload);

// Act
var clone = executionSettings!.Clone();

// Assert
Assert.NotNull(clone);
Assert.Equal(executionSettings.ModelId, clone.ModelId);
Assert.Equivalent(executionSettings.ExtensionData, clone.ExtensionData);
}

[Fact]
public void PromptExecutionSettingsFreezeWorksAsExpected()
{
// Arrange
string configPayload = """
{
"max_tokens": 60,
"temperature": 0.5,
"top_p": 0.0,
"presence_penalty": 0.0,
"frequency_penalty": 0.0,
"stop_sequences": [ "DONE" ],
"token_selection_biases": { "1": 2, "3": 4 }
}
""";
var executionSettings = JsonSerializer.Deserialize<AzureOpenAIPromptExecutionSettings>(configPayload);

// Act
executionSettings!.Freeze();

// Assert
Assert.True(executionSettings.IsFrozen);
Assert.Throws<InvalidOperationException>(() => executionSettings.ModelId = "gpt-4");
Assert.Throws<InvalidOperationException>(() => executionSettings.ResultsPerPrompt = 2);
Assert.Throws<InvalidOperationException>(() => executionSettings.Temperature = 1);
Assert.Throws<InvalidOperationException>(() => executionSettings.TopP = 1);
Assert.Throws<NotSupportedException>(() => executionSettings.StopSequences?.Add("STOP"));
Assert.Throws<NotSupportedException>(() => executionSettings.TokenSelectionBiases?.Add(5, 6));

executionSettings!.Freeze(); // idempotent
Assert.True(executionSettings.IsFrozen);
}

[Fact]
public void FromExecutionSettingsWithDataDoesNotIncludeEmptyStopSequences()
{
// Arrange
var executionSettings = new AzureOpenAIPromptExecutionSettings { StopSequences = [] };

// Act
#pragma warning disable CS0618 // AzureOpenAIChatCompletionWithData is deprecated in favor of OpenAIPromptExecutionSettings.AzureChatExtensionsOptions
var executionSettingsWithData = AzureOpenAIPromptExecutionSettings.FromExecutionSettingsWithData(executionSettings);
#pragma warning restore CS0618
// Assert
Assert.Null(executionSettingsWithData.StopSequences);
}

private static void AssertExecutionSettings(AzureOpenAIPromptExecutionSettings executionSettings)
{
Assert.NotNull(executionSettings);
Assert.Equal(0.7, executionSettings.Temperature);
Assert.Equal(0.7, executionSettings.TopP);
Assert.Equal(0.7, executionSettings.FrequencyPenalty);
Assert.Equal(0.7, executionSettings.PresencePenalty);
Assert.Equal(2, executionSettings.ResultsPerPrompt);
Assert.Equal(new string[] { "foo", "bar" }, executionSettings.StopSequences);
Assert.Equal("chat system prompt", executionSettings.ChatSystemPrompt);
Assert.Equal(new Dictionary<int, int>() { { 1, 2 }, { 3, 4 } }, executionSettings.TokenSelectionBiases);
Assert.Equal(128, executionSettings.MaxTokens);
Assert.Equal(123456, executionSettings.Seed);
Assert.Equal(true, executionSettings.Logprobs);
Assert.Equal(5, executionSettings.TopLogprobs);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) Microsoft. All rights reserved.

using System.IO;

namespace SemanticKernel.Connectors.AzureOpenAI.UnitTests;

/// <summary>
/// Helper for AzureOpenAI test purposes.
/// </summary>
internal static class AzureOpenAITestHelper
{
/// <summary>
/// Reads test response from file for mocking purposes.
/// </summary>
/// <param name="fileName">Name of the file with test response.</param>
internal static string GetTestResponse(string fileName)
{
return File.ReadAllText($"./TestData/{fileName}");
}
}
Loading