Skip to content

Commit 3b756a7

Browse files
RUST-2149 Sync additional vector tests (#514)
1 parent 098e1a1 commit 3b756a7

File tree

5 files changed

+74
-55
lines changed

5 files changed

+74
-55
lines changed

src/tests/spec/json/bson-binary-vector/README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Each JSON file contains three top-level keys.
2929

3030
- `description`: string describing the test.
3131
- `valid`: boolean indicating if the vector, dtype, and padding should be considered a valid input.
32-
- `vector`: list of numbers
32+
- `vector`: (required if valid is true) list of numbers
3333
- `dtype_hex`: string defining the data type in hex (e.g. "0x10", "0x27")
3434
- `dtype_alias`: (optional) string defining the data dtype, perhaps as Enum.
3535
- `padding`: (optional) integer for byte padding. Defaults to 0.
@@ -50,7 +50,10 @@ MUST assert that the input float array is the same after encoding and decoding.
5050

5151
#### To prove correct in an invalid case (`valid:false`), one MUST
5252

53-
- raise an exception when attempting to encode a document from the numeric values, dtype, and padding.
53+
- if the vector field is present, raise an exception when attempting to encode a document from the numeric values,
54+
dtype, and padding.
55+
- if the canonical_bson field is present, raise an exception when attempting to deserialize it into the corresponding
56+
numeric values, as the field contains corrupted data.
5457

5558
## FAQ
5659

src/tests/spec/json/bson-binary-vector/float32.json

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,22 @@
4444
"vector": [127.0, 7.0],
4545
"dtype_hex": "0x27",
4646
"dtype_alias": "FLOAT32",
47-
"padding": 3
47+
"padding": 3,
48+
"canonical_bson": "1C00000005766563746F72000A0000000927030000FE420000E04000"
49+
},
50+
{
51+
"description": "Insufficient vector data with 3 bytes FLOAT32",
52+
"valid": false,
53+
"dtype_hex": "0x27",
54+
"dtype_alias": "FLOAT32",
55+
"canonical_bson": "1700000005766563746F7200050000000927002A2A2A00"
56+
},
57+
{
58+
"description": "Insufficient vector data with 5 bytes FLOAT32",
59+
"valid": false,
60+
"dtype_hex": "0x27",
61+
"dtype_alias": "FLOAT32",
62+
"canonical_bson": "1900000005766563746F7200070000000927002A2A2A2A2A00"
4863
}
4964
]
5065
}
51-

src/tests/spec/json/bson-binary-vector/int8.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@
4242
"vector": [127, 7],
4343
"dtype_hex": "0x03",
4444
"dtype_alias": "INT8",
45-
"padding": 3
45+
"padding": 3,
46+
"canonical_bson": "1600000005766563746F7200040000000903037F0700"
4647
},
4748
{
4849
"description": "INT8 with float inputs",
@@ -54,4 +55,3 @@
5455
}
5556
]
5657
}
57-

src/tests/spec/json/bson-binary-vector/packed_bit.json

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
"vector": [],
99
"dtype_hex": "0x10",
1010
"dtype_alias": "PACKED_BIT",
11-
"padding": 1
11+
"padding": 1,
12+
"canonical_bson": "1400000005766563746F72000200000009100100"
1213
},
1314
{
1415
"description": "Simple Vector PACKED_BIT",
@@ -61,21 +62,14 @@
6162
"dtype_alias": "PACKED_BIT",
6263
"padding": 0
6364
},
64-
{
65-
"description": "Padding specified with no vector data PACKED_BIT",
66-
"valid": false,
67-
"vector": [],
68-
"dtype_hex": "0x10",
69-
"dtype_alias": "PACKED_BIT",
70-
"padding": 1
71-
},
7265
{
7366
"description": "Exceeding maximum padding PACKED_BIT",
7467
"valid": false,
7568
"vector": [1],
7669
"dtype_hex": "0x10",
7770
"dtype_alias": "PACKED_BIT",
78-
"padding": 8
71+
"padding": 8,
72+
"canonical_bson": "1500000005766563746F7200030000000910080100"
7973
},
8074
{
8175
"description": "Negative padding PACKED_BIT",
@@ -84,15 +78,6 @@
8478
"dtype_hex": "0x10",
8579
"dtype_alias": "PACKED_BIT",
8680
"padding": -1
87-
},
88-
{
89-
"description": "Vector with float values PACKED_BIT",
90-
"valid": false,
91-
"vector": [127.5],
92-
"dtype_hex": "0x10",
93-
"dtype_alias": "PACKED_BIT",
94-
"padding": 0
9581
}
9682
]
9783
}
98-

