]>
git.proxmox.com Git - ceph.git/blob - ceph/src/test/cls_lua/test_cls_lua.cc
3 #include "include/types.h"
4 #include "include/rados/librados.hpp"
5 #include "gtest/gtest.h"
6 #include "test/librados/test_cxx.h"
7 #include "cls/lua/cls_lua_client.h"
8 #include "cls/lua/cls_lua.h"
11 * JSON script to test JSON I/O protocol with cls_lua
13 const std::string json_test_script
= R
"jsonscript(
15 "script
": "function
json_echo(input
, output
) output
:append(input
:str()); end objclass
.register(json_echo
)",
16 "handler
": "json_echo
",
17 "input
": "omg it works
",
22 * Lua test script thanks to the magical c++11 string literal syntax
24 const std::string test_script
= R
"luascript(
26 -- This Lua script file contains all of the handlers used in the cls_lua unit
27 -- tests (src/test/cls_lua/test_cls_lua.cc). Each section header corresponds
28 -- to the ClsLua.XYZ test.
34 function read(input, output)
35 size = objclass.stat()
36 bl = objclass.read(0, size)
37 output:append(bl:str())
40 objclass.register(read)
45 function write(input, output)
46 objclass.write(0, #input, input)
49 objclass.register(write)
54 function map_get_val_foo(input, output)
55 bl = objclass.map_get_val('foo')
56 output:append(bl:str())
59 function map_get_val_dne()
60 bl = objclass.map_get_val('dne')
63 objclass.register(map_get_val_foo)
64 objclass.register(map_get_val_dne)
69 function stat_ret(input, output)
70 size, mtime = objclass.stat()
71 output:append(size .. "," .. mtime)
75 size, mtime = objclass.stat()
78 function stat_sdne_pcall()
79 ok, ret, size, mtime = pcall(objclass.stat, o)
81 assert(ret == -objclass.ENOENT)
85 objclass.register(stat_ret)
86 objclass.register(stat_sdne)
87 objclass.register(stat_sdne_pcall)
93 function rv_h1() return 1; end
94 function rv_h0() return 0; end
95 function rv_hn1() return -1; end
96 function rv_hs1() return '1'; end
97 function rv_hs0() return '0'; end
98 function rv_hsn1() return '-1'; end
99 function rv_hnil() return nil; end
100 function rv_ht() return {}; end
101 function rv_hstr() return 'asdf'; end
103 objclass.register(rv_h)
104 objclass.register(rv_h1)
105 objclass.register(rv_h0)
106 objclass.register(rv_hn1)
107 objclass.register(rv_hs1)
108 objclass.register(rv_hs0)
109 objclass.register(rv_hsn1)
110 objclass.register(rv_hnil)
111 objclass.register(rv_ht)
112 objclass.register(rv_hstr)
117 function create_c() objclass.create(true); end
118 function create_cne() objclass.create(false); end
120 objclass.register(create_c)
121 objclass.register(create_cne)
126 function pcall_c() objclass.create(true); end
129 ok, ret = pcall(objclass.create, true)
131 assert(ret == -objclass.EEXIST)
135 ok, ret = pcall(objclass.create, true)
137 assert(ret == -objclass.EEXIST)
141 function pcall_pcr2()
142 ok, ret = pcall(objclass.create, true)
144 assert(ret == -objclass.EEXIST)
145 ok, ret = pcall(objclass.create, true)
147 assert(ret == -objclass.EEXIST)
151 objclass.register(pcall_c)
152 objclass.register(pcall_pc)
153 objclass.register(pcall_pcr)
154 objclass.register(pcall_pcr2)
159 function remove_c() objclass.create(true); end
160 function remove_r() objclass.remove(); end
162 objclass.register(remove_c)
163 objclass.register(remove_r)
168 function map_set_val(input, output)
169 objclass.map_set_val('foo', input)
172 objclass.register(map_set_val)
181 objclass.register(map_clear)
184 -- BufferlistEquality
186 function bl_eq_empty_equal(input, output)
187 bl1 = bufferlist.new()
188 bl2 = bufferlist.new()
192 function bl_eq_empty_selfequal()
193 bl1 = bufferlist.new()
197 function bl_eq_selfequal()
198 bl1 = bufferlist.new()
203 function bl_eq_equal()
204 bl1 = bufferlist.new()
205 bl2 = bufferlist.new()
211 function bl_eq_notequal()
212 bl1 = bufferlist.new()
213 bl2 = bufferlist.new()
219 objclass.register(bl_eq_empty_equal)
220 objclass.register(bl_eq_empty_selfequal)
221 objclass.register(bl_eq_selfequal)
222 objclass.register(bl_eq_equal)
223 objclass.register(bl_eq_notequal)
226 -- Bufferlist Compare
229 local a = bufferlist.new()
230 local b = bufferlist.new()
237 local a = bufferlist.new()
238 local b = bufferlist.new()
244 objclass.register(bl_lt)
245 objclass.register(bl_le)
250 function bl_concat_eq()
251 local a = bufferlist.new()
252 local b = bufferlist.new()
253 local ab = bufferlist.new()
260 function bl_concat_ne()
261 local a = bufferlist.new()
262 local b = bufferlist.new()
263 local ab = bufferlist.new()
270 function bl_concat_immut()
271 local a = bufferlist.new()
272 local b = bufferlist.new()
273 local ab = bufferlist.new()
281 local bc = bufferlist.new()
286 objclass.register(bl_concat_eq)
287 objclass.register(bl_concat_ne)
288 objclass.register(bl_concat_immut)
305 -- only runerr_c is called
306 objclass.register(runerr_c)
311 function getxattr(input, output)
312 bl = objclass.getxattr("fooz
")
313 output:append(bl:str())
316 objclass.register(getxattr)
321 function setxattr(input, output)
322 objclass.setxattr("fooz2
", input)
325 objclass.register(setxattr)
330 function write_full(input, output)
331 objclass.write_full(input)
334 objclass.register(write_full)
339 function getxattrs(input, output)
341 xattrs = objclass.getxattrs()
343 -- sort for determisitic test
345 for n in pairs(xattrs) do
351 for i,key in ipairs(arr) do
352 output_str = output_str .. key .. "/" .. xattrs[key]:str() .. "/"
354 output:append(output_str)
357 objclass.register(getxattrs)
362 function map_get_keys(input, output)
364 keys = objclass.map_get_keys("", 5)
366 -- sort for determisitic test
368 for n in pairs(keys) do
374 for i,key in ipairs(arr) do
375 output_str = output_str .. key .. "/"
378 output:append(output_str)
381 objclass.register(map_get_keys)
386 function map_get_vals(input, output)
388 kvs = objclass.map_get_vals("", "", 10)
390 -- sort for determisitic test
392 for n in pairs(kvs) do
398 for i,key in ipairs(arr) do
399 output_str = output_str .. key .. "/" .. kvs[key]:str() .. "/"
401 output:append(output_str)
404 objclass.register(map_get_vals)
409 function map_write_header(input, output)
410 objclass.map_write_header(input)
413 objclass.register(map_write_header)
418 function map_read_header(input, output)
419 hdr = objclass.map_read_header()
420 output:append(hdr:str())
423 objclass.register(map_read_header)
428 function map_set_vals_empty(input, output)
430 objclass.map_set_vals(record)
433 function map_set_vals_one(input, output)
437 objclass.map_set_vals(record)
440 function map_set_vals_two(input, output)
445 objclass.map_set_vals(record)
448 function map_set_vals_three(input, output)
454 objclass.map_set_vals(record)
457 function map_set_vals_array(input, output)
461 objclass.map_set_vals(array)
464 function map_set_vals_mixed(input, output)
471 objclass.map_set_vals(record)
474 function map_set_vals_bad_val(input, output)
478 objclass.map_set_vals(record)
481 objclass.register(map_set_vals_empty)
482 objclass.register(map_set_vals_one)
483 objclass.register(map_set_vals_two)
484 objclass.register(map_set_vals_three)
485 objclass.register(map_set_vals_array)
486 objclass.register(map_set_vals_mixed)
487 objclass.register(map_set_vals_bad_val)
492 function map_remove_key(input, output)
493 objclass.map_remove_key("a
")
496 objclass.register(map_remove_key)
501 function current_version(input, output)
502 ret = objclass.current_version()
503 output:append("" .. ret)
507 function current_subop_num(input, output)
508 ret = objclass.current_subop_num()
509 output:append("" .. ret)
513 function current_subop_version(input, output)
514 ret = objclass.current_subop_version()
515 output:append("" .. ret)
519 objclass.register(current_version)
520 objclass.register(current_subop_num)
521 objclass.register(current_subop_version)
526 * Test harness uses single pool for the entire test case, and generates
527 * unique object names for each test.
529 class ClsLua
: public ::testing::Test
{
531 static void SetUpTestCase() {
532 pool_name
= get_temp_pool_name();
533 ASSERT_EQ("", create_one_pool_pp(pool_name
, rados
));
534 ASSERT_EQ(0, rados
.ioctx_create(pool_name
.c_str(), ioctx
));
537 static void TearDownTestCase() {
539 ASSERT_EQ(0, destroy_one_pool_pp(pool_name
, rados
));
542 void SetUp() override
{
543 /* Grab test names to build unique objects */
544 const ::testing::TestInfo
* const test_info
=
545 ::testing::UnitTest::GetInstance()->current_test_info();
547 /* Create unique string using test/testname/pid */
548 std::stringstream ss_oid
;
549 ss_oid
<< test_info
->test_case_name() << "_" <<
550 test_info
->name() << "_" << getpid();
552 /* Unique object for test to use */
556 void TearDown() override
{
560 * Helper function. This functionality should eventually make its way into
561 * a clslua client library of some sort.
563 int __clslua_exec(const string
& oid
, const string
& script
,
564 librados::bufferlist
*input
= NULL
, const string
& funcname
= "")
570 reply_output
.clear();
572 return cls_lua_client::exec(ioctx
, oid
, script
, funcname
, inbl
,
576 int clslua_exec(const string
& script
, librados::bufferlist
*input
= NULL
,
577 const string
& funcname
= "")
579 return __clslua_exec(oid
, script
, input
, funcname
);
582 static librados::Rados rados
;
583 static librados::IoCtx ioctx
;
584 static string pool_name
;
587 bufferlist reply_output
;
590 librados::Rados
ClsLua::rados
;
591 librados::IoCtx
ClsLua::ioctx
;
592 string
ClsLua::pool_name
;
594 TEST_F(ClsLua
, Write
) {
595 /* write some data into object */
596 string written
= "Hello World";
598 encode(written
, inbl
);
599 ASSERT_EQ(0, clslua_exec(test_script
, &inbl
, "write"));
601 /* have Lua read out of the object */
604 ASSERT_EQ(0, ioctx
.stat(oid
, &size
, NULL
));
605 ASSERT_EQ(size
, (uint64_t)ioctx
.read(oid
, outbl
, size
, 0) );
607 /* compare what Lua read to what we wrote */
610 ASSERT_EQ(read
, written
);
613 TEST_F(ClsLua
, SyntaxError
) {
614 ASSERT_EQ(-EIO
, clslua_exec("-"));
617 TEST_F(ClsLua
, EmptyScript
) {
618 ASSERT_EQ(0, clslua_exec(""));
621 TEST_F(ClsLua
, RetVal
) {
622 /* handlers can return numeric values */
623 ASSERT_EQ(1, clslua_exec(test_script
, NULL
, "rv_h1"));
624 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "rv_h0"));
625 ASSERT_EQ(-1, clslua_exec(test_script
, NULL
, "rv_hn1"));
626 ASSERT_EQ(1, clslua_exec(test_script
, NULL
, "rv_hs1"));
627 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "rv_hs0"));
628 ASSERT_EQ(-1, clslua_exec(test_script
, NULL
, "rv_hsn1"));
630 /* no return value is success */
631 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "rv_h"));
633 /* non-numeric return values are errors */
634 ASSERT_EQ(-EIO
, clslua_exec(test_script
, NULL
, "rv_hnil"));
635 ASSERT_EQ(-EIO
, clslua_exec(test_script
, NULL
, "rv_ht"));
636 ASSERT_EQ(-EIO
, clslua_exec(test_script
, NULL
, "rv_hstr"));
639 TEST_F(ClsLua
, Create
) {
641 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "create_c"));
643 /* exclusive works */
644 ASSERT_EQ(-EEXIST
, clslua_exec(test_script
, NULL
, "create_c"));
645 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "create_cne"));
648 TEST_F(ClsLua
, Pcall
) {
649 /* create and error works */
650 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "pcall_c"));
651 ASSERT_EQ(-EEXIST
, clslua_exec(test_script
, NULL
, "pcall_c"));
653 /* pcall masks the error */
654 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "pcall_pc"));
656 /* pcall lets us get the failed return value */
657 ASSERT_EQ(-EEXIST
, clslua_exec(test_script
, NULL
, "pcall_pcr"));
660 * the first call in pcr2 will fail (check ret != 0), and the second pcall
661 * should also fail (we check with a bogus return value to mask real
662 * errors). This is also an important check for our error handling because
663 * we need a case where two functions in the same handler fail to exercise
664 * our internal error book keeping.
666 ASSERT_EQ(-9999, clslua_exec(test_script
, NULL
, "pcall_pcr2"));
669 TEST_F(ClsLua
, Remove
) {
670 /* object doesn't exist */
671 ASSERT_EQ(-ENOENT
, clslua_exec(test_script
, NULL
, "remove_r"));
674 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "remove_c"));
675 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "remove_r"));
676 ASSERT_EQ(-ENOENT
, clslua_exec(test_script
, NULL
, "remove_r"));
679 TEST_F(ClsLua
, Stat
) {
680 /* build object and stat */
683 bl
.append(buf
, sizeof(buf
));
684 ASSERT_EQ(0, ioctx
.write_full(oid
, bl
));
687 ASSERT_EQ(0, ioctx
.stat(oid
, &size
, &mtime
));
689 /* test stat success */
690 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "stat_ret"));
692 // size,mtime from ioctx call
693 std::stringstream s1
;
694 s1
<< size
<< "," << mtime
;
696 // lua constructed size,mtime string
697 std::string
s2(reply_output
.c_str(), reply_output
.length());
699 ASSERT_EQ(s1
.str(), s2
);
701 /* test object dne */
702 ASSERT_EQ(-ENOENT
, __clslua_exec("dne", test_script
, NULL
, "stat_sdne"));
704 /* can capture error with pcall */
705 ASSERT_EQ(-ENOENT
, __clslua_exec("dne", test_script
, NULL
, "stat_sdne_pcall"));
708 TEST_F(ClsLua
, MapClear
) {
709 /* write some data into a key */
710 string msg
= "This is a test message";
712 val
.append(msg
.c_str(), msg
.size());
713 map
<string
, bufferlist
> map
;
715 ASSERT_EQ(0, ioctx
.omap_set(oid
, map
));
717 /* test we can get it back out */
721 ASSERT_EQ(0, (int)map
.count("foo"));
722 ASSERT_EQ(0, ioctx
.omap_get_vals_by_keys(oid
, keys
, &map
));
723 ASSERT_EQ(1, (int)map
.count("foo"));
726 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "map_clear"));
728 /* test that the map we get back is empty now */
730 ASSERT_EQ(0, (int)map
.count("foo"));
731 ASSERT_EQ(0, ioctx
.omap_get_vals_by_keys(oid
, keys
, &map
));
732 ASSERT_EQ(0, (int)map
.count("foo"));
735 TEST_F(ClsLua
, MapSetVal
) {
736 /* build some input value */
738 encode("this is the original value yay", orig_val
);
740 /* have the lua script stuff the data into a map value */
741 ASSERT_EQ(0, clslua_exec(test_script
, &orig_val
, "map_set_val"));
743 /* grap the key now and compare to orig */
744 map
<string
, bufferlist
> out_map
;
745 set
<string
> out_keys
;
746 out_keys
.insert("foo");
747 ASSERT_EQ(0, ioctx
.omap_get_vals_by_keys(oid
, out_keys
, &out_map
));
748 bufferlist out_bl
= out_map
["foo"];
750 decode(out_val
, out_bl
);
751 ASSERT_EQ(out_val
, "this is the original value yay");
754 TEST_F(ClsLua
, MapGetVal
) {
755 /* write some data into a key */
756 string msg
= "This is a test message";
758 orig_val
.append(msg
.c_str(), msg
.size());
759 map
<string
, bufferlist
> orig_map
;
760 orig_map
["foo"] = orig_val
;
761 ASSERT_EQ(0, ioctx
.omap_set(oid
, orig_map
));
763 /* now compare to what we put it */
764 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "map_get_val_foo"));
768 ret_val
.assign(reply_output
.c_str(), reply_output
.length());
769 ASSERT_EQ(ret_val
, msg
);
772 ASSERT_EQ(-ENOENT
, clslua_exec(test_script
, NULL
, "map_get_val_dne"));
775 TEST_F(ClsLua
, Read
) {
776 /* put data into object */
777 string msg
= "This is a test message";
779 bl
.append(msg
.c_str(), msg
.size());
780 ASSERT_EQ(0, ioctx
.write_full(oid
, bl
));
782 /* get lua to read it and send it back */
783 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "read"));
787 ret_val
.assign(reply_output
.c_str(), reply_output
.length());
788 ASSERT_EQ(ret_val
, msg
);
791 TEST_F(ClsLua
, Log
) {
792 ASSERT_EQ(0, clslua_exec("objclass.log()"));
793 ASSERT_EQ(0, clslua_exec("s = objclass.log(); objclass.log(s);"));
794 ASSERT_EQ(0, clslua_exec("objclass.log(1)"));
795 ASSERT_EQ(0, clslua_exec("objclass.log(-1)"));
796 ASSERT_EQ(0, clslua_exec("objclass.log('x')"));
797 ASSERT_EQ(0, clslua_exec("objclass.log(0, 0)"));
798 ASSERT_EQ(0, clslua_exec("objclass.log(1, 1)"));
799 ASSERT_EQ(0, clslua_exec("objclass.log(-10, -10)"));
800 ASSERT_EQ(0, clslua_exec("objclass.log('x', 'y')"));
801 ASSERT_EQ(0, clslua_exec("objclass.log(1, 'one')"));
802 ASSERT_EQ(0, clslua_exec("objclass.log(1, 'one', 'two')"));
803 ASSERT_EQ(0, clslua_exec("objclass.log('one', 'two', 'three')"));
804 ASSERT_EQ(0, clslua_exec("s = objclass.log('one', 'two', 'three'); objclass.log(s);"));
807 TEST_F(ClsLua
, BufferlistEquality
) {
808 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "bl_eq_empty_equal"));
809 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "bl_eq_empty_selfequal"));
810 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "bl_eq_selfequal"));
811 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "bl_eq_equal"));
812 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "bl_eq_notequal"));
815 TEST_F(ClsLua
, RunError
) {
816 ASSERT_EQ(-EIO
, clslua_exec(test_script
, NULL
, "runerr_c"));
819 TEST_F(ClsLua
, HandleNotFunc
) {
820 string script
= "x = 1;";
821 ASSERT_EQ(-EOPNOTSUPP
, clslua_exec(script
, NULL
, "x"));
824 TEST_F(ClsLua
, Register
) {
825 /* normal cases: register and maybe call the handler */
826 string script
= "function h() end; objclass.register(h);";
827 ASSERT_EQ(0, clslua_exec(script
, NULL
, ""));
828 ASSERT_EQ(0, clslua_exec(script
, NULL
, "h"));
830 /* can register and call multiple handlers */
831 script
= "function h1() end; function h2() end;"
832 "objclass.register(h1); objclass.register(h2);";
833 ASSERT_EQ(0, clslua_exec(script
, NULL
, ""));
834 ASSERT_EQ(0, clslua_exec(script
, NULL
, "h1"));
835 ASSERT_EQ(0, clslua_exec(script
, NULL
, "h2"));
837 /* normal cases: register before function is defined */
838 script
= "objclass.register(h); function h() end;";
839 ASSERT_EQ(-EIO
, clslua_exec(script
, NULL
, ""));
840 ASSERT_EQ(-EIO
, clslua_exec(script
, NULL
, "h"));
842 /* cannot call handler that isn't registered */
843 script
= "function h() end;";
844 ASSERT_EQ(-EIO
, clslua_exec(script
, NULL
, "h"));
846 /* handler doesn't exist */
847 script
= "objclass.register(lalala);";
848 ASSERT_EQ(-EIO
, clslua_exec(script
, NULL
, ""));
850 /* handler isn't a function */
851 script
= "objclass.register('some string');";
852 ASSERT_EQ(-EIO
, clslua_exec(script
, NULL
, ""));
854 /* cannot register handler multiple times */
855 script
= "function h() end; objclass.register(h); objclass.register(h);";
856 ASSERT_EQ(-EIO
, clslua_exec(script
, NULL
, ""));
859 TEST_F(ClsLua
, BufferlistCompare
) {
860 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "bl_lt"));
861 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "bl_le"));
864 TEST_F(ClsLua
, BufferlistConcat
) {
865 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "bl_concat_eq"));
866 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "bl_concat_ne"));
867 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "bl_concat_immut"));
870 TEST_F(ClsLua
, GetXattr
) {
872 bl
.append("blahblahblahblahblah");
873 ASSERT_EQ(0, ioctx
.setxattr(oid
, "fooz", bl
));
874 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "getxattr"));
875 ASSERT_TRUE(reply_output
== bl
);
878 TEST_F(ClsLua
, SetXattr
) {
880 inbl
.append("blahblahblahblahblah");
881 ASSERT_EQ(0, clslua_exec(test_script
, &inbl
, "setxattr"));
883 ASSERT_EQ((int)inbl
.length(), ioctx
.getxattr(oid
, "fooz2", outbl
));
884 ASSERT_TRUE(outbl
== inbl
);
887 TEST_F(ClsLua
, WriteFull
) {
891 blin
.append(buf
, sizeof(buf
));
892 ASSERT_EQ(0, ioctx
.write(oid
, blin
, blin
.length(), 0));
894 ASSERT_EQ((int)blin
.length(), ioctx
.read(oid
, blout
, 0, 0));
895 ASSERT_EQ(blin
, blout
);
897 // execute write_full from lua
900 sprintf(buf2
, "%s", "data replacing content");
901 blin
.append(buf2
, sizeof(buf2
));
902 ASSERT_EQ(0, clslua_exec(test_script
, &blin
, "write_full"));
906 ASSERT_EQ((int)blin
.length(), ioctx
.read(oid
, blout
, 0, 0));
907 ASSERT_EQ(blin
, blout
);
910 TEST_F(ClsLua
, GetXattrs
) {
911 ASSERT_EQ(0, ioctx
.create(oid
, false));
913 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "getxattrs"));
914 ASSERT_EQ(0, (int)reply_output
.length());
916 string
key1str("key1str");
918 key1bl
.append(key1str
);
919 ASSERT_EQ(0, ioctx
.setxattr(oid
, "key1", key1bl
));
920 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "getxattrs"));
921 string
out1(reply_output
.c_str(), reply_output
.length()); // add the trailing \0
922 ASSERT_STREQ(out1
.c_str(), "key1/key1str/");
924 string
key2str("key2str");
926 key2bl
.append(key2str
);
927 ASSERT_EQ(0, ioctx
.setxattr(oid
, "key2", key2bl
));
928 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "getxattrs"));
929 string
out2(reply_output
.c_str(), reply_output
.length()); // add the trailing \0
930 ASSERT_STREQ(out2
.c_str(), "key1/key1str/key2/key2str/");
932 string
key3str("key3str");
934 key3bl
.append(key3str
);
935 ASSERT_EQ(0, ioctx
.setxattr(oid
, "key3", key3bl
));
936 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "getxattrs"));
937 string
out3(reply_output
.c_str(), reply_output
.length()); // add the trailing \0
938 ASSERT_STREQ(out3
.c_str(), "key1/key1str/key2/key2str/key3/key3str/");
941 TEST_F(ClsLua
, MapGetKeys
) {
942 ASSERT_EQ(0, ioctx
.create(oid
, false));
944 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "map_get_keys"));
945 ASSERT_EQ(0, (int)reply_output
.length());
947 map
<string
, bufferlist
> kvpairs
;
949 kvpairs
["k1"] = bufferlist();
950 ASSERT_EQ(0, ioctx
.omap_set(oid
, kvpairs
));
951 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "map_get_keys"));
952 string
out1(reply_output
.c_str(), reply_output
.length()); // add the trailing \0
953 ASSERT_STREQ(out1
.c_str(), "k1/");
955 kvpairs
["k2"] = bufferlist();
956 ASSERT_EQ(0, ioctx
.omap_set(oid
, kvpairs
));
957 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "map_get_keys"));
958 string
out2(reply_output
.c_str(), reply_output
.length()); // add the trailing \0
959 ASSERT_STREQ(out2
.c_str(), "k1/k2/");
961 kvpairs
["xxx"] = bufferlist();
962 ASSERT_EQ(0, ioctx
.omap_set(oid
, kvpairs
));
963 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "map_get_keys"));
964 string
out3(reply_output
.c_str(), reply_output
.length()); // add the trailing \0
965 ASSERT_STREQ(out3
.c_str(), "k1/k2/xxx/");
968 TEST_F(ClsLua
, MapGetVals
) {
969 ASSERT_EQ(0, ioctx
.create(oid
, false));
971 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "map_get_vals"));
972 ASSERT_EQ(0, (int)reply_output
.length());
974 map
<string
, bufferlist
> kvpairs
;
976 kvpairs
["key1"] = bufferlist();
977 kvpairs
["key1"].append(string("key1str"));
978 ASSERT_EQ(0, ioctx
.omap_set(oid
, kvpairs
));
979 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "map_get_vals"));
980 string
out1(reply_output
.c_str(), reply_output
.length()); // add the trailing \0
981 ASSERT_STREQ(out1
.c_str(), "key1/key1str/");
983 kvpairs
["key2"] = bufferlist();
984 kvpairs
["key2"].append(string("key2str"));
985 ASSERT_EQ(0, ioctx
.omap_set(oid
, kvpairs
));
986 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "map_get_vals"));
987 string
out2(reply_output
.c_str(), reply_output
.length()); // add the trailing \0
988 ASSERT_STREQ(out2
.c_str(), "key1/key1str/key2/key2str/");
990 kvpairs
["key3"] = bufferlist();
991 kvpairs
["key3"].append(string("key3str"));
992 ASSERT_EQ(0, ioctx
.omap_set(oid
, kvpairs
));
993 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "map_get_vals"));
994 string
out3(reply_output
.c_str(), reply_output
.length()); // add the trailing \0
995 ASSERT_STREQ(out3
.c_str(), "key1/key1str/key2/key2str/key3/key3str/");
998 TEST_F(ClsLua
, MapHeader
) {
999 ASSERT_EQ(0, ioctx
.create(oid
, false));
1002 ASSERT_EQ(0, ioctx
.omap_get_header(oid
, &bl_out
));
1003 ASSERT_EQ(0, (int)bl_out
.length());
1005 std::string
val("this is a value");
1009 ASSERT_EQ(0, clslua_exec(test_script
, &hdr
, "map_write_header"));
1010 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "map_read_header"));
1012 ASSERT_EQ(reply_output
, hdr
);
1015 TEST_F(ClsLua
, MapSetVals
) {
1016 ASSERT_EQ(0, ioctx
.create(oid
, false));
1018 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "map_set_vals_empty"));
1020 std::map
<string
, bufferlist
> out_vals
;
1021 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "map_set_vals_one"));
1022 ASSERT_EQ(0, ioctx
.omap_get_vals(oid
, "", 100, &out_vals
));
1023 ASSERT_EQ(1, (int)out_vals
.size());
1024 ASSERT_STREQ("a_val", std::string(out_vals
["a"].c_str(), out_vals
["a"].length()).c_str());
1027 ASSERT_EQ(0, ioctx
.omap_clear(oid
));
1028 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "map_set_vals_two"));
1029 ASSERT_EQ(0, ioctx
.omap_get_vals(oid
, "", 100, &out_vals
));
1030 ASSERT_EQ(2, (int)out_vals
.size());
1031 ASSERT_STREQ("a_val", std::string(out_vals
["a"].c_str(), out_vals
["a"].length()).c_str());
1032 ASSERT_STREQ("b_val", std::string(out_vals
["b"].c_str(), out_vals
["b"].length()).c_str());
1035 ASSERT_EQ(0, ioctx
.omap_clear(oid
));
1036 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "map_set_vals_three"));
1037 ASSERT_EQ(0, ioctx
.omap_get_vals(oid
, "", 100, &out_vals
));
1038 ASSERT_EQ(3, (int)out_vals
.size());
1039 ASSERT_STREQ("a_val", std::string(out_vals
["a"].c_str(), out_vals
["a"].length()).c_str());
1040 ASSERT_STREQ("b_val", std::string(out_vals
["b"].c_str(), out_vals
["b"].length()).c_str());
1041 ASSERT_STREQ("c_val", std::string(out_vals
["c"].c_str(), out_vals
["c"].length()).c_str());
1044 ASSERT_EQ(0, ioctx
.omap_clear(oid
));
1045 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "map_set_vals_array"));
1046 ASSERT_EQ(0, ioctx
.omap_get_vals(oid
, "", 100, &out_vals
));
1047 ASSERT_EQ(2, (int)out_vals
.size());
1048 ASSERT_STREQ("1_val", std::string(out_vals
["1"].c_str(), out_vals
["1"].length()).c_str());
1049 ASSERT_STREQ("2_val", std::string(out_vals
["2"].c_str(), out_vals
["2"].length()).c_str());
1052 ASSERT_EQ(0, ioctx
.omap_clear(oid
));
1053 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "map_set_vals_mixed"));
1054 ASSERT_EQ(0, ioctx
.omap_get_vals(oid
, "", 100, &out_vals
));
1055 ASSERT_EQ(4, (int)out_vals
.size());
1056 ASSERT_STREQ("a_val", std::string(out_vals
["a"].c_str(), out_vals
["a"].length()).c_str());
1057 ASSERT_STREQ("b_val", std::string(out_vals
["b"].c_str(), out_vals
["b"].length()).c_str());
1058 ASSERT_STREQ("1_val", std::string(out_vals
["1"].c_str(), out_vals
["1"].length()).c_str());
1059 ASSERT_STREQ("2_val", std::string(out_vals
["2"].c_str(), out_vals
["2"].length()).c_str());
1061 ASSERT_EQ(-EINVAL
, clslua_exec(test_script
, NULL
, "map_set_vals_bad_val"));
1064 TEST_F(ClsLua
, MapRemoveKey
) {
1065 ASSERT_EQ(0, ioctx
.create(oid
, false));
1067 std::map
<string
, bufferlist
> out_vals
;
1068 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "map_set_vals_two"));
1069 ASSERT_EQ(0, ioctx
.omap_get_vals(oid
, "", 100, &out_vals
));
1070 ASSERT_EQ(2, (int)out_vals
.size());
1071 ASSERT_STREQ("a_val", std::string(out_vals
["a"].c_str(), out_vals
["a"].length()).c_str());
1072 ASSERT_STREQ("b_val", std::string(out_vals
["b"].c_str(), out_vals
["b"].length()).c_str());
1075 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "map_remove_key"));
1076 ASSERT_EQ(0, ioctx
.omap_get_vals(oid
, "", 100, &out_vals
));
1077 ASSERT_EQ(1, (int)out_vals
.size());
1078 ASSERT_STREQ("b_val", std::string(out_vals
["b"].c_str(), out_vals
["b"].length()).c_str());
1081 TEST_F(ClsLua
, VersionSubop
) {
1082 ASSERT_EQ(0, ioctx
.create(oid
, false));
1084 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "current_version"));
1085 ASSERT_GT((int)reply_output
.length(), 0);
1087 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "current_subop_num"));
1088 ASSERT_GT((int)reply_output
.length(), 0);
1090 ASSERT_EQ(0, clslua_exec(test_script
, NULL
, "current_subop_version"));
1091 ASSERT_GT((int)reply_output
.length(), 0);
1094 TEST_F(ClsLua
, Json
) {
1095 ASSERT_EQ(0, ioctx
.create(oid
, false));
1097 bufferlist inbl
, outbl
;
1099 inbl
.append(json_test_script
);
1101 int ret
= ioctx
.exec(oid
, "lua", "eval_json", inbl
, outbl
);
1104 std::string
out(outbl
.c_str(), outbl
.length());
1105 ASSERT_STREQ(out
.c_str(), "omg it works");