Skip to content
This repository was archived by the owner on Oct 13, 2020. It is now read-only.

Commit eaeb976

Browse files
committed
CDRIVER-2225: Execute BSON corpus Decimal128 parse error tests
Since d7406f5, all parse error tests were executing with bson_new_from_json(), which is only appropriate for type 0x00. This commit also restructures the corpus test runner so that callbacks may be provided for decode and parse error tests as they are for valid tests. This change will make it easier to skip tests of any type, which will be necessary for CDRIVER-2223.
1 parent 35bba3c commit eaeb976

File tree

3 files changed

+180
-73
lines changed

3 files changed

+180
-73
lines changed

tests/corpus-test.c

+58-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ corpus_test_unhexlify (bson_iter_t *iter, uint32_t *bson_str_len)
6060

6161

6262
void
63-
corpus_test (bson_t *scenario, test_bson_type_valid_cb valid)
63+
corpus_test (bson_t *scenario,
64+
test_bson_valid_cb valid,
65+
test_bson_decode_error_cb decode_error,
66+
test_bson_parse_error_cb parse_error)
6467
{
6568
bson_iter_t iter;
6669
bson_iter_t inner_iter;
@@ -80,11 +83,12 @@ corpus_test (bson_t *scenario, test_bson_type_valid_cb valid)
8083
abort ();
8184
}
8285

86+
/* test valid BSON and Extended JSON */
8387
if (bson_iter_init_find (&iter, scenario, "valid")) {
8488
bson_iter_recurse (&iter, &inner_iter);
8589
while (bson_iter_next (&inner_iter)) {
8690
bson_iter_t test_iter;
87-
test_bson_type_t test = {scenario_description, bson_type, NULL};
91+
test_bson_valid_type_t test = {scenario_description, bson_type, NULL};
8892

8993
bson_iter_recurse (&inner_iter, &test_iter);
9094
while (bson_iter_next (&test_iter)) {
@@ -127,4 +131,56 @@ corpus_test (bson_t *scenario, test_bson_type_valid_cb valid)
127131
bson_free (test.dB);
128132
}
129133
}
134+
135+
/* test decoding errors (i.e. invalid BSON) */
136+
if (bson_iter_init_find (&iter, scenario, "decodeErrors")) {
137+
bson_iter_recurse (&iter, &inner_iter);
138+
while (bson_iter_next (&inner_iter)) {
139+
bson_iter_t test_iter;
140+
test_bson_decode_error_type_t test = {
141+
scenario_description, bson_type, NULL};
142+
143+
bson_iter_recurse (&inner_iter, &test_iter);
144+
while (bson_iter_next (&test_iter)) {
145+
if (!strcmp (bson_iter_key (&test_iter), "description")) {
146+
test.test_description = bson_iter_utf8 (&test_iter, NULL);
147+
corpus_test_print_description (test.test_description);
148+
}
149+
150+
if (!strcmp (bson_iter_key (&test_iter), "bson")) {
151+
test.bson = corpus_test_unhexlify (&test_iter, &test.bson_len);
152+
}
153+
}
154+
155+
/* execute the test callback */
156+
decode_error (&test);
157+
158+
bson_free (test.bson);
159+
}
160+
}
161+
162+
/* test parsing errors (e.g. invalid JSON or Decimal128 strings) */
163+
if (bson_iter_init_find (&iter, scenario, "parseErrors")) {
164+
bson_iter_recurse (&iter, &inner_iter);
165+
while (bson_iter_next (&inner_iter)) {
166+
bson_iter_t test_iter;
167+
test_bson_parse_error_type_t test = {
168+
scenario_description, bson_type, NULL};
169+
170+
bson_iter_recurse (&inner_iter, &test_iter);
171+
while (bson_iter_next (&test_iter)) {
172+
if (!strcmp (bson_iter_key (&test_iter), "description")) {
173+
test.test_description = bson_iter_utf8 (&test_iter, NULL);
174+
corpus_test_print_description (test.test_description);
175+
}
176+
177+
if (!strcmp (bson_iter_key (&test_iter), "string")) {
178+
test.str = bson_iter_utf8 (&test_iter, &test.str_len);
179+
}
180+
}
181+
182+
/* execute the test callback */
183+
parse_error (&test);
184+
}
185+
}
130186
}

tests/corpus-test.h

