From a76de920e6f7d261ccda9dde3230d06b6676ae87 Mon Sep 17 00:00:00 2001 From: Qingyang Hu <103950869+qingyang-hu@users.noreply.github.com> Date: Fri, 21 Feb 2025 08:54:08 -0500 Subject: [PATCH] GODRIVER-3481 Improve JSON tests for Binary Vector Subtype. (#1942) --- bson/bson_binary_vector_spec_test.go | 116 ++++---------------- testdata/bson-binary-vector/float32.json | 17 ++- testdata/bson-binary-vector/int8.json | 3 +- testdata/bson-binary-vector/packed_bit.json | 22 +--- 4 files changed, 46 insertions(+), 112 deletions(-) diff --git a/bson/bson_binary_vector_spec_test.go b/bson/bson_binary_vector_spec_test.go index b30aac1a83..dcd987b3e5 100644 --- a/bson/bson_binary_vector_spec_test.go +++ b/bson/bson_binary_vector_spec_test.go @@ -9,7 +9,6 @@ package bson import ( "encoding/hex" "encoding/json" - "fmt" "math" "os" "path" @@ -64,36 +63,6 @@ func TestBsonBinaryVectorSpec(t *testing.T) { }) } - t.Run("FLOAT32 with padding", func(t *testing.T) { - t.Parallel() - - t.Run("Unmarshaling", func(t *testing.T) { - val := D{{"vector", Binary{Subtype: TypeBinaryVector, Data: []byte{Float32Vector, 3}}}} - b, err := Marshal(val) - require.NoError(t, err, "marshaling test BSON") - var got struct { - Vector Vector - } - err = Unmarshal(b, &got) - require.ErrorContains(t, err, errNonZeroVectorPadding.Error()) - }) - }) - - t.Run("INT8 with padding", func(t *testing.T) { - t.Parallel() - - t.Run("Unmarshaling", func(t *testing.T) { - val := D{{"vector", Binary{Subtype: TypeBinaryVector, Data: []byte{Int8Vector, 3}}}} - b, err := Marshal(val) - require.NoError(t, err, "marshaling test BSON") - var got struct { - Vector Vector - } - err = Unmarshal(b, &got) - require.ErrorContains(t, err, errNonZeroVectorPadding.Error()) - }) - }) - t.Run("Padding specified with no vector data PACKED_BIT", func(t *testing.T) { t.Parallel() @@ -101,16 +70,6 @@ func TestBsonBinaryVectorSpec(t *testing.T) { _, err := NewPackedBitVector(nil, 1) require.EqualError(t, err, errNonZeroVectorPadding.Error()) }) - t.Run("Unmarshaling", func(t *testing.T) { - val := D{{"vector", Binary{Subtype: TypeBinaryVector, Data: []byte{PackedBitVector, 1}}}} - b, err := Marshal(val) - require.NoError(t, err, "marshaling test BSON") - var got struct { - Vector Vector - } - err = Unmarshal(b, &got) - require.ErrorContains(t, err, errNonZeroVectorPadding.Error()) - }) }) t.Run("Exceeding maximum padding PACKED_BIT", func(t *testing.T) { @@ -120,47 +79,9 @@ func TestBsonBinaryVectorSpec(t *testing.T) { _, err := NewPackedBitVector(nil, 8) require.EqualError(t, err, errVectorPaddingTooLarge.Error()) }) - t.Run("Unmarshaling", func(t *testing.T) { - val := D{{"vector", Binary{Subtype: TypeBinaryVector, Data: []byte{PackedBitVector, 8}}}} - b, err := Marshal(val) - require.NoError(t, err, "marshaling test BSON") - var got struct { - Vector Vector - } - err = Unmarshal(b, &got) - require.ErrorContains(t, err, errVectorPaddingTooLarge.Error()) - }) }) } -// TODO: This test may be added into the spec tests. -func TestFloat32VectorWithInsufficientData(t *testing.T) { - t.Parallel() - - val := Binary{Subtype: TypeBinaryVector} - - for _, tc := range [][]byte{ - {Float32Vector, 0, 42}, - {Float32Vector, 0, 42, 42}, - {Float32Vector, 0, 42, 42, 42}, - - {Float32Vector, 0, 42, 42, 42, 42, 42}, - {Float32Vector, 0, 42, 42, 42, 42, 42, 42}, - {Float32Vector, 0, 42, 42, 42, 42, 42, 42, 42}, - } { - t.Run(fmt.Sprintf("marshaling %d bytes", len(tc)-2), func(t *testing.T) { - val.Data = tc - b, err := Marshal(D{{"vector", val}}) - require.NoError(t, err, "marshaling test BSON") - var got struct { - Vector Vector - } - err = Unmarshal(b, &got) - require.ErrorContains(t, err, errInsufficientVectorData.Error()) - }) - } -} - func convertSlice[T int8 | float32 | byte](s []interface{}) []T { v := make([]T, len(s)) for i, e := range s { @@ -208,33 +129,44 @@ func runBsonBinaryVectorTest(t *testing.T, testKey string, test bsonBinaryVector t.Run("Unmarshaling", func(t *testing.T) { skipCases := map[string]string{ - "FLOAT32 with padding": "run in alternative case", - "Overflow Vector INT8": "compile-time restriction", - "Underflow Vector INT8": "compile-time restriction", - "INT8 with padding": "run in alternative case", - "INT8 with float inputs": "compile-time restriction", - "Overflow Vector PACKED_BIT": "compile-time restriction", - "Underflow Vector PACKED_BIT": "compile-time restriction", - "Vector with float values PACKED_BIT": "compile-time restriction", - "Padding specified with no vector data PACKED_BIT": "run in alternative case", - "Exceeding maximum padding PACKED_BIT": "run in alternative case", - "Negative padding PACKED_BIT": "compile-time restriction", + "Overflow Vector INT8": "compile-time restriction", + "Underflow Vector INT8": "compile-time restriction", + "INT8 with float inputs": "compile-time restriction", + "Overflow Vector PACKED_BIT": "compile-time restriction", + "Underflow Vector PACKED_BIT": "compile-time restriction", + "Vector with float values PACKED_BIT": "compile-time restriction", + "Negative padding PACKED_BIT": "compile-time restriction", } if reason, ok := skipCases[test.Description]; ok { t.Skipf("skip test case %s: %s", test.Description, reason) } + errMap := map[string]string{ + "FLOAT32 with padding": "padding must be 0", + "INT8 with padding": "padding must be 0", + "Padding specified with no vector data PACKED_BIT": "padding must be 0", + "Exceeding maximum padding PACKED_BIT": "padding cannot be larger than 7", + } + t.Parallel() var got map[string]Vector err := Unmarshal(testBSON, &got) - require.NoError(t, err) - require.Equal(t, testVector, got) + if test.Valid { + require.NoError(t, err) + require.Equal(t, testVector, got) + } else if errMsg, ok := errMap[test.Description]; ok { + require.ErrorContains(t, err, errMsg) + } else { + require.Error(t, err) + } }) t.Run("Marshaling", func(t *testing.T) { skipCases := map[string]string{ "FLOAT32 with padding": "private padding field", + "Insufficient vector data with 3 bytes FLOAT32": "invalid case", + "Insufficient vector data with 5 bytes FLOAT32": "invalid case", "Overflow Vector INT8": "compile-time restriction", "Underflow Vector INT8": "compile-time restriction", "INT8 with padding": "private padding field", diff --git a/testdata/bson-binary-vector/float32.json b/testdata/bson-binary-vector/float32.json index d423f9e2bd..845f504ff3 100644 --- a/testdata/bson-binary-vector/float32.json +++ b/testdata/bson-binary-vector/float32.json @@ -44,7 +44,22 @@ "vector": [127.0, 7.0], "dtype_hex": "0x27", "dtype_alias": "FLOAT32", - "padding": 3 + "padding": 3, + "canonical_bson": "1C00000005766563746F72000A0000000927030000FE420000E04000" + }, + { + "description": "Insufficient vector data with 3 bytes FLOAT32", + "valid": false, + "dtype_hex": "0x27", + "dtype_alias": "FLOAT32", + "canonical_bson": "1700000005766563746F7200050000000927002A2A2A00" + }, + { + "description": "Insufficient vector data with 5 bytes FLOAT32", + "valid": false, + "dtype_hex": "0x27", + "dtype_alias": "FLOAT32", + "canonical_bson": "1900000005766563746F7200070000000927002A2A2A2A2A00" } ] } diff --git a/testdata/bson-binary-vector/int8.json b/testdata/bson-binary-vector/int8.json index d849819992..29524fb617 100644 --- a/testdata/bson-binary-vector/int8.json +++ b/testdata/bson-binary-vector/int8.json @@ -42,7 +42,8 @@ "vector": [127, 7], "dtype_hex": "0x03", "dtype_alias": "INT8", - "padding": 3 + "padding": 3, + "canonical_bson": "1600000005766563746F7200040000000903037F0700" }, { "description": "INT8 with float inputs", diff --git a/testdata/bson-binary-vector/packed_bit.json b/testdata/bson-binary-vector/packed_bit.json index 0d5dae52b4..a220e7e318 100644 --- a/testdata/bson-binary-vector/packed_bit.json +++ b/testdata/bson-binary-vector/packed_bit.json @@ -8,7 +8,8 @@ "vector": [], "dtype_hex": "0x10", "dtype_alias": "PACKED_BIT", - "padding": 1 + "padding": 1, + "canonical_bson": "1400000005766563746F72000200000009100100" }, { "description": "Simple Vector PACKED_BIT", @@ -61,21 +62,14 @@ "dtype_alias": "PACKED_BIT", "padding": 0 }, - { - "description": "Padding specified with no vector data PACKED_BIT", - "valid": false, - "vector": [], - "dtype_hex": "0x10", - "dtype_alias": "PACKED_BIT", - "padding": 1 - }, { "description": "Exceeding maximum padding PACKED_BIT", "valid": false, "vector": [1], "dtype_hex": "0x10", "dtype_alias": "PACKED_BIT", - "padding": 8 + "padding": 8, + "canonical_bson": "1500000005766563746F7200030000000910080100" }, { "description": "Negative padding PACKED_BIT", @@ -84,14 +78,6 @@ "dtype_hex": "0x10", "dtype_alias": "PACKED_BIT", "padding": -1 - }, - { - "description": "Vector with float values PACKED_BIT", - "valid": false, - "vector": [127.5], - "dtype_hex": "0x10", - "dtype_alias": "PACKED_BIT", - "padding": 0 } ] }