• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "ejdb_test.h"
2 #include <stdlib.h>
3 #include <CUnit/Basic.h>
4 
init_suite()5 int init_suite() {
6   int rc = ejdb_init();
7   return rc;
8 }
9 
clean_suite()10 int clean_suite() {
11   return 0;
12 }
13 
14 // Test document sorting overflow on disk
ejdb_test2_2()15 static void ejdb_test2_2() {
16   EJDB_OPTS opts = {
17     .kv                 = {
18       .path             = "ejdb_test2_2.db",
19       .oflags           = IWKV_TRUNC
20     },
21     .document_buffer_sz = 16 * 1024,   // 16K
22     .sort_buffer_sz     = 1024 * 1024, // 1M
23     .no_wal             = true
24   };
25   EJDB db;
26   EJDB_LIST list = 0;
27   const int vbufsz = 512 * 1024;
28   const int dbufsz = vbufsz + 128;
29   char *vbuf = malloc(vbufsz);
30   char *dbuf = malloc(dbufsz);
31   CU_ASSERT_PTR_NOT_NULL_FATAL(vbuf);
32   CU_ASSERT_PTR_NOT_NULL_FATAL(dbuf);
33   memset(vbuf, 'z', vbufsz);
34   vbuf[vbufsz - 1] = '\0';
35 
36   iwrc rc = ejdb_open(&opts, &db);
37   CU_ASSERT_EQUAL_FATAL(rc, 0);
38 
39   for (int i = 0; i < 6; ++i) {
40     snprintf(dbuf, dbufsz, "{\"f\":%d, \"d\":\"%s\"}", i, vbuf);
41     rc = put_json(db, "c1", dbuf);
42     CU_ASSERT_EQUAL_FATAL(rc, 0);
43   }
44   // Here is we will overflow sort buffer
45   rc = ejdb_list2(db, "c1", "/f | asc /f", 0, &list);
46   CU_ASSERT_EQUAL_FATAL(rc, 0);
47   int i = 0;
48   for (EJDB_DOC doc = list->first; doc; doc = doc->next, ++i) {
49     JBL jbl;
50     rc = jbl_at(doc->raw, "/f", &jbl);
51     CU_ASSERT_EQUAL_FATAL(rc, 0);
52     int64_t llv = jbl_get_i64(jbl);
53     jbl_destroy(&jbl);
54     CU_ASSERT_EQUAL(llv, i);
55   }
56   ejdb_list_destroy(&list);
57 
58   rc = ejdb_close(&db);
59   CU_ASSERT_EQUAL_FATAL(rc, 0);
60   free(vbuf);
61   free(dbuf);
62 }
63 
64 struct TEST21_1 {
65   int     stage;
66   int     cnt;
67   IWXSTR *xstr;
68 };
69 
ejdb_test2_1_exec_visitor1(struct _EJDB_EXEC * ctx,const EJDB_DOC doc,int64_t * step)70 static iwrc ejdb_test2_1_exec_visitor1(struct _EJDB_EXEC *ctx, const EJDB_DOC doc, int64_t *step) {
71   struct TEST21_1 *tc = ctx->opaque;
72   JBL jbl;
73   iwrc rc = jbl_at(doc->raw, "/f", &jbl);
74   RCRET(rc);
75   int64_t llv = jbl_get_i64(jbl);
76   if (tc->cnt && (tc->stage == 0)) {
77     tc->stage = 1;
78     *step = 2;
79   } else if (tc->stage == 1) {
80     tc->stage = 2;
81     *step = -1;
82   }
83   jbl_destroy(&jbl);
84   iwxstr_printf(tc->xstr, "%lld", llv);
85   tc->cnt++;
86   return rc;
87 }
88 
ejdb_test2_1()89 static void ejdb_test2_1() {
90   EJDB_OPTS opts = {
91     .kv       = {
92       .path   = "ejdb_test2_1.db",
93       .oflags = IWKV_TRUNC
94     },
95     .no_wal   = true
96   };
97 
98   EJDB db;
99   EJDB_LIST list = 0;
100   IWXSTR *xstr = iwxstr_new();
101   CU_ASSERT_PTR_NOT_NULL_FATAL(xstr);
102   int i = 0;
103 
104   iwrc rc = ejdb_open(&opts, &db);
105   CU_ASSERT_EQUAL_FATAL(rc, 0);
106 
107   rc = put_json(db, "a", "{'f':2}");
108   CU_ASSERT_EQUAL_FATAL(rc, 0);
109   rc = put_json(db, "a", "{'f':1}");
110   CU_ASSERT_EQUAL_FATAL(rc, 0);
111   rc = put_json(db, "a", "{'f':3}");
112   CU_ASSERT_EQUAL_FATAL(rc, 0);
113   rc = put_json(db, "a", "{'a':'foo'}");
114   CU_ASSERT_EQUAL_FATAL(rc, 0);
115   rc = put_json(db, "a", "{'a':'gaz'}");
116   CU_ASSERT_EQUAL_FATAL(rc, 0);
117   rc = put_json(db, "a", "{'a':'bar'}");
118   CU_ASSERT_EQUAL_FATAL(rc, 0);
119 
120   rc = ejdb_list2(db, "not_exists", "/*", 0, &list);
121   CU_ASSERT_EQUAL_FATAL(rc, 0);
122   i = 0;
123   for (EJDB_DOC doc = list->first; doc; doc = doc->next, ++i) {
124   }
125   CU_ASSERT_EQUAL(i, 0);
126   ejdb_list_destroy(&list);
127 
128   rc = ejdb_list2(db, "a", "/*", 0, &list);
129   CU_ASSERT_EQUAL_FATAL(rc, 0);
130   i = 0;
131   for (EJDB_DOC doc = list->first; doc; doc = doc->next, ++i) {
132     iwxstr_clear(xstr);
133     rc = jbl_as_json(doc->raw, jbl_xstr_json_printer, xstr, 0);
134     CU_ASSERT_EQUAL_FATAL(rc, 0);
135     switch (i) {
136       case 0:
137         CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr), "{\"a\":\"bar\"}");
138         break;
139       case 1:
140         CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr), "{\"a\":\"gaz\"}");
141         break;
142       case 2:
143         CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr), "{\"a\":\"foo\"}");
144         break;
145       case 5:
146         CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr), "{\"f\":2}");
147         break;
148     }
149   }
150   CU_ASSERT_EQUAL(i, 6);
151   ejdb_list_destroy(&list);
152 
153   rc = ejdb_list2(db, "a", "/*", 1, &list);
154   CU_ASSERT_EQUAL_FATAL(rc, 0);
155   i = 0;
156   for (EJDB_DOC doc = list->first; doc; doc = doc->next, ++i) {
157   }
158   CU_ASSERT_EQUAL(i, 1);
159   ejdb_list_destroy(&list);
160 
161   rc = ejdb_list2(db, "a", "/f", 0, &list);
162   CU_ASSERT_EQUAL_FATAL(rc, 0);
163   i = 0;
164   for (EJDB_DOC doc = list->first; doc; doc = doc->next, ++i) {
165   }
166   CU_ASSERT_EQUAL(i, 3);
167   ejdb_list_destroy(&list);
168 
169   rc = ejdb_list2(db, "a", "/* | skip 1", 0, &list);
170   CU_ASSERT_EQUAL_FATAL(rc, 0);
171   i = 0;
172   for (EJDB_DOC doc = list->first; doc; doc = doc->next, ++i) {
173     iwxstr_clear(xstr);
174     rc = jbl_as_json(doc->raw, jbl_xstr_json_printer, xstr, 0);
175     CU_ASSERT_EQUAL_FATAL(rc, 0);
176     switch (i) {
177       case 0:
178         CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr), "{\"a\":\"gaz\"}");
179         break;
180     }
181   }
182   CU_ASSERT_EQUAL(i, 5);
183   ejdb_list_destroy(&list);
184 
185   rc = ejdb_list2(db, "a", "/* | skip 2 limit 3", 0, &list);
186   CU_ASSERT_EQUAL_FATAL(rc, 0);
187   i = 0;
188   for (EJDB_DOC doc = list->first; doc; doc = doc->next, ++i) {
189     iwxstr_clear(xstr);
190     rc = jbl_as_json(doc->raw, jbl_xstr_json_printer, xstr, 0);
191     CU_ASSERT_EQUAL_FATAL(rc, 0);
192     switch (i) {
193       case 0:
194         CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr), "{\"a\":\"foo\"}");
195         break;
196     }
197   }
198   CU_ASSERT_EQUAL(i, 3);
199   ejdb_list_destroy(&list);
200 
201   // Add {f:5}, {f:6}
202   rc = put_json(db, "a", "{'f':5}");
203   CU_ASSERT_EQUAL_FATAL(rc, 0);
204 
205   rc = put_json(db, "a", "{'f':6}");
206   CU_ASSERT_EQUAL_FATAL(rc, 0);
207 
208   rc = ejdb_list2(db, "a", "/f | asc /f", 0, &list);
209   CU_ASSERT_EQUAL_FATAL(rc, 0);
210   i = 0;
211   for (EJDB_DOC doc = list->first; doc; doc = doc->next, ++i) {
212     iwxstr_clear(xstr);
213     rc = jbl_as_json(doc->raw, jbl_xstr_json_printer, xstr, 0);
214     CU_ASSERT_EQUAL_FATAL(rc, 0);
215     switch (i) {
216       case 0:
217         CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr), "{\"f\":1}");
218         break;
219       case 1:
220         CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr), "{\"f\":2}");
221         break;
222       case 2:
223         CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr), "{\"f\":3}");
224         break;
225       case 3:
226         CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr), "{\"f\":5}");
227         break;
228       case 4:
229         CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr), "{\"f\":6}");
230         break;
231     }
232   }
233   CU_ASSERT_EQUAL(i, 5);
234   ejdb_list_destroy(&list);
235 
236   rc = ejdb_list2(db, "a", "/f | desc /f", 0, &list);
237   CU_ASSERT_EQUAL_FATAL(rc, 0);
238   i = 0;
239   for (EJDB_DOC doc = list->first; doc; doc = doc->next, ++i) {
240     iwxstr_clear(xstr);
241     rc = jbl_as_json(doc->raw, jbl_xstr_json_printer, xstr, 0);
242     CU_ASSERT_EQUAL_FATAL(rc, 0);
243     switch (i) {
244       case 0:
245         CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr), "{\"f\":6}");
246         break;
247       case 1:
248         CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr), "{\"f\":5}");
249         break;
250       case 2:
251         CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr), "{\"f\":3}");
252         break;
253       case 3:
254         CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr), "{\"f\":2}");
255         break;
256       case 4:
257         CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr), "{\"f\":1}");
258         break;
259     }
260   }
261   CU_ASSERT_EQUAL(i, 5);
262   ejdb_list_destroy(&list);
263 
264   //
265   // Now test basic back/forward skips
266   //
267   JQL q;
268   struct TEST21_1 tc = { 0 };
269   tc.xstr = iwxstr_new();
270   rc = jql_create(&q, "a", "/f");
271   CU_ASSERT_EQUAL_FATAL(rc, 0);
272   EJDB_EXEC ux = {
273     .db      = db,
274     .q       = q,
275     .opaque  = &tc,
276     .visitor = ejdb_test2_1_exec_visitor1
277   };
278   rc = ejdb_exec(&ux);
279   CU_ASSERT_EQUAL_FATAL(rc, 0);
280   CU_ASSERT_STRING_EQUAL(iwxstr_ptr(tc.xstr), "65112");
281   jql_destroy(&q);
282   iwxstr_destroy(tc.xstr);
283 
284   // back/forward skips for sorted output
285   memset(&tc, 0, sizeof(tc));
286   tc.xstr = iwxstr_new();
287   rc = jql_create(&q, "a", "/f | asc /f");
288   CU_ASSERT_EQUAL_FATAL(rc, 0);
289   ux.q = q;
290   rc = ejdb_exec(&ux);
291   CU_ASSERT_EQUAL_FATAL(rc, 0);
292   CU_ASSERT_STRING_EQUAL(iwxstr_ptr(tc.xstr), "12556");
293   jql_destroy(&q);
294   iwxstr_destroy(tc.xstr);
295 
296   rc = ejdb_close(&db);
297   CU_ASSERT_EQUAL_FATAL(rc, 0);
298   iwxstr_destroy(xstr);
299 }
300 
main()301 int main() {
302   CU_pSuite pSuite = NULL;
303   if (CUE_SUCCESS != CU_initialize_registry()) {
304     return CU_get_error();
305   }
306   pSuite = CU_add_suite("ejdb_test1", init_suite, clean_suite);
307   if (NULL == pSuite) {
308     CU_cleanup_registry();
309     return CU_get_error();
310   }
311   if (  (NULL == CU_add_test(pSuite, "ejdb_test2_1", ejdb_test2_1))
312      || (NULL == CU_add_test(pSuite, "ejdb_test2_2", ejdb_test2_2))) {
313     CU_cleanup_registry();
314     return CU_get_error();
315   }
316   CU_basic_set_mode(CU_BRM_VERBOSE);
317   CU_basic_run_tests();
318   int ret = CU_get_error() || CU_get_number_of_failures();
319   CU_cleanup_registry();
320   return ret;
321 }
322