Skip to content

Tests | Refactor NativeVectorFloat32Tests for future Half support#4347

Open
edwardneal wants to merge 29 commits into
dotnet:mainfrom
edwardneal:tests/generic-vector-testbase
Open

Tests | Refactor NativeVectorFloat32Tests for future Half support#4347
edwardneal wants to merge 29 commits into
dotnet:mainfrom
edwardneal:tests/generic-vector-testbase

Conversation

@edwardneal

Copy link
Copy Markdown
Contributor

Description

This is somewhat inspired by #4234. We don't yet have support for SqlVector<Half> and other types, but this should hopefully make the test logic trivial to add.

I'd recommend moving commit by commit - the introduction of a base class has resulted in the PR looking much larger than it truly is.

The overall design is now more generic. We have:

  • NativeVectorTestDataBase<TElement>, which contains test data for SqlVector<TElement>
  • NativeVectorTestsBase<TElement, TTestData>, which contains the test logic and links it to the test data
  • VectorFloat32TestData: derived from NativeVectorTestDataBase which contains float-based sample data
  • NativeVectorFloat32Tests: the same tests and the same logic as in main, but derived from NativeVectorTestsBase

Adding future support for Half should mean simply introducing VectorFloat16TestData and NativeVectorFloat16Tests classes:

public sealed class VectorFloat16TestData : NativeVectorTestDataBase<Half>
{
    public override Half[] SampleScalarData => [1, 2, 3, 4, 5, 6];

    public override Half[,] SampleDataSet => /* */;

    public override int IncorrectScalarDataParameterSize => 9999;

    public override bool IsSupported => DataTestUtility.IsSqlVectorFloat16Supported;

    public override string SqlServerTypeName => "float16";
}

public sealed class NativeVectorFloat16Tests : NativeVectorTestsBase<Half, VectorFloat16TestData>
{
}

I've also made a handful of hygiene improvements, but none are particularly controversial:

  • Use of RAII primitives
  • Text corrections in comments
  • Assertion cleanups (catching an exception and running Assert.Fail, performing Assert.True(!verifyReader.IsDBNull(0), ...), etc.)
  • Nullability annotations

Issues

In lieu of any more specific issue for Half/float16 support for SqlVector, this contributes to #3444.

Testing

All automated tests continue to pass.

@edwardneal
edwardneal requested a review from a team as a code owner June 7, 2026 16:15
@github-project-automation github-project-automation Bot moved this to To triage in SqlClient Board Jun 7, 2026
@apoorvdeshmukh apoorvdeshmukh self-assigned this Jun 8, 2026
@apoorvdeshmukh
apoorvdeshmukh requested a review from Copilot June 26, 2026 09:43
@apoorvdeshmukh

Copy link
Copy Markdown
Contributor

/azp run

@apoorvdeshmukh apoorvdeshmukh moved this from To triage to In review in SqlClient Board Jun 26, 2026
@apoorvdeshmukh apoorvdeshmukh added this to the 7.1.0-preview2 milestone Jun 26, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 3 pipeline(s).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the native SqlVector<T> manual test suite to use a generic test-data + shared test-logic base, so adding future element types (e.g., Half) becomes mostly a matter of adding a new *TestData + thin derived test class.

Changes:

  • Adds NativeVectorTestDataBase<TElement> to centralize per-element sample data and parameter-pattern cases.
  • Adds NativeVectorTestsBase<TElement, TTestData> to host the shared insertion/read, stored-proc, bulk-copy, and prepare/execute test logic using RAII DB objects.
  • Refactors the float32 suite into VectorFloat32TestData + NativeVectorFloat32Tests : NativeVectorTestsBase<...>.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/VectorTest/NativeVectorTestsBase.cs New generic base classes for vector manual tests + shared test logic and RAII-managed DB objects.
src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/VectorTest/NativeVectorFloat32Tests.cs Refactors float32 tests into new test-data class + thin derived test class using the new base.

Comment on lines +108 to +120
int vectorDimensions = TestDataInstance.ValidSampleScalarDataLength;
string tableDefinition = $@"(Id INT PRIMARY KEY IDENTITY, {VectorColumnName} vector({vectorDimensions}, {TestDataInstance.SqlServerTypeName}) NULL)";

_connectionString = DataTestUtility.TCPConnectionString;
_managementConnection = new SqlConnection(_connectionString);
_vectorTable = new Table(_managementConnection, "VectorTestTable", tableDefinition);
_bulkCopySourceTable = new Table(_managementConnection, "VectorBulkCopyTestTable", tableDefinition);
_vectorProcedure = new StoredProcedure(_managementConnection,
prefix: "VectorsAsVarcharSp",
definition: $@"
{VectorParameterName} vector({vectorDimensions}, {TestDataInstance.SqlServerTypeName}), -- Input: Serialized TElement[] as JSON string
{VectorOutputParameterName} vector({vectorDimensions}, {TestDataInstance.SqlServerTypeName}) OUTPUT -- Output: Echoed back from latest inserted row
AS

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default vector base type is float32, so vector(N, float32) is a more explicit name for vector(N). We explicitly specify the base type rather than implementing a special case.

Comment on lines +37 to +40
public override bool IsSupported => DataTestUtility.IsSqlVectorSupported;

// Verify GetFieldValue<SqlVector<float>> returns the correct typed value
SqlVector<float> typedValue = reader.GetFieldValue<SqlVector<float>>(0);
Assert.IsType<SqlVector<float>>(typedValue);
Assert.Equal(VectorFloat32TestData.testData, typedValue.Memory.ToArray());
}
public override string SqlServerTypeName => "float32";
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default vector base type is float32, so vector(N, float32) is a more explicit name for vector(N). We explicitly specify the base type rather than implementing a special case.

Comment on lines +463 to +468
case 1:
bulkCopy.WriteToServer(reader);
break;
case 2:
bulkCopy.WriteToServer(table);
break;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 07c2ae1.

@paulmedynski paulmedynski self-assigned this Jun 30, 2026
@paulmedynski

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).

Assert.Equal(expectedData, dbData);
rowcnt++;
}
Assert.Equal(10, rowcnt);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice refactor — this generalizes cleanly. One small thing: the row count here is hardcoded to 10, while the loop above is data-driven off SampleDataSet. Since the point of this base class is to let future element types (e.g. a SqlVector<Half> suite) supply their own SampleDataSet with a potentially different row count, this assertion couples the base back to float[10, N].

Suggest deriving it from the data so it stays element-agnostic:

Suggested change
Assert.Equal(10, rowcnt);
Assert.Equal(sampleDataSet.GetLength(0), rowcnt);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, thanks - fixed in c2d227d.

apoorvdeshmukh
apoorvdeshmukh previously approved these changes Jul 23, 2026

@apoorvdeshmukh apoorvdeshmukh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one minor suggestion. Looks good to me otherwise.

@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 63.56%. Comparing base (5ac26c9) to head (07c2ae1).
⚠️ Report is 67 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4347      +/-   ##
==========================================
- Coverage   66.50%   63.56%   -2.95%     
==========================================
  Files         285      280       -5     
  Lines       43311    66783   +23472     
==========================================
+ Hits        28806    42450   +13644     
- Misses      14505    24333    +9828     
Flag Coverage Δ
CI-SqlClient ?
PR-SqlClient-Project 63.56% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

4 participants