chore: import upstream snapshot with attribution
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:21:23 +08:00
commit b957a53def
5423 changed files with 863745 additions and 0 deletions
@@ -0,0 +1,168 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Extensions.VectorData;
using Xunit;
namespace AzureAISearch.ConformanceTests.Support;
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
public class AzureAISearchAllTypes
{
[VectorStoreKey]
public string Id { get; set; }
[VectorStoreData]
public bool BoolProperty { get; set; }
[VectorStoreData]
public bool? NullableBoolProperty { get; set; }
[VectorStoreData]
public string StringProperty { get; set; }
[VectorStoreData]
public string? NullableStringProperty { get; set; }
[VectorStoreData]
public int IntProperty { get; set; }
[VectorStoreData]
public int? NullableIntProperty { get; set; }
[VectorStoreData]
public long LongProperty { get; set; }
[VectorStoreData]
public long? NullableLongProperty { get; set; }
[VectorStoreData]
public float FloatProperty { get; set; }
[VectorStoreData]
public float? NullableFloatProperty { get; set; }
[VectorStoreData]
public double DoubleProperty { get; set; }
[VectorStoreData]
public double? NullableDoubleProperty { get; set; }
[VectorStoreData]
public DateTimeOffset DateTimeOffsetProperty { get; set; }
[VectorStoreData]
public DateTimeOffset? NullableDateTimeOffsetProperty { get; set; }
[VectorStoreData]
public string[] StringArray { get; set; }
[VectorStoreData]
public List<string> StringList { get; set; }
[VectorStoreData]
public bool[] BoolArray { get; set; }
[VectorStoreData]
public List<bool> BoolList { get; set; }
[VectorStoreData]
public int[] IntArray { get; set; }
[VectorStoreData]
public List<int> IntList { get; set; }
[VectorStoreData]
public long[] LongArray { get; set; }
[VectorStoreData]
public List<long> LongList { get; set; }
[VectorStoreData]
public float[] FloatArray { get; set; }
[VectorStoreData]
public List<float> FloatList { get; set; }
[VectorStoreData]
public double[] DoubleArray { get; set; }
[VectorStoreData]
public List<double> DoubleList { get; set; }
[VectorStoreData]
public DateTimeOffset[] DateTimeOffsetArray { get; set; }
[VectorStoreData]
public List<DateTimeOffset> DateTimeOffsetList { get; set; }
[VectorStoreVector(Dimensions: 8, DistanceFunction = DistanceFunction.DotProductSimilarity)]
public ReadOnlyMemory<float>? Embedding { get; set; }
internal void AssertEqual(AzureAISearchAllTypes other)
{
Assert.Equal(this.Id, other.Id);
Assert.Equal(this.BoolProperty, other.BoolProperty);
Assert.Equal(this.NullableBoolProperty, other.NullableBoolProperty);
Assert.Equal(this.StringProperty, other.StringProperty);
Assert.Equal(this.NullableStringProperty, other.NullableStringProperty);
Assert.Equal(this.IntProperty, other.IntProperty);
Assert.Equal(this.NullableIntProperty, other.NullableIntProperty);
Assert.Equal(this.LongProperty, other.LongProperty);
Assert.Equal(this.NullableLongProperty, other.NullableLongProperty);
Assert.Equal(this.FloatProperty, other.FloatProperty);
Assert.Equal(this.NullableFloatProperty, other.NullableFloatProperty);
Assert.Equal(this.DoubleProperty, other.DoubleProperty);
Assert.Equal(this.NullableDoubleProperty, other.NullableDoubleProperty);
AssertEqual(this.DateTimeOffsetProperty, other.DateTimeOffsetProperty);
Assert.Equal(this.NullableDateTimeOffsetProperty.HasValue, other.NullableDateTimeOffsetProperty.HasValue);
if (this.NullableDateTimeOffsetProperty.HasValue && other.NullableDateTimeOffsetProperty.HasValue)
{
AssertEqual(this.NullableDateTimeOffsetProperty.Value, other.NullableDateTimeOffsetProperty.Value);
}
Assert.Equal(this.StringArray, other.StringArray);
Assert.Equal(this.StringList, other.StringList);
Assert.Equal(this.BoolArray, other.BoolArray);
Assert.Equal(this.BoolList, other.BoolList);
Assert.Equal(this.IntArray, other.IntArray);
Assert.Equal(this.IntList, other.IntList);
Assert.Equal(this.LongArray, other.LongArray);
Assert.Equal(this.LongList, other.LongList);
Assert.Equal(this.FloatArray, other.FloatArray);
Assert.Equal(this.FloatList, other.FloatList);
Assert.Equal(this.DoubleArray, other.DoubleArray);
Assert.Equal(this.DoubleList, other.DoubleList);
Assert.Equal(this.DateTimeOffsetArray.Length, other.DateTimeOffsetArray.Length);
for (int i = 0; i < this.DateTimeOffsetArray.Length; i++)
{
AssertEqual(this.DateTimeOffsetArray[i], other.DateTimeOffsetArray[i]);
}
Assert.Equal(this.DateTimeOffsetList.Count, other.DateTimeOffsetList.Count);
for (int i = 0; i < this.DateTimeOffsetList.Count; i++)
{
AssertEqual(this.DateTimeOffsetList[i], other.DateTimeOffsetList[i]);
}
Assert.Equal(this.Embedding!.Value.ToArray(), other.Embedding!.Value.ToArray());
static void AssertEqual(DateTimeOffset expected, DateTimeOffset actual)
{
Assert.Equal(expected, actual, TimeSpan.FromSeconds(0.01));
}
}
internal static VectorStoreCollectionDefinition GetRecordDefinition()
=> new()
{
Properties =
[
new VectorStoreKeyProperty(nameof(AzureAISearchAllTypes.Id), typeof(string)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.BoolProperty), typeof(bool)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.NullableBoolProperty), typeof(bool?)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.StringProperty), typeof(string)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.NullableStringProperty), typeof(string)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.IntProperty), typeof(int)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.NullableIntProperty), typeof(int?)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.LongProperty), typeof(long)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.NullableLongProperty), typeof(long?)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.FloatProperty), typeof(float)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.NullableFloatProperty), typeof(float?)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.DoubleProperty), typeof(double)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.NullableDoubleProperty), typeof(double?)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.DateTimeOffsetProperty), typeof(DateTimeOffset)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.NullableDateTimeOffsetProperty), typeof(DateTimeOffset?)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.StringArray), typeof(string[])),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.StringList), typeof(List<string>)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.BoolArray), typeof(bool[])),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.BoolList), typeof(List<bool>)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.IntArray), typeof(int[])),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.IntList), typeof(List<int>)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.LongArray), typeof(long[])),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.LongList), typeof(List<long>)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.FloatArray), typeof(float[])),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.FloatList), typeof(List<float>)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.DoubleArray), typeof(double[])),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.DoubleList), typeof(List<double>)),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.DateTimeOffsetArray), typeof(DateTimeOffset[])),
new VectorStoreDataProperty(nameof(AzureAISearchAllTypes.DateTimeOffsetList), typeof(List<DateTimeOffset>)),
new VectorStoreVectorProperty(nameof(AzureAISearchAllTypes.Embedding), typeof(ReadOnlyMemory<float>?), 8) { DistanceFunction = Microsoft.Extensions.VectorData.DistanceFunction.DotProductSimilarity }
]
};
}
@@ -0,0 +1,10 @@
// Copyright (c) Microsoft. All rights reserved.
using VectorData.ConformanceTests.Support;
namespace AzureAISearch.ConformanceTests.Support;
public class AzureAISearchFixture : VectorStoreFixture
{
public override TestStore TestStore => AzureAISearchTestStore.Instance;
}
@@ -0,0 +1,33 @@
// Copyright (c) Microsoft. All rights reserved.
using System.Text.RegularExpressions;
using Microsoft.Extensions.Configuration;
namespace AzureAISearch.ConformanceTests.Support;
#pragma warning disable CA1810 // Initialize all static fields when those fields are declared
internal static class AzureAISearchTestEnvironment
{
#pragma warning disable CA1308 // Normalize strings to uppercase
public static readonly string TestIndexPostfix = '-' + new Regex("[^a-zA-Z0-9]").Replace(Environment.MachineName.ToLowerInvariant(), "");
#pragma warning restore CA1308 // Normalize strings to uppercase
public static readonly string? ServiceUrl, ApiKey;
public static bool IsConnectionInfoDefined => ServiceUrl is not null;
static AzureAISearchTestEnvironment()
{
var configuration = new ConfigurationBuilder()
.AddJsonFile(path: "testsettings.json", optional: true)
.AddJsonFile(path: "testsettings.development.json", optional: true)
.AddEnvironmentVariables()
.AddUserSecrets<AzureAISearchUrlRequiredAttribute>()
.Build();
var azureAISearchSection = configuration.GetSection("AzureAISearch");
ServiceUrl = azureAISearchSection?["ServiceUrl"];
ApiKey = azureAISearchSection?["ApiKey"];
}
}
@@ -0,0 +1,68 @@
// Copyright (c) Microsoft. All rights reserved.
using System.Linq.Expressions;
using Azure;
using Azure.Identity;
using Azure.Search.Documents.Indexes;
using Humanizer;
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Connectors.AzureAISearch;
using VectorData.ConformanceTests.Support;
namespace AzureAISearch.ConformanceTests.Support;
internal sealed class AzureAISearchTestStore : TestStore
{
public static AzureAISearchTestStore Instance { get; } = new();
private SearchIndexClient? _client;
public SearchIndexClient Client
=> this._client ?? throw new InvalidOperationException("Call InitializeAsync() first");
public AzureAISearchVectorStore GetVectorStore(AzureAISearchVectorStoreOptions options)
=> new(this.Client, options);
private AzureAISearchTestStore()
{
}
protected override Task StartAsync()
{
(string? serviceUrl, string? apiKey) = (AzureAISearchTestEnvironment.ServiceUrl, AzureAISearchTestEnvironment.ApiKey);
if (string.IsNullOrWhiteSpace(serviceUrl))
{
throw new InvalidOperationException("Service URL is not configured, set AzureAISearch:ServiceUrl (and AzureAISearch:ApiKey if you want)");
}
this._client = string.IsNullOrWhiteSpace(apiKey)
? new SearchIndexClient(new Uri(serviceUrl), new DefaultAzureCredential())
: new SearchIndexClient(new Uri(serviceUrl), new AzureKeyCredential(apiKey));
this.DefaultVectorStore = new AzureAISearchVectorStore(this._client);
return Task.CompletedTask;
}
// Azure AI search only supports lowercase letters, digits or dashes.
// Also, add a suffix containing machine name to allow multiple developers to work against the same cloud instance.
public override string AdjustCollectionName(string baseName)
=> baseName.Kebaberize() + AzureAISearchTestEnvironment.TestIndexPostfix;
public override async Task WaitForDataAsync<TKey, TRecord>(
VectorStoreCollection<TKey, TRecord> collection,
int recordCount,
Expression<Func<TRecord, bool>>? filter = null,
Expression<Func<TRecord, object?>>? vectorProperty = null,
int? vectorSize = null,
object? dummyVector = null)
{
await base.WaitForDataAsync(collection, recordCount, filter, vectorProperty, vectorSize, dummyVector);
// There seems to be some asynchronicity/race condition specific to Azure AI Search which isn't taken care
// of by the generic retry loop in the base implementation.
// TODO: Investigate this and remove
await Task.Delay(TimeSpan.FromMilliseconds(1000));
}
}
@@ -0,0 +1,19 @@
// Copyright (c) Microsoft. All rights reserved.
using VectorData.ConformanceTests.Xunit;
namespace AzureAISearch.ConformanceTests.Support;
/// <summary>
/// Checks whether the sqlite_vec extension is properly installed, and skips the test(s) otherwise.
/// </summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)]
public sealed class AzureAISearchUrlRequiredAttribute : Attribute, ITestCondition
{
public ValueTask<bool> IsMetAsync() => new(AzureAISearchTestEnvironment.IsConnectionInfoDefined);
public string Skip { get; set; } = "Service URL is not configured, set AzureAISearch:ServiceUrl (and AzureAISearch:ApiKey if you don't use managed identity).";
public string SkipReason
=> this.Skip;
}