]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | #include <errno.h> |
2 | #include <lua.hpp> | |
3 | #include "include/types.h" | |
11fdf7f2 | 4 | #include "include/rados/librados.hpp" |
7c673cae | 5 | #include "gtest/gtest.h" |
11fdf7f2 | 6 | #include "test/librados/test_cxx.h" |
7c673cae FG |
7 | #include "cls/lua/cls_lua_client.h" |
8 | #include "cls/lua/cls_lua.h" | |
9 | ||
20effc67 TL |
10 | using namespace std; |
11 | ||
7c673cae FG |
12 | /* |
13 | * JSON script to test JSON I/O protocol with cls_lua | |
14 | */ | |
15 | const std::string json_test_script = R"jsonscript( | |
16 | { | |
17 | "script": "function json_echo(input, output) output:append(input:str()); end objclass.register(json_echo)", | |
18 | "handler": "json_echo", | |
19 | "input": "omg it works", | |
20 | } | |
21 | )jsonscript"; | |
22 | ||
23 | /* | |
24 | * Lua test script thanks to the magical c++11 string literal syntax | |
25 | */ | |
26 | const std::string test_script = R"luascript( | |
27 | -- | |
28 | -- This Lua script file contains all of the handlers used in the cls_lua unit | |
29 | -- tests (src/test/cls_lua/test_cls_lua.cc). Each section header corresponds | |
30 | -- to the ClsLua.XYZ test. | |
31 | -- | |
32 | ||
33 | -- | |
34 | -- Read | |
35 | -- | |
36 | function read(input, output) | |
37 | size = objclass.stat() | |
38 | bl = objclass.read(0, size) | |
39 | output:append(bl:str()) | |
40 | end | |
41 | ||
42 | objclass.register(read) | |
43 | ||
44 | -- | |
45 | -- Write | |
46 | -- | |
47 | function write(input, output) | |
48 | objclass.write(0, #input, input) | |
49 | end | |
50 | ||
51 | objclass.register(write) | |
52 | ||
53 | -- | |
54 | -- MapGetVal | |
55 | -- | |
56 | function map_get_val_foo(input, output) | |
57 | bl = objclass.map_get_val('foo') | |
58 | output:append(bl:str()) | |
59 | end | |
60 | ||
61 | function map_get_val_dne() | |
62 | bl = objclass.map_get_val('dne') | |
63 | end | |
64 | ||
65 | objclass.register(map_get_val_foo) | |
66 | objclass.register(map_get_val_dne) | |
67 | ||
68 | -- | |
69 | -- Stat | |
70 | -- | |
71 | function stat_ret(input, output) | |
72 | size, mtime = objclass.stat() | |
73 | output:append(size .. "," .. mtime) | |
74 | end | |
75 | ||
76 | function stat_sdne() | |
77 | size, mtime = objclass.stat() | |
78 | end | |
79 | ||
80 | function stat_sdne_pcall() | |
81 | ok, ret, size, mtime = pcall(objclass.stat, o) | |
82 | assert(ok == false) | |
83 | assert(ret == -objclass.ENOENT) | |
84 | return ret | |
85 | end | |
86 | ||
87 | objclass.register(stat_ret) | |
88 | objclass.register(stat_sdne) | |
89 | objclass.register(stat_sdne_pcall) | |
90 | ||
91 | -- | |
92 | -- RetVal | |
93 | -- | |
94 | function rv_h() end | |
95 | function rv_h1() return 1; end | |
96 | function rv_h0() return 0; end | |
97 | function rv_hn1() return -1; end | |
98 | function rv_hs1() return '1'; end | |
99 | function rv_hs0() return '0'; end | |
100 | function rv_hsn1() return '-1'; end | |
101 | function rv_hnil() return nil; end | |
102 | function rv_ht() return {}; end | |
103 | function rv_hstr() return 'asdf'; end | |
104 | ||
105 | objclass.register(rv_h) | |
106 | objclass.register(rv_h1) | |
107 | objclass.register(rv_h0) | |
108 | objclass.register(rv_hn1) | |
109 | objclass.register(rv_hs1) | |
110 | objclass.register(rv_hs0) | |
111 | objclass.register(rv_hsn1) | |
112 | objclass.register(rv_hnil) | |
113 | objclass.register(rv_ht) | |
114 | objclass.register(rv_hstr) | |
115 | ||
116 | -- | |
117 | -- Create | |
118 | -- | |
119 | function create_c() objclass.create(true); end | |
120 | function create_cne() objclass.create(false); end | |
121 | ||
122 | objclass.register(create_c) | |
123 | objclass.register(create_cne) | |
124 | ||
125 | -- | |
126 | -- Pcall | |
127 | -- | |
128 | function pcall_c() objclass.create(true); end | |
129 | ||
130 | function pcall_pc() | |
131 | ok, ret = pcall(objclass.create, true) | |
132 | assert(ok == false) | |
133 | assert(ret == -objclass.EEXIST) | |
134 | end | |
135 | ||
136 | function pcall_pcr() | |
137 | ok, ret = pcall(objclass.create, true) | |
138 | assert(ok == false) | |
139 | assert(ret == -objclass.EEXIST) | |
140 | return ret | |
141 | end | |
142 | ||
143 | function pcall_pcr2() | |
144 | ok, ret = pcall(objclass.create, true) | |
145 | assert(ok == false) | |
146 | assert(ret == -objclass.EEXIST) | |
147 | ok, ret = pcall(objclass.create, true) | |
148 | assert(ok == false) | |
149 | assert(ret == -objclass.EEXIST) | |
150 | return -9999 | |
151 | end | |
152 | ||
153 | objclass.register(pcall_c) | |
154 | objclass.register(pcall_pc) | |
155 | objclass.register(pcall_pcr) | |
156 | objclass.register(pcall_pcr2) | |
157 | ||
158 | -- | |
159 | -- Remove | |
160 | -- | |
161 | function remove_c() objclass.create(true); end | |
162 | function remove_r() objclass.remove(); end | |
163 | ||
164 | objclass.register(remove_c) | |
165 | objclass.register(remove_r) | |
166 | ||
167 | -- | |
168 | -- MapSetVal | |
169 | -- | |
170 | function map_set_val(input, output) | |
171 | objclass.map_set_val('foo', input) | |
172 | end | |
173 | ||
174 | objclass.register(map_set_val) | |
175 | ||
176 | -- | |
177 | -- MapClear | |
178 | -- | |
179 | function map_clear() | |
180 | objclass.map_clear() | |
181 | end | |
182 | ||
183 | objclass.register(map_clear) | |
184 | ||
185 | -- | |
186 | -- BufferlistEquality | |
187 | -- | |
188 | function bl_eq_empty_equal(input, output) | |
189 | bl1 = bufferlist.new() | |
190 | bl2 = bufferlist.new() | |
191 | assert(bl1 == bl2) | |
192 | end | |
193 | ||
194 | function bl_eq_empty_selfequal() | |
195 | bl1 = bufferlist.new() | |
196 | assert(bl1 == bl1) | |
197 | end | |
198 | ||
199 | function bl_eq_selfequal() | |
200 | bl1 = bufferlist.new() | |
201 | bl1:append('asdf') | |
202 | assert(bl1 == bl1) | |
203 | end | |
204 | ||
205 | function bl_eq_equal() | |
206 | bl1 = bufferlist.new() | |
207 | bl2 = bufferlist.new() | |
208 | bl1:append('abc') | |
209 | bl2:append('abc') | |
210 | assert(bl1 == bl2) | |
211 | end | |
212 | ||
213 | function bl_eq_notequal() | |
214 | bl1 = bufferlist.new() | |
215 | bl2 = bufferlist.new() | |
216 | bl1:append('abc') | |
217 | bl2:append('abcd') | |
218 | assert(bl1 ~= bl2) | |
219 | end | |
220 | ||
221 | objclass.register(bl_eq_empty_equal) | |
222 | objclass.register(bl_eq_empty_selfequal) | |
223 | objclass.register(bl_eq_selfequal) | |
224 | objclass.register(bl_eq_equal) | |
225 | objclass.register(bl_eq_notequal) | |
226 | ||
227 | -- | |
228 | -- Bufferlist Compare | |
229 | -- | |
230 | function bl_lt() | |
231 | local a = bufferlist.new() | |
232 | local b = bufferlist.new() | |
233 | a:append('A') | |
234 | b:append('B') | |
235 | assert(a < b) | |
236 | end | |
237 | ||
238 | function bl_le() | |
239 | local a = bufferlist.new() | |
240 | local b = bufferlist.new() | |
241 | a:append('A') | |
242 | b:append('B') | |
243 | assert(a <= b) | |
244 | end | |
245 | ||
246 | objclass.register(bl_lt) | |
247 | objclass.register(bl_le) | |
248 | ||
249 | -- | |
250 | -- Bufferlist concat | |
251 | -- | |
252 | function bl_concat_eq() | |
253 | local a = bufferlist.new() | |
254 | local b = bufferlist.new() | |
255 | local ab = bufferlist.new() | |
256 | a:append('A') | |
257 | b:append('B') | |
258 | ab:append('AB') | |
259 | assert(a .. b == ab) | |
260 | end | |
261 | ||
262 | function bl_concat_ne() | |
263 | local a = bufferlist.new() | |
264 | local b = bufferlist.new() | |
265 | local ab = bufferlist.new() | |
266 | a:append('A') | |
267 | b:append('B') | |
268 | ab:append('AB') | |
269 | assert(b .. a ~= ab) | |
270 | end | |
271 | ||
272 | function bl_concat_immut() | |
273 | local a = bufferlist.new() | |
274 | local b = bufferlist.new() | |
275 | local ab = bufferlist.new() | |
276 | a:append('A') | |
277 | b:append('B') | |
278 | ab:append('AB') | |
279 | x = a .. b | |
280 | assert(x == ab) | |
281 | b:append('C') | |
282 | assert(x == ab) | |
283 | local bc = bufferlist.new() | |
284 | bc:append('BC') | |
285 | assert(b == bc) | |
286 | end | |
287 | ||
288 | objclass.register(bl_concat_eq) | |
289 | objclass.register(bl_concat_ne) | |
290 | objclass.register(bl_concat_immut) | |
291 | ||
292 | -- | |
293 | -- RunError | |
294 | -- | |
295 | function runerr_a() | |
9f95a23c | 296 | error('error_a') |
7c673cae FG |
297 | end |
298 | ||
299 | function runerr_b() | |
300 | runerr_a() | |
301 | end | |
302 | ||
303 | function runerr_c() | |
304 | runerr_b() | |
305 | end | |
306 | ||
307 | -- only runerr_c is called | |
308 | objclass.register(runerr_c) | |
309 | ||
310 | -- | |
311 | -- GetXattr | |
312 | -- | |
313 | function getxattr(input, output) | |
314 | bl = objclass.getxattr("fooz") | |
315 | output:append(bl:str()) | |
316 | end | |
317 | ||
318 | objclass.register(getxattr) | |
319 | ||
320 | -- | |
321 | -- SetXattr | |
322 | -- | |
323 | function setxattr(input, output) | |
324 | objclass.setxattr("fooz2", input) | |
325 | end | |
326 | ||
327 | objclass.register(setxattr) | |
328 | ||
329 | -- | |
330 | -- WriteFull | |
331 | -- | |
332 | function write_full(input, output) | |
333 | objclass.write_full(input) | |
334 | end | |
335 | ||
336 | objclass.register(write_full) | |
337 | ||
338 | -- | |
339 | -- GetXattrs | |
340 | -- | |
341 | function getxattrs(input, output) | |
342 | -- result | |
343 | xattrs = objclass.getxattrs() | |
344 | ||
345 | -- sort for determisitic test | |
346 | arr = {} | |
347 | for n in pairs(xattrs) do | |
348 | table.insert(arr, n) | |
349 | end | |
350 | table.sort(arr) | |
351 | ||
352 | output_str = "" | |
353 | for i,key in ipairs(arr) do | |
354 | output_str = output_str .. key .. "/" .. xattrs[key]:str() .. "/" | |
355 | end | |
356 | output:append(output_str) | |
357 | end | |
358 | ||
359 | objclass.register(getxattrs) | |
360 | ||
361 | -- | |
362 | -- MapGetKeys | |
363 | -- | |
364 | function map_get_keys(input, output) | |
365 | -- result | |
366 | keys = objclass.map_get_keys("", 5) | |
367 | ||
368 | -- sort for determisitic test | |
369 | arr = {} | |
370 | for n in pairs(keys) do | |
371 | table.insert(arr, n) | |
372 | end | |
373 | table.sort(arr) | |
374 | ||
375 | output_str = "" | |
376 | for i,key in ipairs(arr) do | |
377 | output_str = output_str .. key .. "/" | |
378 | end | |
379 | ||
380 | output:append(output_str) | |
381 | end | |
382 | ||
383 | objclass.register(map_get_keys) | |
384 | ||
385 | -- | |
386 | -- MapGetVals | |
387 | -- | |
388 | function map_get_vals(input, output) | |
389 | -- result | |
390 | kvs = objclass.map_get_vals("", "", 10) | |
391 | ||
392 | -- sort for determisitic test | |
393 | arr = {} | |
394 | for n in pairs(kvs) do | |
395 | table.insert(arr, n) | |
396 | end | |
397 | table.sort(arr) | |
398 | ||
399 | output_str = "" | |
400 | for i,key in ipairs(arr) do | |
401 | output_str = output_str .. key .. "/" .. kvs[key]:str() .. "/" | |
402 | end | |
403 | output:append(output_str) | |
404 | end | |
405 | ||
406 | objclass.register(map_get_vals) | |
407 | ||
408 | -- | |
409 | -- MapHeader (write) | |
410 | -- | |
411 | function map_write_header(input, output) | |
412 | objclass.map_write_header(input) | |
413 | end | |
414 | ||
415 | objclass.register(map_write_header) | |
416 | ||
417 | -- | |
418 | -- MapHeader (read) | |
419 | -- | |
420 | function map_read_header(input, output) | |
421 | hdr = objclass.map_read_header() | |
422 | output:append(hdr:str()) | |
423 | end | |
424 | ||
425 | objclass.register(map_read_header) | |
426 | ||
427 | -- | |
428 | -- MapSetVals | |
429 | -- | |
430 | function map_set_vals_empty(input, output) | |
431 | record = {} | |
432 | objclass.map_set_vals(record) | |
433 | end | |
434 | ||
435 | function map_set_vals_one(input, output) | |
436 | record = { | |
437 | a = "a_val" | |
438 | } | |
439 | objclass.map_set_vals(record) | |
440 | end | |
441 | ||
442 | function map_set_vals_two(input, output) | |
443 | record = { | |
444 | a = "a_val", | |
445 | b = "b_val" | |
446 | } | |
447 | objclass.map_set_vals(record) | |
448 | end | |
449 | ||
450 | function map_set_vals_three(input, output) | |
451 | record = { | |
452 | a = "a_val", | |
453 | b = "b_val", | |
454 | c = "c_val" | |
455 | } | |
456 | objclass.map_set_vals(record) | |
457 | end | |
458 | ||
459 | function map_set_vals_array(input, output) | |
460 | array = {} | |
461 | array[1] = "1_val" | |
462 | array[2] = "2_val" | |
463 | objclass.map_set_vals(array) | |
464 | end | |
465 | ||
466 | function map_set_vals_mixed(input, output) | |
467 | record = { | |
468 | a = "a_val", | |
469 | b = "b_val" | |
470 | } | |
471 | record[1] = "1_val" | |
472 | record[2] = "2_val" | |
473 | objclass.map_set_vals(record) | |
474 | end | |
475 | ||
476 | function map_set_vals_bad_val(input, output) | |
477 | record = { | |
478 | a = {} | |
479 | } | |
480 | objclass.map_set_vals(record) | |
481 | end | |
482 | ||
483 | objclass.register(map_set_vals_empty) | |
484 | objclass.register(map_set_vals_one) | |
485 | objclass.register(map_set_vals_two) | |
486 | objclass.register(map_set_vals_three) | |
487 | objclass.register(map_set_vals_array) | |
488 | objclass.register(map_set_vals_mixed) | |
489 | objclass.register(map_set_vals_bad_val) | |
490 | ||
491 | -- | |
492 | -- MapRemoveKey | |
493 | -- | |
494 | function map_remove_key(input, output) | |
495 | objclass.map_remove_key("a") | |
496 | end | |
497 | ||
498 | objclass.register(map_remove_key) | |
499 | ||
500 | -- | |
501 | -- Version/Subop | |
502 | -- | |
503 | function current_version(input, output) | |
504 | ret = objclass.current_version() | |
505 | output:append("" .. ret) | |
506 | objclass.log(0, ret) | |
507 | end | |
508 | ||
509 | function current_subop_num(input, output) | |
510 | ret = objclass.current_subop_num() | |
511 | output:append("" .. ret) | |
512 | objclass.log(0, ret) | |
513 | end | |
514 | ||
515 | function current_subop_version(input, output) | |
516 | ret = objclass.current_subop_version() | |
517 | output:append("" .. ret) | |
518 | objclass.log(0, ret) | |
519 | end | |
520 | ||
521 | objclass.register(current_version) | |
522 | objclass.register(current_subop_num) | |
523 | objclass.register(current_subop_version) | |
524 | ||
525 | )luascript"; | |
526 | ||
527 | /* | |
528 | * Test harness uses single pool for the entire test case, and generates | |
529 | * unique object names for each test. | |
530 | */ | |
531 | class ClsLua : public ::testing::Test { | |
532 | protected: | |
533 | static void SetUpTestCase() { | |
534 | pool_name = get_temp_pool_name(); | |
535 | ASSERT_EQ("", create_one_pool_pp(pool_name, rados)); | |
536 | ASSERT_EQ(0, rados.ioctx_create(pool_name.c_str(), ioctx)); | |
537 | } | |
538 | ||
539 | static void TearDownTestCase() { | |
540 | ioctx.close(); | |
541 | ASSERT_EQ(0, destroy_one_pool_pp(pool_name, rados)); | |
542 | } | |
543 | ||
544 | void SetUp() override { | |
545 | /* Grab test names to build unique objects */ | |
546 | const ::testing::TestInfo* const test_info = | |
547 | ::testing::UnitTest::GetInstance()->current_test_info(); | |
548 | ||
549 | /* Create unique string using test/testname/pid */ | |
550 | std::stringstream ss_oid; | |
551 | ss_oid << test_info->test_case_name() << "_" << | |
552 | test_info->name() << "_" << getpid(); | |
553 | ||
554 | /* Unique object for test to use */ | |
555 | oid = ss_oid.str(); | |
556 | } | |
557 | ||
558 | void TearDown() override { | |
559 | } | |
560 | ||
561 | /* | |
562 | * Helper function. This functionality should eventually make its way into | |
563 | * a clslua client library of some sort. | |
564 | */ | |
565 | int __clslua_exec(const string& oid, const string& script, | |
566 | librados::bufferlist *input = NULL, const string& funcname = "") | |
567 | { | |
568 | bufferlist inbl; | |
569 | if (input) | |
570 | inbl = *input; | |
571 | ||
572 | reply_output.clear(); | |
573 | ||
574 | return cls_lua_client::exec(ioctx, oid, script, funcname, inbl, | |
575 | reply_output); | |
576 | } | |
577 | ||
578 | int clslua_exec(const string& script, librados::bufferlist *input = NULL, | |
579 | const string& funcname = "") | |
580 | { | |
581 | return __clslua_exec(oid, script, input, funcname); | |
582 | } | |
583 | ||
584 | static librados::Rados rados; | |
585 | static librados::IoCtx ioctx; | |
586 | static string pool_name; | |
587 | ||
588 | string oid; | |
589 | bufferlist reply_output; | |
590 | }; | |
591 | ||
592 | librados::Rados ClsLua::rados; | |
593 | librados::IoCtx ClsLua::ioctx; | |
594 | string ClsLua::pool_name; | |
595 | ||
596 | TEST_F(ClsLua, Write) { | |
597 | /* write some data into object */ | |
598 | string written = "Hello World"; | |
599 | bufferlist inbl; | |
11fdf7f2 | 600 | encode(written, inbl); |
7c673cae FG |
601 | ASSERT_EQ(0, clslua_exec(test_script, &inbl, "write")); |
602 | ||
603 | /* have Lua read out of the object */ | |
604 | uint64_t size; | |
605 | bufferlist outbl; | |
606 | ASSERT_EQ(0, ioctx.stat(oid, &size, NULL)); | |
607 | ASSERT_EQ(size, (uint64_t)ioctx.read(oid, outbl, size, 0) ); | |
608 | ||
609 | /* compare what Lua read to what we wrote */ | |
610 | string read; | |
11fdf7f2 | 611 | decode(read, outbl); |
7c673cae FG |
612 | ASSERT_EQ(read, written); |
613 | } | |
614 | ||
615 | TEST_F(ClsLua, SyntaxError) { | |
616 | ASSERT_EQ(-EIO, clslua_exec("-")); | |
617 | } | |
618 | ||
619 | TEST_F(ClsLua, EmptyScript) { | |
620 | ASSERT_EQ(0, clslua_exec("")); | |
621 | } | |
622 | ||
623 | TEST_F(ClsLua, RetVal) { | |
624 | /* handlers can return numeric values */ | |
625 | ASSERT_EQ(1, clslua_exec(test_script, NULL, "rv_h1")); | |
626 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "rv_h0")); | |
627 | ASSERT_EQ(-1, clslua_exec(test_script, NULL, "rv_hn1")); | |
628 | ASSERT_EQ(1, clslua_exec(test_script, NULL, "rv_hs1")); | |
629 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "rv_hs0")); | |
630 | ASSERT_EQ(-1, clslua_exec(test_script, NULL, "rv_hsn1")); | |
631 | ||
632 | /* no return value is success */ | |
633 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "rv_h")); | |
634 | ||
635 | /* non-numeric return values are errors */ | |
636 | ASSERT_EQ(-EIO, clslua_exec(test_script, NULL, "rv_hnil")); | |
637 | ASSERT_EQ(-EIO, clslua_exec(test_script, NULL, "rv_ht")); | |
638 | ASSERT_EQ(-EIO, clslua_exec(test_script, NULL, "rv_hstr")); | |
639 | } | |
640 | ||
641 | TEST_F(ClsLua, Create) { | |
642 | /* create works */ | |
643 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "create_c")); | |
644 | ||
645 | /* exclusive works */ | |
646 | ASSERT_EQ(-EEXIST, clslua_exec(test_script, NULL, "create_c")); | |
647 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "create_cne")); | |
648 | } | |
649 | ||
650 | TEST_F(ClsLua, Pcall) { | |
651 | /* create and error works */ | |
652 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "pcall_c")); | |
653 | ASSERT_EQ(-EEXIST, clslua_exec(test_script, NULL, "pcall_c")); | |
654 | ||
655 | /* pcall masks the error */ | |
656 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "pcall_pc")); | |
657 | ||
658 | /* pcall lets us get the failed return value */ | |
659 | ASSERT_EQ(-EEXIST, clslua_exec(test_script, NULL, "pcall_pcr")); | |
660 | ||
661 | /* | |
662 | * the first call in pcr2 will fail (check ret != 0), and the second pcall | |
663 | * should also fail (we check with a bogus return value to mask real | |
664 | * errors). This is also an important check for our error handling because | |
665 | * we need a case where two functions in the same handler fail to exercise | |
666 | * our internal error book keeping. | |
667 | */ | |
668 | ASSERT_EQ(-9999, clslua_exec(test_script, NULL, "pcall_pcr2")); | |
669 | } | |
670 | ||
671 | TEST_F(ClsLua, Remove) { | |
672 | /* object doesn't exist */ | |
673 | ASSERT_EQ(-ENOENT, clslua_exec(test_script, NULL, "remove_r")); | |
674 | ||
675 | /* can remove */ | |
676 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "remove_c")); | |
677 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "remove_r")); | |
678 | ASSERT_EQ(-ENOENT, clslua_exec(test_script, NULL, "remove_r")); | |
679 | } | |
680 | ||
681 | TEST_F(ClsLua, Stat) { | |
682 | /* build object and stat */ | |
1e59de90 | 683 | char buf[1024] = {}; |
7c673cae FG |
684 | bufferlist bl; |
685 | bl.append(buf, sizeof(buf)); | |
686 | ASSERT_EQ(0, ioctx.write_full(oid, bl)); | |
687 | uint64_t size; | |
688 | time_t mtime; | |
689 | ASSERT_EQ(0, ioctx.stat(oid, &size, &mtime)); | |
690 | ||
691 | /* test stat success */ | |
692 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "stat_ret")); | |
693 | ||
694 | // size,mtime from ioctx call | |
695 | std::stringstream s1; | |
696 | s1 << size << "," << mtime; | |
697 | ||
698 | // lua constructed size,mtime string | |
699 | std::string s2(reply_output.c_str(), reply_output.length()); | |
700 | ||
701 | ASSERT_EQ(s1.str(), s2); | |
702 | ||
703 | /* test object dne */ | |
704 | ASSERT_EQ(-ENOENT, __clslua_exec("dne", test_script, NULL, "stat_sdne")); | |
705 | ||
706 | /* can capture error with pcall */ | |
707 | ASSERT_EQ(-ENOENT, __clslua_exec("dne", test_script, NULL, "stat_sdne_pcall")); | |
708 | } | |
709 | ||
710 | TEST_F(ClsLua, MapClear) { | |
711 | /* write some data into a key */ | |
712 | string msg = "This is a test message"; | |
713 | bufferlist val; | |
714 | val.append(msg.c_str(), msg.size()); | |
715 | map<string, bufferlist> map; | |
716 | map["foo"] = val; | |
717 | ASSERT_EQ(0, ioctx.omap_set(oid, map)); | |
718 | ||
719 | /* test we can get it back out */ | |
720 | set<string> keys; | |
721 | keys.insert("foo"); | |
722 | map.clear(); | |
723 | ASSERT_EQ(0, (int)map.count("foo")); | |
724 | ASSERT_EQ(0, ioctx.omap_get_vals_by_keys(oid, keys, &map)); | |
725 | ASSERT_EQ(1, (int)map.count("foo")); | |
726 | ||
727 | /* now clear it */ | |
728 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "map_clear")); | |
729 | ||
730 | /* test that the map we get back is empty now */ | |
731 | map.clear(); | |
732 | ASSERT_EQ(0, (int)map.count("foo")); | |
733 | ASSERT_EQ(0, ioctx.omap_get_vals_by_keys(oid, keys, &map)); | |
734 | ASSERT_EQ(0, (int)map.count("foo")); | |
735 | } | |
736 | ||
737 | TEST_F(ClsLua, MapSetVal) { | |
738 | /* build some input value */ | |
739 | bufferlist orig_val; | |
11fdf7f2 | 740 | encode("this is the original value yay", orig_val); |
7c673cae FG |
741 | |
742 | /* have the lua script stuff the data into a map value */ | |
743 | ASSERT_EQ(0, clslua_exec(test_script, &orig_val, "map_set_val")); | |
744 | ||
745 | /* grap the key now and compare to orig */ | |
746 | map<string, bufferlist> out_map; | |
747 | set<string> out_keys; | |
748 | out_keys.insert("foo"); | |
749 | ASSERT_EQ(0, ioctx.omap_get_vals_by_keys(oid, out_keys, &out_map)); | |
750 | bufferlist out_bl = out_map["foo"]; | |
751 | string out_val; | |
11fdf7f2 | 752 | decode(out_val, out_bl); |
7c673cae FG |
753 | ASSERT_EQ(out_val, "this is the original value yay"); |
754 | } | |
755 | ||
756 | TEST_F(ClsLua, MapGetVal) { | |
757 | /* write some data into a key */ | |
758 | string msg = "This is a test message"; | |
759 | bufferlist orig_val; | |
760 | orig_val.append(msg.c_str(), msg.size()); | |
761 | map<string, bufferlist> orig_map; | |
762 | orig_map["foo"] = orig_val; | |
763 | ASSERT_EQ(0, ioctx.omap_set(oid, orig_map)); | |
764 | ||
765 | /* now compare to what we put it */ | |
766 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "map_get_val_foo")); | |
767 | ||
768 | /* check return */ | |
769 | string ret_val; | |
770 | ret_val.assign(reply_output.c_str(), reply_output.length()); | |
771 | ASSERT_EQ(ret_val, msg); | |
772 | ||
773 | /* error case */ | |
774 | ASSERT_EQ(-ENOENT, clslua_exec(test_script, NULL, "map_get_val_dne")); | |
775 | } | |
776 | ||
777 | TEST_F(ClsLua, Read) { | |
778 | /* put data into object */ | |
779 | string msg = "This is a test message"; | |
780 | bufferlist bl; | |
781 | bl.append(msg.c_str(), msg.size()); | |
782 | ASSERT_EQ(0, ioctx.write_full(oid, bl)); | |
783 | ||
784 | /* get lua to read it and send it back */ | |
785 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "read")); | |
786 | ||
787 | /* check return */ | |
788 | string ret_val; | |
789 | ret_val.assign(reply_output.c_str(), reply_output.length()); | |
790 | ASSERT_EQ(ret_val, msg); | |
791 | } | |
792 | ||
793 | TEST_F(ClsLua, Log) { | |
794 | ASSERT_EQ(0, clslua_exec("objclass.log()")); | |
795 | ASSERT_EQ(0, clslua_exec("s = objclass.log(); objclass.log(s);")); | |
796 | ASSERT_EQ(0, clslua_exec("objclass.log(1)")); | |
797 | ASSERT_EQ(0, clslua_exec("objclass.log(-1)")); | |
798 | ASSERT_EQ(0, clslua_exec("objclass.log('x')")); | |
799 | ASSERT_EQ(0, clslua_exec("objclass.log(0, 0)")); | |
800 | ASSERT_EQ(0, clslua_exec("objclass.log(1, 1)")); | |
801 | ASSERT_EQ(0, clslua_exec("objclass.log(-10, -10)")); | |
802 | ASSERT_EQ(0, clslua_exec("objclass.log('x', 'y')")); | |
803 | ASSERT_EQ(0, clslua_exec("objclass.log(1, 'one')")); | |
804 | ASSERT_EQ(0, clslua_exec("objclass.log(1, 'one', 'two')")); | |
805 | ASSERT_EQ(0, clslua_exec("objclass.log('one', 'two', 'three')")); | |
806 | ASSERT_EQ(0, clslua_exec("s = objclass.log('one', 'two', 'three'); objclass.log(s);")); | |
807 | } | |
808 | ||
809 | TEST_F(ClsLua, BufferlistEquality) { | |
810 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "bl_eq_empty_equal")); | |
811 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "bl_eq_empty_selfequal")); | |
812 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "bl_eq_selfequal")); | |
813 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "bl_eq_equal")); | |
814 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "bl_eq_notequal")); | |
815 | } | |
816 | ||
817 | TEST_F(ClsLua, RunError) { | |
818 | ASSERT_EQ(-EIO, clslua_exec(test_script, NULL, "runerr_c")); | |
819 | } | |
820 | ||
821 | TEST_F(ClsLua, HandleNotFunc) { | |
822 | string script = "x = 1;"; | |
823 | ASSERT_EQ(-EOPNOTSUPP, clslua_exec(script, NULL, "x")); | |
824 | } | |
825 | ||
826 | TEST_F(ClsLua, Register) { | |
827 | /* normal cases: register and maybe call the handler */ | |
828 | string script = "function h() end; objclass.register(h);"; | |
829 | ASSERT_EQ(0, clslua_exec(script, NULL, "")); | |
830 | ASSERT_EQ(0, clslua_exec(script, NULL, "h")); | |
831 | ||
832 | /* can register and call multiple handlers */ | |
833 | script = "function h1() end; function h2() end;" | |
834 | "objclass.register(h1); objclass.register(h2);"; | |
835 | ASSERT_EQ(0, clslua_exec(script, NULL, "")); | |
836 | ASSERT_EQ(0, clslua_exec(script, NULL, "h1")); | |
837 | ASSERT_EQ(0, clslua_exec(script, NULL, "h2")); | |
838 | ||
839 | /* normal cases: register before function is defined */ | |
840 | script = "objclass.register(h); function h() end;"; | |
841 | ASSERT_EQ(-EIO, clslua_exec(script, NULL, "")); | |
842 | ASSERT_EQ(-EIO, clslua_exec(script, NULL, "h")); | |
843 | ||
844 | /* cannot call handler that isn't registered */ | |
845 | script = "function h() end;"; | |
846 | ASSERT_EQ(-EIO, clslua_exec(script, NULL, "h")); | |
847 | ||
848 | /* handler doesn't exist */ | |
849 | script = "objclass.register(lalala);"; | |
850 | ASSERT_EQ(-EIO, clslua_exec(script, NULL, "")); | |
851 | ||
852 | /* handler isn't a function */ | |
853 | script = "objclass.register('some string');"; | |
854 | ASSERT_EQ(-EIO, clslua_exec(script, NULL, "")); | |
855 | ||
856 | /* cannot register handler multiple times */ | |
857 | script = "function h() end; objclass.register(h); objclass.register(h);"; | |
858 | ASSERT_EQ(-EIO, clslua_exec(script, NULL, "")); | |
859 | } | |
860 | ||
861 | TEST_F(ClsLua, BufferlistCompare) { | |
862 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "bl_lt")); | |
863 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "bl_le")); | |
864 | } | |
865 | ||
866 | TEST_F(ClsLua, BufferlistConcat) { | |
867 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "bl_concat_eq")); | |
868 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "bl_concat_ne")); | |
869 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "bl_concat_immut")); | |
870 | } | |
871 | ||
872 | TEST_F(ClsLua, GetXattr) { | |
873 | bufferlist bl; | |
874 | bl.append("blahblahblahblahblah"); | |
875 | ASSERT_EQ(0, ioctx.setxattr(oid, "fooz", bl)); | |
876 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "getxattr")); | |
877 | ASSERT_TRUE(reply_output == bl); | |
878 | } | |
879 | ||
880 | TEST_F(ClsLua, SetXattr) { | |
881 | bufferlist inbl; | |
882 | inbl.append("blahblahblahblahblah"); | |
883 | ASSERT_EQ(0, clslua_exec(test_script, &inbl, "setxattr")); | |
884 | bufferlist outbl; | |
885 | ASSERT_EQ((int)inbl.length(), ioctx.getxattr(oid, "fooz2", outbl)); | |
886 | ASSERT_TRUE(outbl == inbl); | |
887 | } | |
888 | ||
889 | TEST_F(ClsLua, WriteFull) { | |
890 | // write some data | |
1e59de90 | 891 | char buf[1024] = {}; |
7c673cae FG |
892 | bufferlist blin; |
893 | blin.append(buf, sizeof(buf)); | |
894 | ASSERT_EQ(0, ioctx.write(oid, blin, blin.length(), 0)); | |
895 | bufferlist blout; | |
896 | ASSERT_EQ((int)blin.length(), ioctx.read(oid, blout, 0, 0)); | |
897 | ASSERT_EQ(blin, blout); | |
898 | ||
899 | // execute write_full from lua | |
900 | blin.clear(); | |
901 | char buf2[200]; | |
902 | sprintf(buf2, "%s", "data replacing content"); | |
903 | blin.append(buf2, sizeof(buf2)); | |
904 | ASSERT_EQ(0, clslua_exec(test_script, &blin, "write_full")); | |
905 | ||
906 | // read it back | |
907 | blout.clear(); | |
908 | ASSERT_EQ((int)blin.length(), ioctx.read(oid, blout, 0, 0)); | |
909 | ASSERT_EQ(blin, blout); | |
910 | } | |
911 | ||
912 | TEST_F(ClsLua, GetXattrs) { | |
913 | ASSERT_EQ(0, ioctx.create(oid, false)); | |
914 | ||
915 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "getxattrs")); | |
916 | ASSERT_EQ(0, (int)reply_output.length()); | |
917 | ||
918 | string key1str("key1str"); | |
919 | bufferlist key1bl; | |
920 | key1bl.append(key1str); | |
921 | ASSERT_EQ(0, ioctx.setxattr(oid, "key1", key1bl)); | |
922 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "getxattrs")); | |
923 | string out1(reply_output.c_str(), reply_output.length()); // add the trailing \0 | |
924 | ASSERT_STREQ(out1.c_str(), "key1/key1str/"); | |
925 | ||
926 | string key2str("key2str"); | |
927 | bufferlist key2bl; | |
928 | key2bl.append(key2str); | |
929 | ASSERT_EQ(0, ioctx.setxattr(oid, "key2", key2bl)); | |
930 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "getxattrs")); | |
931 | string out2(reply_output.c_str(), reply_output.length()); // add the trailing \0 | |
932 | ASSERT_STREQ(out2.c_str(), "key1/key1str/key2/key2str/"); | |
933 | ||
934 | string key3str("key3str"); | |
935 | bufferlist key3bl; | |
936 | key3bl.append(key3str); | |
937 | ASSERT_EQ(0, ioctx.setxattr(oid, "key3", key3bl)); | |
938 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "getxattrs")); | |
939 | string out3(reply_output.c_str(), reply_output.length()); // add the trailing \0 | |
940 | ASSERT_STREQ(out3.c_str(), "key1/key1str/key2/key2str/key3/key3str/"); | |
941 | } | |
942 | ||
943 | TEST_F(ClsLua, MapGetKeys) { | |
944 | ASSERT_EQ(0, ioctx.create(oid, false)); | |
945 | ||
946 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "map_get_keys")); | |
947 | ASSERT_EQ(0, (int)reply_output.length()); | |
948 | ||
949 | map<string, bufferlist> kvpairs; | |
950 | ||
951 | kvpairs["k1"] = bufferlist(); | |
952 | ASSERT_EQ(0, ioctx.omap_set(oid, kvpairs)); | |
953 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "map_get_keys")); | |
954 | string out1(reply_output.c_str(), reply_output.length()); // add the trailing \0 | |
955 | ASSERT_STREQ(out1.c_str(), "k1/"); | |
956 | ||
957 | kvpairs["k2"] = bufferlist(); | |
958 | ASSERT_EQ(0, ioctx.omap_set(oid, kvpairs)); | |
959 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "map_get_keys")); | |
960 | string out2(reply_output.c_str(), reply_output.length()); // add the trailing \0 | |
961 | ASSERT_STREQ(out2.c_str(), "k1/k2/"); | |
962 | ||
963 | kvpairs["xxx"] = bufferlist(); | |
964 | ASSERT_EQ(0, ioctx.omap_set(oid, kvpairs)); | |
965 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "map_get_keys")); | |
966 | string out3(reply_output.c_str(), reply_output.length()); // add the trailing \0 | |
967 | ASSERT_STREQ(out3.c_str(), "k1/k2/xxx/"); | |
968 | } | |
969 | ||
970 | TEST_F(ClsLua, MapGetVals) { | |
971 | ASSERT_EQ(0, ioctx.create(oid, false)); | |
972 | ||
973 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "map_get_vals")); | |
974 | ASSERT_EQ(0, (int)reply_output.length()); | |
975 | ||
976 | map<string, bufferlist> kvpairs; | |
977 | ||
978 | kvpairs["key1"] = bufferlist(); | |
979 | kvpairs["key1"].append(string("key1str")); | |
980 | ASSERT_EQ(0, ioctx.omap_set(oid, kvpairs)); | |
981 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "map_get_vals")); | |
982 | string out1(reply_output.c_str(), reply_output.length()); // add the trailing \0 | |
983 | ASSERT_STREQ(out1.c_str(), "key1/key1str/"); | |
984 | ||
985 | kvpairs["key2"] = bufferlist(); | |
986 | kvpairs["key2"].append(string("key2str")); | |
987 | ASSERT_EQ(0, ioctx.omap_set(oid, kvpairs)); | |
988 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "map_get_vals")); | |
989 | string out2(reply_output.c_str(), reply_output.length()); // add the trailing \0 | |
990 | ASSERT_STREQ(out2.c_str(), "key1/key1str/key2/key2str/"); | |
991 | ||
992 | kvpairs["key3"] = bufferlist(); | |
993 | kvpairs["key3"].append(string("key3str")); | |
994 | ASSERT_EQ(0, ioctx.omap_set(oid, kvpairs)); | |
995 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "map_get_vals")); | |
996 | string out3(reply_output.c_str(), reply_output.length()); // add the trailing \0 | |
997 | ASSERT_STREQ(out3.c_str(), "key1/key1str/key2/key2str/key3/key3str/"); | |
998 | } | |
999 | ||
1000 | TEST_F(ClsLua, MapHeader) { | |
1001 | ASSERT_EQ(0, ioctx.create(oid, false)); | |
1002 | ||
1003 | bufferlist bl_out; | |
1004 | ASSERT_EQ(0, ioctx.omap_get_header(oid, &bl_out)); | |
1005 | ASSERT_EQ(0, (int)bl_out.length()); | |
1006 | ||
1007 | std::string val("this is a value"); | |
1008 | bufferlist hdr; | |
1009 | hdr.append(val); | |
1010 | ||
1011 | ASSERT_EQ(0, clslua_exec(test_script, &hdr, "map_write_header")); | |
1012 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "map_read_header")); | |
1013 | ||
1014 | ASSERT_EQ(reply_output, hdr); | |
1015 | } | |
1016 | ||
1017 | TEST_F(ClsLua, MapSetVals) { | |
1018 | ASSERT_EQ(0, ioctx.create(oid, false)); | |
1019 | ||
1020 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "map_set_vals_empty")); | |
1021 | ||
1022 | std::map<string, bufferlist> out_vals; | |
1023 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "map_set_vals_one")); | |
1024 | ASSERT_EQ(0, ioctx.omap_get_vals(oid, "", 100, &out_vals)); | |
1025 | ASSERT_EQ(1, (int)out_vals.size()); | |
1026 | ASSERT_STREQ("a_val", std::string(out_vals["a"].c_str(), out_vals["a"].length()).c_str()); | |
1027 | ||
1028 | out_vals.clear(); | |
1029 | ASSERT_EQ(0, ioctx.omap_clear(oid)); | |
1030 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "map_set_vals_two")); | |
1031 | ASSERT_EQ(0, ioctx.omap_get_vals(oid, "", 100, &out_vals)); | |
1032 | ASSERT_EQ(2, (int)out_vals.size()); | |
1033 | ASSERT_STREQ("a_val", std::string(out_vals["a"].c_str(), out_vals["a"].length()).c_str()); | |
1034 | ASSERT_STREQ("b_val", std::string(out_vals["b"].c_str(), out_vals["b"].length()).c_str()); | |
1035 | ||
1036 | out_vals.clear(); | |
1037 | ASSERT_EQ(0, ioctx.omap_clear(oid)); | |
1038 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "map_set_vals_three")); | |
1039 | ASSERT_EQ(0, ioctx.omap_get_vals(oid, "", 100, &out_vals)); | |
1040 | ASSERT_EQ(3, (int)out_vals.size()); | |
1041 | ASSERT_STREQ("a_val", std::string(out_vals["a"].c_str(), out_vals["a"].length()).c_str()); | |
1042 | ASSERT_STREQ("b_val", std::string(out_vals["b"].c_str(), out_vals["b"].length()).c_str()); | |
1043 | ASSERT_STREQ("c_val", std::string(out_vals["c"].c_str(), out_vals["c"].length()).c_str()); | |
1044 | ||
1045 | out_vals.clear(); | |
1046 | ASSERT_EQ(0, ioctx.omap_clear(oid)); | |
1047 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "map_set_vals_array")); | |
1048 | ASSERT_EQ(0, ioctx.omap_get_vals(oid, "", 100, &out_vals)); | |
1049 | ASSERT_EQ(2, (int)out_vals.size()); | |
1050 | ASSERT_STREQ("1_val", std::string(out_vals["1"].c_str(), out_vals["1"].length()).c_str()); | |
1051 | ASSERT_STREQ("2_val", std::string(out_vals["2"].c_str(), out_vals["2"].length()).c_str()); | |
1052 | ||
1053 | out_vals.clear(); | |
1054 | ASSERT_EQ(0, ioctx.omap_clear(oid)); | |
1055 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "map_set_vals_mixed")); | |
1056 | ASSERT_EQ(0, ioctx.omap_get_vals(oid, "", 100, &out_vals)); | |
1057 | ASSERT_EQ(4, (int)out_vals.size()); | |
1058 | ASSERT_STREQ("a_val", std::string(out_vals["a"].c_str(), out_vals["a"].length()).c_str()); | |
1059 | ASSERT_STREQ("b_val", std::string(out_vals["b"].c_str(), out_vals["b"].length()).c_str()); | |
1060 | ASSERT_STREQ("1_val", std::string(out_vals["1"].c_str(), out_vals["1"].length()).c_str()); | |
1061 | ASSERT_STREQ("2_val", std::string(out_vals["2"].c_str(), out_vals["2"].length()).c_str()); | |
1062 | ||
1063 | ASSERT_EQ(-EINVAL, clslua_exec(test_script, NULL, "map_set_vals_bad_val")); | |
1064 | } | |
1065 | ||
1066 | TEST_F(ClsLua, MapRemoveKey) { | |
1067 | ASSERT_EQ(0, ioctx.create(oid, false)); | |
1068 | ||
1069 | std::map<string, bufferlist> out_vals; | |
1070 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "map_set_vals_two")); | |
1071 | ASSERT_EQ(0, ioctx.omap_get_vals(oid, "", 100, &out_vals)); | |
1072 | ASSERT_EQ(2, (int)out_vals.size()); | |
1073 | ASSERT_STREQ("a_val", std::string(out_vals["a"].c_str(), out_vals["a"].length()).c_str()); | |
1074 | ASSERT_STREQ("b_val", std::string(out_vals["b"].c_str(), out_vals["b"].length()).c_str()); | |
1075 | ||
1076 | out_vals.clear(); | |
1077 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "map_remove_key")); | |
1078 | ASSERT_EQ(0, ioctx.omap_get_vals(oid, "", 100, &out_vals)); | |
1079 | ASSERT_EQ(1, (int)out_vals.size()); | |
1080 | ASSERT_STREQ("b_val", std::string(out_vals["b"].c_str(), out_vals["b"].length()).c_str()); | |
1081 | } | |
1082 | ||
1083 | TEST_F(ClsLua, VersionSubop) { | |
1084 | ASSERT_EQ(0, ioctx.create(oid, false)); | |
1085 | ||
1086 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "current_version")); | |
1087 | ASSERT_GT((int)reply_output.length(), 0); | |
1088 | ||
1089 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "current_subop_num")); | |
1090 | ASSERT_GT((int)reply_output.length(), 0); | |
1091 | ||
1092 | ASSERT_EQ(0, clslua_exec(test_script, NULL, "current_subop_version")); | |
1093 | ASSERT_GT((int)reply_output.length(), 0); | |
1094 | } | |
1095 | ||
1096 | TEST_F(ClsLua, Json) { | |
1097 | ASSERT_EQ(0, ioctx.create(oid, false)); | |
1098 | ||
1099 | bufferlist inbl, outbl; | |
1100 | ||
1101 | inbl.append(json_test_script); | |
1102 | ||
1103 | int ret = ioctx.exec(oid, "lua", "eval_json", inbl, outbl); | |
1104 | ASSERT_EQ(ret, 0); | |
1105 | ||
1106 | std::string out(outbl.c_str(), outbl.length()); | |
1107 | ASSERT_STREQ(out.c_str(), "omg it works"); | |
1108 | } |