1 /*
2 * Copyright 2013 MongoDB, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18 #include <time.h>
19
20 #include "bson-tests.h"
21 #include "TestSuite.h"
22
23
24 static void *
test_bson_writer_custom_realloc_helper(void * mem,size_t num_bytes,void * ctx)25 test_bson_writer_custom_realloc_helper (void *mem, size_t num_bytes, void *ctx)
26 {
27 int *x = (int *) ctx;
28
29 *x = *x + 1;
30 return bson_realloc (mem, num_bytes);
31 }
32
33 static void
test_bson_writer_custom_realloc(void)34 test_bson_writer_custom_realloc (void)
35 {
36 bson_writer_t *writer;
37 uint8_t *buf = bson_malloc (0);
38 size_t buflen = 0;
39 bson_t *b;
40 int x = 0;
41
42 writer = bson_writer_new (
43 &buf, &buflen, 0, test_bson_writer_custom_realloc_helper, &x);
44
45 BSON_ASSERT (bson_writer_begin (writer, &b));
46
47 BSON_ASSERT (bson_append_utf8 (b, "hello", -1, "world", -1));
48
49 bson_writer_end (writer);
50
51 bson_writer_destroy (writer);
52
53 BSON_ASSERT_CMPINT (x, >, 0);
54
55 bson_free (buf);
56 }
57
58
59 static void
test_bson_writer_shared_buffer(void)60 test_bson_writer_shared_buffer (void)
61 {
62 bson_writer_t *writer;
63 uint8_t *buf = bson_malloc0 (32);
64 bool rolled_back = false;
65 size_t buflen = 32;
66 size_t n_bytes;
67 bson_t *b;
68 const char *key;
69 char keystr[32];
70 int i = 0;
71 int j = 0;
72 int n_docs = 10000;
73
74 writer = bson_writer_new (&buf, &buflen, 0, bson_realloc_ctx, NULL);
75
76 for (i = 0; i < n_docs; i++) {
77 BSON_ASSERT (bson_writer_begin (writer, &b));
78
79 for (j = 0; j < 1000; j++) {
80 bson_uint32_to_string (j, &key, keystr, sizeof keystr);
81 BSON_ASSERT (bson_append_int64 (b, key, -1, j));
82 }
83
84 if (bson_writer_get_length (writer) > (48 * 1024 * 1024)) {
85 rolled_back = true;
86 bson_writer_rollback (writer);
87 break;
88 } else {
89 bson_writer_end (writer);
90 }
91 }
92
93 n_bytes = bson_writer_get_length (writer);
94
95 bson_writer_destroy (writer);
96
97 BSON_ASSERT_CMPINT (n_bytes, <, (48 * 1024 * 1024));
98 BSON_ASSERT_CMPINT (rolled_back, ==, true);
99 BSON_ASSERT (rolled_back);
100
101 bson_free (buf);
102 }
103
104
105 static void
test_bson_writer_empty_sequence(void)106 test_bson_writer_empty_sequence (void)
107 {
108 const uint8_t testdata[] = {5, 0, 0, 0, 0, 5, 0, 0, 0, 0, 5, 0, 0,
109 0, 0, 5, 0, 0, 0, 0, 5, 0, 0, 0, 0};
110 bson_writer_t *writer;
111 uint8_t *buf = NULL;
112 bson_t *b;
113 size_t len = 0;
114 int r;
115 int i;
116
117 writer = bson_writer_new (&buf, &len, 0, bson_realloc_ctx, NULL);
118 for (i = 0; i < 5; i++) {
119 BSON_ASSERT (bson_writer_begin (writer, &b));
120 bson_writer_end (writer);
121 }
122 r = memcmp (buf, testdata, 25);
123 BSON_ASSERT (r == 0);
124 bson_writer_destroy (writer);
125 bson_free (buf);
126 }
127
128
129 static void
test_bson_writer_null_realloc(void)130 test_bson_writer_null_realloc (void)
131 {
132 const uint8_t testdata[] = {5, 0, 0, 0, 0, 5, 0, 0, 0, 0, 5, 0, 0, 0, 0, 5,
133 0, 0, 0, 0, 5, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0};
134 bson_writer_t *writer;
135 uint8_t *buf = bson_malloc0 (32);
136 size_t buflen = 32;
137 bson_t *b;
138 int r;
139 int i;
140
141 writer = bson_writer_new (&buf, &buflen, 0, NULL, NULL);
142 for (i = 0; i < 6; i++) {
143 BSON_ASSERT (bson_writer_begin (writer, &b));
144 bson_writer_end (writer);
145 }
146
147 BSON_ASSERT (!bson_writer_begin (writer, &b));
148
149 r = memcmp (buf, testdata, 32);
150 BSON_ASSERT (r == 0);
151 bson_writer_destroy (writer);
152
153 bson_free (buf);
154 }
155
156 static void
test_bson_writer_null_realloc_2(void)157 test_bson_writer_null_realloc_2 (void)
158 {
159 const uint8_t testdata[] = {5, 0, 0, 0, 0, 5, 0, 0, 0, 0, 5, 0, 0, 0, 0, 5,
160 0, 0, 0, 0, 5, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0};
161 bson_writer_t *writer;
162 uint8_t *buf = bson_malloc0 (32);
163 size_t buflen = 32;
164 bson_t *b;
165 int r;
166 int i;
167
168 writer = bson_writer_new (&buf, &buflen, 0, NULL, NULL);
169 for (i = 0; i < 5; i++) {
170 BSON_ASSERT (bson_writer_begin (writer, &b));
171 bson_writer_end (writer);
172 }
173
174 BSON_ASSERT (bson_writer_begin (writer, &b));
175 BSON_ASSERT (!bson_append_int32 (b, "a", -1, 123));
176 bson_writer_end (writer);
177
178 r = memcmp (buf, testdata, 32);
179 BSON_ASSERT (r == 0);
180 bson_writer_destroy (writer);
181
182 bson_free (buf);
183 }
184
185 void
test_writer_install(TestSuite * suite)186 test_writer_install (TestSuite *suite)
187 {
188 TestSuite_Add (
189 suite, "/bson/writer/custom_realloc", test_bson_writer_custom_realloc);
190 TestSuite_Add (
191 suite, "/bson/writer/shared_buffer", test_bson_writer_shared_buffer);
192 TestSuite_Add (
193 suite, "/bson/writer/empty_sequence", test_bson_writer_empty_sequence);
194 TestSuite_Add (
195 suite, "/bson/writer/null_realloc", test_bson_writer_null_realloc);
196 TestSuite_Add (
197 suite, "/bson/writer/null_realloc_2", test_bson_writer_null_realloc_2);
198 }
199