src/tests/spec/vector.rs

Lines changed: 47 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ struct TestFile {
3131
struct Test {
3232
description: String,
3333
valid: bool,
34-
vector: Vec<Number>,
34+
vector: Option<Vec<Number>>,
3535
#[serde(
3636
rename = "dtype_hex",
3737
deserialize_with = "deserialize_u8_from_hex_string"
@@ -131,51 +131,68 @@ fn vector_from_numbers(
131131
}
132132
}
133133

134+
// Only return the binary if it represents a valid vector; otherwise, return an error.
135+
fn binary_from_bytes(bson: &str, test_key: &str, description: &str) -> Result<Binary, String> {
136+
let bytes = hex::decode(bson).expect(description);
137+
let mut test_document = Document::from_reader(bytes.as_slice()).expect(description);
138+
let bson = test_document.remove(test_key).expect(description);
139+
let binary = match bson {
140+
Bson::Binary(binary) => binary,
141+
other => panic!("{}: expected binary, got {}", description, other),
142+
};
143+
if let Err(error) = Vector::try_from(&binary) {
144+
Err(error.to_string())
145+
} else {
146+
Ok(binary)
147+
}
148+
}
149+
134150
fn run_test_file(test_file: TestFile) {
135151
for test in test_file.tests {
136152
let description = format!("{} ({})", test.description, test_file.description);
137153

138-
let test_vector = match (
139-
vector_from_numbers(test.vector, test.d_type, test.padding),
140-
test.valid,
141-
) {
142-
(Ok(vector), true) => vector,
143-
(Err(_), false) => return,
144-
(Ok(vector), false) => panic!(
145-
"{}: valid was false but successfully constructed vector {:?}",
146-
description, vector
147-
),
148-
(Err(error), true) => panic!(
149-
"{}: valid was true but vector construction failed with error {}",
150-
description, error
151-
),
154+
let test_vector = match test.vector {
155+
Some(vector) => match vector_from_numbers(vector, test.d_type, test.padding) {
156+
Ok(vector) => {
157+
assert!(test.valid, "{}", description);
158+
Some(vector)
159+
}
160+
Err(error) => {
161+
assert!(!test.valid, "{}: {}", description, error);
162+
None
163+
}
164+
},
165+
None => None,
166+
};
167+
168+
let test_binary = match test.canonical_bson {
169+
Some(bson) => match binary_from_bytes(&bson, &test_file.test_key, &description) {
170+
Ok(vector) => {
171+
assert!(test.valid, "{}", description);
172+
Some(vector)
173+
}
174+
Err(error) => {
175+
assert!(!test.valid, "{}: {}", description, error);
176+
None
177+
}
178+
},
179+
None => None,
152180
};
153181

154-
let Some(canonical_bson) = test.canonical_bson else {
182+
let (Some(test_vector), Some(test_binary)) = (test_vector, test_binary) else {
155183
return;
156184
};
157185

158-
let bytes = hex::decode(canonical_bson).expect(&description);
159-
let mut test_document = Document::from_reader(bytes.as_slice()).expect(&description);
160-
// Rename the field to match the name used in the struct below.
161-
let vector = test_document
162-
.remove(&test_file.test_key)
163-
.expect(&description);
164-
test_document.insert("vector", vector);
165-
let bson = test_document.get("vector").expect(&description);
166-
let test_binary = match bson {
167-
Bson::Binary(binary) => binary,
168-
other => panic!("{}: expected binary, got {}", description, other),
169-
};
186+
let test_document = doc! { "vector": &test_binary };
170187

171188
// TryFrom<Binary> for Vector
172-
let parsed_vector = Vector::try_from(test_binary).expect(&description);
189+
let parsed_vector = Vector::try_from(&test_binary).expect(&description);
173190
assert_eq!(parsed_vector, test_vector);
174191

175192
// From<Vector> for Binary
176193
let binary = Binary::from(&test_vector);
177194
assert_eq!(binary.subtype, BinarySubtype::Vector);
178-
assert_eq!(&binary, test_binary);
195+
assert_eq!(binary, test_binary);
179196

180197
// From<Vector> for Bson
181198
let document = doc! { "vector": &test_vector };

0 commit comments

Comments
 (0)