+34-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
github.com/mongodb/specifications/blob/master/source/bson-corpus/bson-corpus.rst
2727
#testing-validity
2828
*/
29-
typedef struct _test_bson_type_t {
29+
typedef struct _test_bson_valid_type_t {
3030
const char *scenario_description;
3131
bson_type_t bson_type;
3232
const char *test_description;
@@ -38,16 +38,46 @@ typedef struct _test_bson_type_t {
3838
const char *rE; /* "relaxed_extjson" */
3939
const char *dE; /* "degenerate_extjson" */
4040
bool lossy;
41-
} test_bson_type_t;
41+
} test_bson_valid_type_t;
4242

43+
/*
44+
See:
45+
github.com/mongodb/specifications/blob/master/source/bson-corpus/bson-corpus.rst
46+
#testing-decode-errors
47+
*/
48+
typedef struct _test_bson_decode_error_type_t {
49+
const char *scenario_description;
50+
bson_type_t bson_type;
51+
const char *test_description;
52+
uint8_t *bson;
53+
uint32_t bson_len;
54+
} test_bson_decode_error_type_t;
55+
56+
/*
57+
See:
58+
github.com/mongodb/specifications/blob/master/source/bson-corpus/bson-corpus.rst
59+
#testing-parsing-errors
60+
*/
61+
typedef struct _test_bson_parse_error_type_t {
62+
const char *scenario_description;
63+
bson_type_t bson_type;
64+
const char *test_description;
65+
const char *str;
66+
uint32_t str_len;
67+
} test_bson_parse_error_type_t;
4368

44-
typedef void (*test_bson_type_valid_cb) (test_bson_type_t *test);
69+
typedef void (*test_bson_valid_cb) (test_bson_valid_type_t *test);
70+
typedef void (*test_bson_decode_error_cb) (test_bson_decode_error_type_t *test);
71+
typedef void (*test_bson_parse_error_cb) (test_bson_parse_error_type_t *test);
4572

4673
void
4774
corpus_test_print_description (const char *description);
4875
uint8_t *
4976
corpus_test_unhexlify (bson_iter_t *iter, uint32_t *bson_str_len);
5077
void
51-
corpus_test (bson_t *scenario, test_bson_type_valid_cb valid);
78+
corpus_test (bson_t *scenario,
79+
test_bson_valid_cb valid,
80+
test_bson_decode_error_cb decode_error,
81+
test_bson_parse_error_cb parse_error);
5282

5383
#endif

tests/test-bson-corpus.c

+88-67
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
#endif
99

1010

11+
#define IS_NAN(dec) (dec).high == 0x7c00000000000000ull
12+
13+
1114
typedef struct {
1215
const char *scenario;
1316
const char *test;
@@ -54,6 +57,22 @@ compare_data (const uint8_t *a,
5457
}
5558

5659

60+
static bool
61+
is_test_skipped (const char *scenario, const char *description)
62+
{
63+
skipped_corpus_test_t *skip;
64+
65+
for (skip = SKIPPED_CORPUS_TESTS; skip->scenario != NULL; skip++) {
66+
if (!strcmp (skip->scenario, scenario) &&
67+
!strcmp (skip->test, description)) {
68+
return true;
69+
}
70+
}
71+
72+
return false;
73+
}
74+
75+
5776
/*
5877
See:
5978
github.com/mongodb/specifications/blob/master/source/bson-corpus/bson-corpus.rst
@@ -78,9 +97,8 @@ github.com/mongodb/specifications/blob/master/source/bson-corpus/bson-corpus.rst
7897
7998
*/
8099
static void
81-
test_bson_corpus (test_bson_type_t *test)
100+
test_bson_corpus_valid (test_bson_valid_type_t *test)
82101
{
83-
skipped_corpus_test_t *skip;
84102
bson_t cB;
85103
bson_t dB;
86104
bson_t *decode_cE;
@@ -91,16 +109,13 @@ test_bson_corpus (test_bson_type_t *test)
91109
BSON_ASSERT (test->cB);
92110
BSON_ASSERT (test->cE);
93111

94-
for (skip = SKIPPED_CORPUS_TESTS; skip->scenario != NULL; skip++) {
95-
if (!strcmp (skip->scenario, test->scenario_description) &&
96-
!strcmp (skip->test, test->test_description)) {
97-
if (test_suite_debug_output ()) {
98-
printf (" SKIP\n");
99-
fflush (stdout);
100-
}
101-
102-
return;
112+
if (is_test_skipped (test->scenario_description, test->test_description)) {
113+
if (test_suite_debug_output ()) {
114+
printf (" SKIP\n");
115+
fflush (stdout);
103116
}
117+
118+
return;
104119
}
105120

106121
BSON_ASSERT (bson_init_static (&cB, test->cB, test->cB_len));
@@ -158,71 +173,77 @@ test_bson_corpus (test_bson_type_t *test)
158173
}
159174

160175

176+
/*
177+
See:
178+
github.com/mongodb/specifications/blob/master/source/bson-corpus/bson-corpus.rst
179+
#testing-decode-errors
180+
*/
161181
static void
162-
test_bson_corpus_cb (bson_t *scenario)
182+
test_bson_corpus_decode_error (test_bson_decode_error_type_t *test)
163183
{
164-
bson_iter_t iter;
165-
bson_iter_t inner_iter;
166184
bson_t invalid_bson;
167185

168-
/* test valid BSON and Extended JSON */
169-
corpus_test (scenario, test_bson_corpus);
170-
171-
/* test invalid BSON */
172-
if (bson_iter_init_find (&iter, scenario, "decodeErrors")) {
173-
bson_iter_recurse (&iter, &inner_iter);
174-
while (bson_iter_next (&inner_iter)) {
175-
bson_iter_t test;
176-
const char *description;
177-
uint8_t *bson_str = NULL;
178-
uint32_t bson_str_len = 0;
179-
180-
bson_iter_recurse (&inner_iter, &test);
181-
while (bson_iter_next (&test)) {
182-
if (!strcmp (bson_iter_key (&test), "description")) {
183-
description = bson_iter_utf8 (&test, NULL);
184-
corpus_test_print_description (description);
185-
}
186-
187-
if (!strcmp (bson_iter_key (&test), "bson")) {
188-
bson_str = corpus_test_unhexlify (&test, &bson_str_len);
189-
}
190-
}
191-
192-
ASSERT (bson_str);
193-
ASSERT (!bson_init_static (&invalid_bson, bson_str, bson_str_len) ||
194-
bson_empty (&invalid_bson) ||
195-
!bson_as_canonical_json (&invalid_bson, NULL));
196-
197-
bson_free (bson_str);
186+
BSON_ASSERT (test->bson);
187+
188+
if (is_test_skipped (test->scenario_description, test->test_description)) {
189+
if (test_suite_debug_output ()) {
190+
printf (" SKIP\n");
191+
fflush (stdout);
198192
}
193+
194+
return;
199195
}
200196

201-
/* test invalid JSON */
202-
if (bson_iter_init_find (&iter, scenario, "parseErrors")) {
203-
bson_iter_recurse (&iter, &inner_iter);
204-
while (bson_iter_next (&inner_iter)) {
205-
bson_iter_t test;
206-
const char *description = NULL;
207-
const char *input = NULL;
208-
uint32_t tmp = 0;
209-
210-
bson_iter_recurse (&inner_iter, &test);
211-
while (bson_iter_next (&test)) {
212-
if (!strcmp (bson_iter_key (&test), "description")) {
213-
description = bson_iter_utf8 (&test, NULL);
214-
corpus_test_print_description (description);
215-
}
216-
217-
if (!strcmp (bson_iter_key (&test), "string")) {
218-
input = bson_iter_utf8 (&test, &tmp);
219-
}
220-
}
221-
222-
ASSERT (input);
223-
ASSERT (!bson_new_from_json ((uint8_t *) input, tmp, NULL));
197+
ASSERT (test->bson);
198+
ASSERT (!bson_init_static (&invalid_bson, test->bson, test->bson_len) ||
199+
bson_empty (&invalid_bson) ||
200+
!bson_as_canonical_json (&invalid_bson, NULL));
201+
}
202+
203+
204+
/*
205+
See:
206+
github.com/mongodb/specifications/blob/master/source/bson-corpus/bson-corpus.rst
207+
#testing-parsing-errors
208+
*/
209+
static void
210+
test_bson_corpus_parse_error (test_bson_parse_error_type_t *test)
211+
{
212+
BSON_ASSERT (test->str);
213+
214+
if (is_test_skipped (test->scenario_description, test->test_description)) {
215+
if (test_suite_debug_output ()) {
216+
printf (" SKIP\n");
217+
fflush (stdout);
224218
}
219+
220+
return;
225221
}
222+
223+
switch (test->bson_type) {
224+
case 0x00: /* top-level document to be parsed as JSON */
225+
ASSERT (!bson_new_from_json ((uint8_t *) test->str, test->str_len, NULL));
226+
break;
227+
case BSON_TYPE_DECIMAL128: {
228+
bson_decimal128_t dec;
229+
ASSERT (!bson_decimal128_from_string (test->str, &dec));
230+
ASSERT (IS_NAN (dec));
231+
break;
232+
}
233+
default:
234+
fprintf (stderr, "Unsupported parseError type: %#x\n", test->bson_type);
235+
abort ();
236+
}
237+
}
238+
239+
240+
static void
241+
test_bson_corpus_cb (bson_t *scenario)
242+
{
243+
corpus_test (scenario,
244+
test_bson_corpus_valid,
245+
test_bson_corpus_decode_error,
246+
test_bson_corpus_parse_error);
226247
}
227248

228249
void

0 commit comments

Comments
 (0)