Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.Net: Refactor shared integration tests to allow attribute based disable. #10236

Merged
merged 3 commits into from
Jan 21, 2025
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
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.

using System.Threading.Tasks;
using Microsoft.SemanticKernel.Connectors.AzureAISearch;
using SemanticKernel.IntegrationTests.Connectors.Memory.Xunit;
using Xunit;

namespace SemanticKernel.IntegrationTests.Connectors.Memory.AzureAISearch;
Expand All @@ -11,15 +11,8 @@ namespace SemanticKernel.IntegrationTests.Connectors.Memory.AzureAISearch;
/// Tests work with an Azure AI Search Instance.
/// </summary>
[Collection("AzureAISearchVectorStoreCollection")]
[DisableVectorStoreTests(Skip = "Requires Azure AI Search Service instance up and running")]
public class AzureAISearchVectorStoreTests(AzureAISearchVectorStoreFixture fixture)
: BaseVectorStoreTests<string, AzureAISearchHotel>(new AzureAISearchVectorStore(fixture.SearchIndexClient))
{
// If null, all tests will be enabled
private const string SkipReason = "Requires Azure AI Search Service instance up and running";

[Fact(Skip = SkipReason)]
public override async Task ItCanGetAListOfExistingCollectionNamesAsync()
{
await base.ItCanGetAListOfExistingCollectionNamesAsync();
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
// Copyright (c) Microsoft. All rights reserved.

using System.Threading.Tasks;
using Microsoft.SemanticKernel.Connectors.AzureCosmosDBMongoDB;
using SemanticKernel.IntegrationTests.Connectors.Memory;
using SemanticKernel.IntegrationTests.Connectors.Memory.Xunit;
using Xunit;

namespace SemanticKernel.IntegrationTests.Connectors.AzureCosmosDBMongoDB;

[Collection("AzureCosmosDBMongoDBVectorStoreCollection")]
[DisableVectorStoreTests(Skip = "Azure CosmosDB MongoDB cluster is required")]
public class AzureCosmosDBMongoDBVectorStoreTests(AzureCosmosDBMongoDBVectorStoreFixture fixture)
: BaseVectorStoreTests<string, AzureCosmosDBMongoDBHotel>(new AzureCosmosDBMongoDBVectorStore(fixture.MongoDatabase))
{
private const string? SkipReason = "Azure CosmosDB MongoDB cluster is required";

[Fact(Skip = SkipReason)]
public override async Task ItCanGetAListOfExistingCollectionNamesAsync()
{
await base.ItCanGetAListOfExistingCollectionNamesAsync();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.

using System.Threading.Tasks;
using Microsoft.SemanticKernel.Connectors.AzureCosmosDBNoSQL;
using SemanticKernel.IntegrationTests.Connectors.Memory.Xunit;
using Xunit;

namespace SemanticKernel.IntegrationTests.Connectors.Memory.AzureCosmosDBNoSQL;
Expand All @@ -10,14 +10,8 @@ namespace SemanticKernel.IntegrationTests.Connectors.Memory.AzureCosmosDBNoSQL;
/// Integration tests for <see cref="AzureCosmosDBNoSQLVectorStore"/>.
/// </summary>
[Collection("AzureCosmosDBNoSQLVectorStoreCollection")]
[DisableVectorStoreTests(Skip = "Azure CosmosDB NoSQL cluster is required")]
public sealed class AzureCosmosDBNoSQLVectorStoreTests(AzureCosmosDBNoSQLVectorStoreFixture fixture)
: BaseVectorStoreTests<string, AzureCosmosDBNoSQLHotel>(new AzureCosmosDBNoSQLVectorStore(fixture.Database!))
{
private const string? SkipReason = "Azure CosmosDB NoSQL cluster is required";

[Fact(Skip = SkipReason)]
public override async Task ItCanGetAListOfExistingCollectionNamesAsync()
{
await base.ItCanGetAListOfExistingCollectionNamesAsync();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.VectorData;
using SemanticKernel.IntegrationTests.Connectors.Memory.Xunit;
using Xunit;

namespace SemanticKernel.IntegrationTests.Connectors.Memory;
Expand All @@ -29,7 +30,7 @@ public abstract class BaseVectorStoreRecordCollectionTests<TKey>

protected virtual int DelayAfterUploadInMilliseconds { get; } = 0;

[Theory]
[VectorStoreTheory]
[InlineData(DistanceFunction.CosineDistance, 0, 2, 1, new int[] { 0, 2, 1 })]
[InlineData(DistanceFunction.CosineSimilarity, 1, -1, 0, new int[] { 0, 2, 1 })]
[InlineData(DistanceFunction.DotProductSimilarity, 1, -1, 0, new int[] { 0, 2, 1 })]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.VectorData;
using SemanticKernel.IntegrationTests.Connectors.Memory.Xunit;
using Xunit;

namespace SemanticKernel.IntegrationTests.Connectors.Memory;
Expand All @@ -14,7 +15,7 @@ namespace SemanticKernel.IntegrationTests.Connectors.Memory;
public abstract class BaseVectorStoreTests<TKey, TRecord>(IVectorStore vectorStore)
where TKey : notnull
{
[Fact]
[VectorStoreFact]
public virtual async Task ItCanGetAListOfExistingCollectionNamesAsync()
{
// Arrange
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
// Copyright (c) Microsoft. All rights reserved.

using System.Threading.Tasks;
using Microsoft.SemanticKernel.Connectors.MongoDB;
using SemanticKernel.IntegrationTests.Connectors.Memory;
using SemanticKernel.IntegrationTests.Connectors.Memory.Xunit;
using Xunit;

namespace SemanticKernel.IntegrationTests.Connectors.MongoDB;

[Collection("MongoDBVectorStoreCollection")]
[DisableVectorStoreTests(Skip = "The tests are for manual verification.")]
public class MongoDBVectorStoreTests(MongoDBVectorStoreFixture fixture)
: BaseVectorStoreTests<string, MongoDBHotel>(new MongoDBVectorStore(fixture.MongoDatabase))
{
// If null, all tests will be enabled
private const string? SkipReason = "The tests are for manual verification.";

[Fact(Skip = SkipReason)]
public override async Task ItCanGetAListOfExistingCollectionNamesAsync()
{
await base.ItCanGetAListOfExistingCollectionNamesAsync();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,13 @@

namespace SemanticKernel.IntegrationTests.Connectors.Memory.Pinecone;

// Disable unused class warning, as this class is marked internal to disable the tests in the base class.
#pragma warning disable CA1812
#pragma warning disable CA1852

/// <summary>
/// Inherits common integration tests that should pass for any <see cref="IVectorStoreRecordCollection{TKey, TRecord}"/>.
/// </summary>
/// <param name="fixture">Pinecone setup and teardown.</param>
[Collection("PineconeVectorStoreTests")]
[PineconeApiKeySetCondition]
internal class CommonPineconeVectorStoreRecordCollectionTests(PineconeVectorStoreFixture fixture) : BaseVectorStoreRecordCollectionTests<string>, IClassFixture<PineconeVectorStoreFixture>
public class CommonPineconeVectorStoreRecordCollectionTests(PineconeVectorStoreFixture fixture) : BaseVectorStoreRecordCollectionTests<string>, IClassFixture<PineconeVectorStoreFixture>
{
protected override string Key1 => "1";
protected override string Key2 => "2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Microsoft.SemanticKernel.Connectors.Pinecone;
using Pinecone;
using SemanticKernel.IntegrationTests.Connectors.Memory.Pinecone.Xunit;
using SemanticKernel.IntegrationTests.Connectors.Memory.Xunit;
using Xunit;

namespace SemanticKernel.IntegrationTests.Connectors.Memory.Pinecone;
Expand All @@ -20,21 +21,21 @@ public class PineconeVectorStoreRecordCollectionTests(PineconeVectorStoreFixture
{
private PineconeVectorStoreFixture Fixture { get; } = fixture;

[PineconeFact]
[VectorStoreFact]
public async Task TryCreateExistingIndexIsNoopAsync()
{
await this.Fixture.HotelRecordCollection.CreateCollectionIfNotExistsAsync();
}

[PineconeFact]
[VectorStoreFact]
public async Task CollectionExistsReturnsTrueForExistingCollectionAsync()
{
var result = await this.Fixture.HotelRecordCollection.CollectionExistsAsync();

Assert.True(result);
}

[PineconeTheory]
[VectorStoreTheory]
[InlineData(true)]
[InlineData(false)]
public async Task BasicGetAsync(bool includeVectors)
Expand Down Expand Up @@ -63,7 +64,7 @@ public async Task BasicGetAsync(bool includeVectors)
}
}

[PineconeTheory]
[VectorStoreTheory]
[InlineData(true)]
[InlineData(false)]
public async Task BatchGetAsync(bool collectionFromVectorStore)
Expand Down Expand Up @@ -107,7 +108,7 @@ public async Task BatchGetAsync(bool collectionFromVectorStore)
Assert.Contains("gym", bestEastern.Tags);
}

[PineconeTheory]
[VectorStoreTheory]
[InlineData(true)]
[InlineData(false)]
public async Task AllTypesBatchGetAsync(bool includeVectors)
Expand Down Expand Up @@ -160,7 +161,7 @@ public async Task AllTypesBatchGetAsync(bool includeVectors)
}
}

[PineconeFact]
[VectorStoreFact]
public async Task BatchGetIncludingNonExistingRecordAsync()
{
var hotels = await this.Fixture.HotelRecordCollection.GetBatchAsync(["vacation-inn", "non-existing"]).ToListAsync();
Expand All @@ -178,14 +179,14 @@ public async Task BatchGetIncludingNonExistingRecordAsync()
Assert.Contains("gym", vacationInn.Tags);
}

[PineconeFact]
[VectorStoreFact]
public async Task GetNonExistingRecordAsync()
{
var result = await this.Fixture.HotelRecordCollection.GetAsync("non-existing");
Assert.Null(result);
}

[PineconeTheory]
[VectorStoreTheory]
[InlineData(true)]
[InlineData(false)]
public async Task GetFromCustomNamespaceAsync(bool includeVectors)
Expand All @@ -205,29 +206,29 @@ public async Task GetFromCustomNamespaceAsync(bool includeVectors)
}
}

[PineconeFact]
[VectorStoreFact]
public async Task TryGetVectorLocatedInDefaultNamespaceButLookInCustomNamespaceAsync()
{
var badFiveSeasons = await this.Fixture.HotelRecordCollectionWithCustomNamespace.GetAsync("five-seasons");

Assert.Null(badFiveSeasons);
}

[PineconeFact]
[VectorStoreFact]
public async Task TryGetVectorLocatedInCustomNamespaceButLookInDefaultNamespaceAsync()
{
var badCustomHotel = await this.Fixture.HotelRecordCollection.GetAsync("custom-hotel");

Assert.Null(badCustomHotel);
}

[PineconeFact]
[VectorStoreFact]
public async Task DeleteNonExistingRecordAsync()
{
await this.Fixture.HotelRecordCollection.DeleteAsync("non-existing");
}

[PineconeFact]
[VectorStoreFact]
public async Task TryDeleteExistingVectorLocatedInDefaultNamespaceButUseCustomNamespaceDoesNotDoAnythingAsync()
{
await this.Fixture.HotelRecordCollectionWithCustomNamespace.DeleteAsync("five-seasons");
Expand All @@ -237,7 +238,7 @@ public async Task TryDeleteExistingVectorLocatedInDefaultNamespaceButUseCustomNa
Assert.Equal("five-seasons", stillThere.HotelId);
}

[PineconeFact]
[VectorStoreFact]
public async Task TryDeleteExistingVectorLocatedInCustomNamespaceButUseDefaultNamespaceDoesNotDoAnythingAsync()
{
await this.Fixture.HotelRecordCollection.DeleteAsync("custom-hotel");
Expand All @@ -247,7 +248,7 @@ public async Task TryDeleteExistingVectorLocatedInCustomNamespaceButUseDefaultNa
Assert.Equal("custom-hotel", stillThere.HotelId);
}

[PineconeTheory]
[VectorStoreTheory]
[InlineData(true)]
[InlineData(false)]
public async Task InsertGetModifyDeleteVectorAsync(bool collectionFromVectorStore)
Expand Down Expand Up @@ -311,7 +312,7 @@ public async Task InsertGetModifyDeleteVectorAsync(bool collectionFromVectorStor
await this.Fixture.VerifyVectorCountModifiedAsync(vectorCountBefore, delta: -1);
}

[PineconeTheory]
[VectorStoreTheory]
[InlineData(true, true)]
[InlineData(true, false)]
[InlineData(false, true)]
Expand Down Expand Up @@ -340,7 +341,7 @@ public async Task VectorizedSearchAsync(bool collectionFromVectorStore, bool inc
Assert.Equal(includeVectors, searchResultRecord.DescriptionEmbedding.Length > 0);
}

[PineconeTheory]
[VectorStoreTheory]
[InlineData(true)]
[InlineData(false)]
public async Task VectorizedSearchWithTopSkipAsync(bool collectionFromVectorStore)
Expand All @@ -359,7 +360,7 @@ public async Task VectorizedSearchWithTopSkipAsync(bool collectionFromVectorStor
Assert.Equal("Best Eastern Hotel", searchResultRecord.HotelName);
}

[PineconeTheory]
[VectorStoreTheory]
[InlineData(true)]
[InlineData(false)]
public async Task VectorizedSearchWithFilterAsync(bool collectionFromVectorStore)
Expand All @@ -379,7 +380,7 @@ public async Task VectorizedSearchWithFilterAsync(bool collectionFromVectorStore
Assert.Equal("Best Eastern Hotel", searchResultRecord.HotelName);
}

[PineconeFact]
[VectorStoreFact]
public async Task ItCanUpsertAndRetrieveUsingTheGenericMapperAsync()
{
var merryYacht = new VectorStoreGenericDataModel<string>("merry-yacht")
Expand Down Expand Up @@ -428,7 +429,7 @@ public async Task ItCanUpsertAndRetrieveUsingTheGenericMapperAsync()
await this.Fixture.VerifyVectorCountModifiedAsync(vectorCountBefore, delta: -1);
}

[PineconeFact]
[VectorStoreFact]
public async Task UseCollectionExistsOnNonExistingStoreReturnsFalseAsync()
{
var incorrectRecordStore = new PineconeVectorStoreRecordCollection<PineconeHotel>(
Expand All @@ -440,7 +441,7 @@ public async Task UseCollectionExistsOnNonExistingStoreReturnsFalseAsync()
Assert.False(result);
}

[PineconeFact]
[VectorStoreFact]
public async Task UseNonExistingIndexThrowsAsync()
{
var incorrectRecordStore = new PineconeVectorStoreRecordCollection<PineconeHotel>(
Expand All @@ -453,7 +454,7 @@ public async Task UseNonExistingIndexThrowsAsync()
Assert.Equal(HttpStatusCode.NotFound, statusCode);
}

[PineconeFact]
[VectorStoreFact]
public async Task UseRecordStoreWithCustomMapperAsync()
{
var recordStore = new PineconeVectorStoreRecordCollection<PineconeHotel>(
Expand Down Expand Up @@ -518,7 +519,7 @@ public PineconeHotel MapFromStorageToDataModel(Vector storageModel, StorageToDat

#region Negative

[PineconeFact]
[VectorStoreFact]
public void UseRecordWithNoEmbeddingThrows()
{
var exception = Assert.Throws<ArgumentException>(
Expand All @@ -542,7 +543,7 @@ private sealed record PineconeRecordNoEmbedding
}
#pragma warning restore CA1812

[PineconeFact]
[VectorStoreFact]
public void UseRecordWithMultipleEmbeddingsThrows()
{
var exception = Assert.Throws<ArgumentException>(
Expand All @@ -569,7 +570,7 @@ private sealed record PineconeRecordMultipleEmbeddings
}
#pragma warning restore CA1812

[PineconeFact]
[VectorStoreFact]
public void UseRecordWithUnsupportedKeyTypeThrows()
{
var message = Assert.Throws<ArgumentException>(
Expand All @@ -596,7 +597,7 @@ private sealed record PineconeRecordUnsupportedKeyType
}
#pragma warning restore CA1812

[PineconeFact]
[VectorStoreFact]
public async Task TryAddingVectorWithUnsupportedValuesAsync()
{
var badAllTypes = new PineconeAllTypes
Expand Down Expand Up @@ -625,7 +626,7 @@ public async Task TryAddingVectorWithUnsupportedValuesAsync()
Assert.Equal(StatusCode.InvalidArgument, inner.StatusCode);
}

[PineconeFact]
[VectorStoreFact]
public async Task TryCreateIndexWithIncorrectDimensionFailsAsync()
{
var recordCollection = new PineconeVectorStoreRecordCollection<PineconeRecordWithIncorrectDimension>(
Expand All @@ -651,7 +652,7 @@ private sealed record PineconeRecordWithIncorrectDimension
}
#pragma warning restore CA1812

[PineconeFact]
[VectorStoreFact]
public async Task TryCreateIndexWithUnsSupportedMetricFailsAsync()
{
var recordCollection = new PineconeVectorStoreRecordCollection<PineconeRecordWithUnsupportedMetric>(
Expand Down
Loading
Loading