• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "ejdb_test.h"
2 #include <CUnit/Basic.h>
3 #include <curl/curl.h>
4 
5 CURL *curl;
6 
init_suite()7 int init_suite() {
8   curl_global_init(CURL_GLOBAL_ALL);
9   curl = curl_easy_init();
10   if (!curl) {
11     return 1;
12   }
13   int rc = ejdb_init();
14   return rc;
15 }
16 
clean_suite()17 int clean_suite() {
18   curl_easy_cleanup(curl);
19   curl_global_cleanup();
20   return 0;
21 }
22 
curl_write_xstr(void * contents,size_t size,size_t nmemb,void * op)23 static size_t curl_write_xstr(void *contents, size_t size, size_t nmemb, void *op) {
24   IWXSTR *xstr = op;
25   assert(xstr);
26   iwxstr_cat(xstr, contents, size * nmemb);
27   return size * nmemb;
28 }
29 
jbr_test1_1()30 static void jbr_test1_1() {
31   char url[64];
32   uint32_t port = iwu_rand_range(20000) + 20000;
33 
34   EJDB_OPTS opts = {
35     .kv         = {
36       .path     = "jbr_test1_1.db",
37       .oflags   = IWKV_TRUNC
38     },
39     .no_wal     = true,
40     .http       = {
41       .bind     = "127.0.0.1",
42       .blocking = false,
43       .enabled  = true,
44       .port     = port
45     }
46   };
47 
48   long code;
49   EJDB db;
50   iwrc rc = ejdb_open(&opts, &db);
51   if (rc) {
52     iwlog_ecode_error3(rc);
53   }
54   CU_ASSERT_EQUAL_FATAL(rc, 0);
55 
56   IWXSTR *xstr = iwxstr_new();
57   IWXSTR *hstr = iwxstr_new();
58   struct curl_slist *headers = curl_slist_append(0, "Content-Type: application/json");
59 
60   snprintf(url, sizeof(url), "http://localhost:%" PRIu32 "/c1/1", port);
61 
62   // Check no element in collection
63   CURLcode cc = curl_easy_setopt(curl, CURLOPT_URL, url);
64   CU_ASSERT_EQUAL_FATAL(cc, 0);
65   cc = curl_easy_perform(curl);
66   CU_ASSERT_EQUAL_FATAL(cc, 0);
67   curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
68   CU_ASSERT_EQUAL_FATAL(code, 404);
69 
70 
71   snprintf(url, sizeof(url), "http://localhost:%" PRIu32 "/c1", port);
72 
73   // Save a document using POST
74   curl_easy_reset(curl);
75   curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
76   CU_ASSERT_EQUAL_FATAL(cc, 0);
77   curl_easy_setopt(curl, CURLOPT_URL, url);
78   curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
79   curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "{\"foo\":\"bar\"}");
80   curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_xstr);
81   curl_easy_setopt(curl, CURLOPT_WRITEDATA, xstr);
82   cc = curl_easy_perform(curl);
83   CU_ASSERT_EQUAL_FATAL(cc, 0);
84   curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
85   CU_ASSERT_EQUAL_FATAL(code, 200);
86   CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr), "1");
87 
88   // Now get document JSON using GET
89   curl_easy_reset(curl);
90   iwxstr_clear(xstr);
91   iwxstr_clear(hstr);
92 
93   snprintf(url, sizeof(url), "http://localhost:%" PRIu32 "/c1/1", port);
94 
95   curl_easy_setopt(curl, CURLOPT_URL, url);
96   curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_xstr);
97   curl_easy_setopt(curl, CURLOPT_WRITEDATA, xstr);
98   curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, curl_write_xstr);
99   curl_easy_setopt(curl, CURLOPT_HEADERDATA, hstr);
100   cc = curl_easy_perform(curl);
101   CU_ASSERT_EQUAL_FATAL(cc, 0);
102   curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
103   CU_ASSERT_EQUAL_FATAL(code, 200);
104   CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr),
105                          "{\n"
106                          " \"foo\": \"bar\"\n"
107                          "}"
108                          );
109   CU_ASSERT_PTR_NOT_NULL(strstr(iwxstr_ptr(hstr), "content-type:application/json"));
110   CU_ASSERT_PTR_NOT_NULL(strstr(iwxstr_ptr(hstr), "content-length:17"));
111   CU_ASSERT_EQUAL(iwxstr_size(xstr), 17);
112 
113   // PUT document under specific ID
114   curl_easy_reset(curl);
115   iwxstr_clear(xstr);
116   iwxstr_clear(hstr);
117   curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
118   CU_ASSERT_EQUAL_FATAL(cc, 0);
119 
120   snprintf(url, sizeof(url), "http://localhost:%" PRIu32 "/c1/33", port);
121 
122   curl_easy_setopt(curl, CURLOPT_URL, url);
123   curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
124   curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "{\"foo\":\"b\nar\"}");
125   curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_xstr);
126   curl_easy_setopt(curl, CURLOPT_WRITEDATA, xstr);
127   cc = curl_easy_perform(curl);
128   CU_ASSERT_EQUAL_FATAL(cc, 0);
129   curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
130   CU_ASSERT_EQUAL_FATAL(code, 200);
131 
132   // Check the last doc
133   curl_easy_reset(curl);
134   iwxstr_clear(xstr);
135   iwxstr_clear(hstr);
136   curl_easy_setopt(curl, CURLOPT_URL, url);
137   curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_xstr);
138   curl_easy_setopt(curl, CURLOPT_WRITEDATA, xstr);
139   curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, curl_write_xstr);
140   curl_easy_setopt(curl, CURLOPT_HEADERDATA, hstr);
141   cc = curl_easy_perform(curl);
142   CU_ASSERT_EQUAL_FATAL(cc, 0);
143   curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
144   CU_ASSERT_EQUAL_FATAL(code, 200);
145   CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr),
146                          "{\n"
147                          " \"foo\": \"b\\nar\"\n"
148                          "}"
149                          );
150   CU_ASSERT_PTR_NOT_NULL(strstr(iwxstr_ptr(hstr), "content-type:application/json"));
151   CU_ASSERT_PTR_NOT_NULL(strstr(iwxstr_ptr(hstr), "content-length:19"));
152   CU_ASSERT_EQUAL(iwxstr_size(xstr), 19);
153 
154   // Perform a query
155   curl_easy_reset(curl);
156   iwxstr_clear(xstr);
157   iwxstr_clear(hstr);
158 
159   snprintf(url, sizeof(url), "http://localhost:%" PRIu32 "/", port);
160 
161   curl_easy_setopt(curl, CURLOPT_URL, url);
162   curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "@c1/foo");
163   curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_xstr);
164   curl_easy_setopt(curl, CURLOPT_WRITEDATA, xstr);
165   curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, curl_write_xstr);
166   curl_easy_setopt(curl, CURLOPT_HEADERDATA, hstr);
167   cc = curl_easy_perform(curl);
168   CU_ASSERT_EQUAL_FATAL(cc, 0);
169   curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
170   CU_ASSERT_EQUAL_FATAL(code, 200);
171 
172   CU_ASSERT_PTR_NOT_NULL(strstr(iwxstr_ptr(xstr), "33\t{\"foo\":\"b\\nar\"}"));
173   CU_ASSERT_PTR_NOT_NULL(strstr(iwxstr_ptr(xstr), "1\t{\"foo\":\"bar\"}"));
174 
175   // Query with explain
176   curl_easy_reset(curl);
177   iwxstr_clear(xstr);
178   iwxstr_clear(hstr);
179   curl_slist_free_all(headers);
180   headers = curl_slist_append(0, "X-Hints: explain");
181   curl_easy_setopt(curl, CURLOPT_URL, url);
182   curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
183   curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "@c1/foo");
184   curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_xstr);
185   curl_easy_setopt(curl, CURLOPT_WRITEDATA, xstr);
186   curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, curl_write_xstr);
187   curl_easy_setopt(curl, CURLOPT_HEADERDATA, hstr);
188   cc = curl_easy_perform(curl);
189   CU_ASSERT_EQUAL_FATAL(cc, 0);
190   curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
191   CU_ASSERT_EQUAL_FATAL(code, 200);
192   CU_ASSERT_PTR_NOT_NULL(strstr(iwxstr_ptr(xstr), "[INDEX] NO [COLLECTOR] PLAIN"));
193   CU_ASSERT_PTR_NOT_NULL(strstr(iwxstr_ptr(xstr), "--------------------"));
194   CU_ASSERT_PTR_NOT_NULL(strstr(iwxstr_ptr(xstr), "33\t{\"foo\":\"b\\nar\"}"));
195   CU_ASSERT_PTR_NOT_NULL(strstr(iwxstr_ptr(xstr), "1\t{\"foo\":\"bar\"}"));
196 
197   // Delete resource
198   curl_easy_reset(curl);
199   iwxstr_clear(xstr);
200   iwxstr_clear(hstr);
201 
202   snprintf(url, sizeof(url), "http://localhost:%" PRIu32 "/c1/33", port);
203 
204   curl_easy_setopt(curl, CURLOPT_URL, url);
205   curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
206   cc = curl_easy_perform(curl);
207   CU_ASSERT_EQUAL_FATAL(cc, 0);
208   curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
209   CU_ASSERT_EQUAL_FATAL(code, 200);
210 
211   // Check the resource has been deleted
212   curl_easy_reset(curl);
213   iwxstr_clear(xstr);
214   iwxstr_clear(hstr);
215   curl_easy_setopt(curl, CURLOPT_URL, url);
216   cc = curl_easy_perform(curl);
217   CU_ASSERT_EQUAL_FATAL(cc, 0);
218   curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
219   CU_ASSERT_EQUAL_FATAL(code, 404);
220 
221   // Apply patch
222   curl_easy_reset(curl);
223   iwxstr_clear(xstr);
224   iwxstr_clear(hstr);
225   curl_slist_free_all(headers);
226   headers = curl_slist_append(0, "Content-Type: application/json");
227 
228   snprintf(url, sizeof(url), "http://localhost:%" PRIu32 "/c1/1", port);
229 
230   curl_easy_setopt(curl, CURLOPT_URL, url);
231   curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PATCH");
232   curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
233   curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "[{\"op\":\"replace\", \"path\":\"/foo\", \"value\":\"zzz\"}]");
234   cc = curl_easy_perform(curl);
235   CU_ASSERT_EQUAL_FATAL(cc, 0);
236   curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
237   CU_ASSERT_EQUAL_FATAL(code, 200);
238 
239   // Check patch applied
240   curl_easy_reset(curl);
241   iwxstr_clear(xstr);
242   iwxstr_clear(hstr);
243   curl_easy_setopt(curl, CURLOPT_URL, url);
244   curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_xstr);
245   curl_easy_setopt(curl, CURLOPT_WRITEDATA, xstr);
246   curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, curl_write_xstr);
247   curl_easy_setopt(curl, CURLOPT_HEADERDATA, hstr);
248   cc = curl_easy_perform(curl);
249   CU_ASSERT_EQUAL_FATAL(cc, 0);
250   curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
251   CU_ASSERT_EQUAL_FATAL(code, 200);
252   CU_ASSERT_STRING_EQUAL(iwxstr_ptr(xstr),
253                          "{\n"
254                          " \"foo\": \"zzz\"\n"
255                          "}"
256                          );
257 
258 
259   iwxstr_destroy(xstr);
260   iwxstr_destroy(hstr);
261   curl_slist_free_all(headers);
262   rc = ejdb_close(&db);
263   CU_ASSERT_EQUAL_FATAL(rc, 0);
264 }
265 
main()266 int main() {
267   CU_pSuite pSuite = NULL;
268   if (CUE_SUCCESS != CU_initialize_registry()) {
269     return CU_get_error();
270   }
271   pSuite = CU_add_suite("jbr_test1", init_suite, clean_suite);
272   if (NULL == pSuite) {
273     CU_cleanup_registry();
274     return CU_get_error();
275   }
276   if (
277     (NULL == CU_add_test(pSuite, "jbr_test1_1", jbr_test1_1))) {
278     CU_cleanup_registry();
279     return CU_get_error();
280   }
281   CU_basic_set_mode(CU_BRM_VERBOSE);
282   CU_basic_run_tests();
283   int ret = CU_get_error() || CU_get_number_of_failures();
284   CU_cleanup_registry();
285   return ret;
286 }
287