diff options
Diffstat (limited to 'fluent-bit/tests/internal/lua.c')
-rw-r--r-- | fluent-bit/tests/internal/lua.c | 325 |
1 files changed, 325 insertions, 0 deletions
diff --git a/fluent-bit/tests/internal/lua.c b/fluent-bit/tests/internal/lua.c new file mode 100644 index 00000000..122748fb --- /dev/null +++ b/fluent-bit/tests/internal/lua.c @@ -0,0 +1,325 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#include <fluent-bit/flb_lua.h> +#include <lauxlib.h> +#include <lua.h> + +#include "flb_tests_internal.h" +#include "mpack/mpack.h" +#include "msgpack/object.h" +#include "msgpack/pack.h" +#include "msgpack/sbuffer.h" + +/* Helper lua function which returns a string representation of lua objects. + * Tables are stringified in key order (lua table iteration order is not deterministic. */ +const char lua_stringify_object_helper[] = ("" +"function stringify(o)\n" +" if type(o) == 'table' then\n" +" local keys = {}\n" +" for k in pairs(o) do table.insert(keys, k) end\n" +" table.sort(keys)\n" +" local s = '{ '\n" +" for _,k in ipairs(keys) do\n" +" local v = o[k]\n" +" s = s .. '['..k..'] = ' .. stringify(v) .. ' '\n" +" end\n" +" return s .. '}'\n" +" else\n" +" return tostring(o)\n" +" end\n" +"end\n"); + +static lua_State *lua_setup(const char *script) +{ + lua_State *ret = luaL_newstate(); + if (!ret) { + flb_error("[lua] error creating new context"); + return NULL; + } + luaL_openlibs(ret); + luaL_loadstring(ret, lua_stringify_object_helper); + if (lua_pcall(ret, 0, 0, 0)) { + flb_error("[lua] error executing stringify helper script"); + lua_close(ret); + return NULL; + } + if (script) { + luaL_loadstring(ret, script); + if (lua_pcall(ret, 0, 0, 0)) { + flb_error("[lua] error executing test script"); + lua_close(ret); + return NULL; + } + } + return ret; +} + +static void check_equals(lua_State *l, const char *expected) +{ + /* push the stringify function on the stack */ + lua_getglobal(l, "stringify"); + /* swap the top two elements of the stack, so that the function is below the arg */ + lua_insert(l, -2); + /* call the function */ + if (lua_pcall(l, 1, 1, 0)) { + flb_error("[lua] error calling stringify helper function"); + return; + } + const char *result = lua_tostring(l, -1); + TEST_CHECK(strcmp(result, expected) == 0); + TEST_MSG("Expected: %s", expected); + TEST_MSG("Actual: %s", result); + /* remove the result */ + lua_pop(l, 1); +} + +static void test_is_valid_func() +{ + lua_State *l = lua_setup(NULL); + TEST_CHECK(flb_lua_is_valid_func(l, "invalid_function") == false); + TEST_CHECK(flb_lua_is_valid_func(l, "stringify") == true); + lua_close(l); +} + +static void test_pushtimetable() +{ + lua_State *l = lua_setup(NULL); + struct flb_time t = {{ 5, 6 }}; + flb_lua_pushtimetable(l, &t); + check_equals(l, "{ [nsec] = 6 [sec] = 5 }"); + t.tm.tv_nsec = 7; + t.tm.tv_sec = 8; + flb_lua_pushtimetable(l, &t); + check_equals(l, "{ [nsec] = 7 [sec] = 8 }"); + lua_close(l); +} + +static void test_pushmsgpack() +{ + msgpack_packer pck; + msgpack_sbuffer sbuf; + msgpack_unpacked msg; + lua_State *l = lua_setup(NULL); + + msgpack_sbuffer_init(&sbuf); + msgpack_packer_init(&pck, &sbuf, msgpack_sbuffer_write); + msgpack_pack_array(&pck, 3); + msgpack_pack_map(&pck, 1); + msgpack_pack_str_with_body(&pck, "key", 3); + msgpack_pack_str_with_body(&pck, "value", 5); + msgpack_pack_str_with_body(&pck, "msgpack-str", 11); + msgpack_pack_int(&pck, 4); + + msgpack_unpacked_init(&msg); + msgpack_unpack_next(&msg, sbuf.data, sbuf.size, NULL); + flb_lua_pushmsgpack(l, &msg.data); + check_equals(l, "{ [1] = { [key] = value } [2] = msgpack-str [3] = 4 }"); + + msgpack_unpacked_destroy(&msg); + msgpack_sbuffer_destroy(&sbuf); + lua_close(l); +} + +static void test_pushmpack() +{ + msgpack_packer pck; + msgpack_sbuffer sbuf; + mpack_reader_t reader; + lua_State *l = lua_setup(NULL); + + msgpack_sbuffer_init(&sbuf); + msgpack_packer_init(&pck, &sbuf, msgpack_sbuffer_write); + msgpack_pack_array(&pck, 3); + msgpack_pack_map(&pck, 1); + msgpack_pack_str_with_body(&pck, "key", 3); + msgpack_pack_str_with_body(&pck, "value", 5); + msgpack_pack_str_with_body(&pck, "msgpack-str", 11); + msgpack_pack_int(&pck, 4); + + mpack_reader_init_data(&reader, sbuf.data, sbuf.size); + flb_lua_pushmpack(l, &reader); + check_equals(l, "{ [1] = { [key] = value } [2] = msgpack-str [3] = 4 }"); + + msgpack_sbuffer_destroy(&sbuf); + lua_close(l); +} + +static void test_tomsgpack() +{ + const char expected[] = "[{\"key\"=>\"value\"}, \"msgpack-str\", 4]"; + char buf[256]; + msgpack_packer pck; + msgpack_sbuffer sbuf; + msgpack_unpacked msg; + struct flb_lua_l2c_config l2cc; + lua_State *l = lua_setup("obj = {{['key']='value'},'msgpack-str',4}"); + + msgpack_sbuffer_init(&sbuf); + msgpack_packer_init(&pck, &sbuf, msgpack_sbuffer_write); + mk_list_init(&l2cc.l2c_types); + l2cc.l2c_types_num = 0; + + lua_getglobal(l, "obj"); + flb_lua_tomsgpack(l, &pck, 0, &l2cc); + + msgpack_unpacked_init(&msg); + msgpack_unpack_next(&msg, sbuf.data, sbuf.size, NULL); + msgpack_object_print_buffer(buf, sizeof(buf), msg.data); + + TEST_CHECK(strcmp(buf, expected) == 0); + TEST_MSG("Expected: %s", expected); + TEST_MSG("Actual: %s", buf); + + msgpack_unpacked_destroy(&msg); + msgpack_sbuffer_destroy(&sbuf); + lua_close(l); +} + +static void test_tompack() +{ + const char expected[] = "[{\"key\"=>\"value\"}, \"msgpack-str\", 4]"; + char buf[256]; + char printbuf[256]; + mpack_writer_t writer; + msgpack_unpacked msg; + struct flb_lua_l2c_config l2cc; + lua_State *l = lua_setup("obj = {{['key']='value'},'msgpack-str',4}"); + + mpack_writer_init(&writer, buf, sizeof(buf)); + mk_list_init(&l2cc.l2c_types); + l2cc.l2c_types_num = 0; + + lua_getglobal(l, "obj"); + flb_lua_tompack(l, &writer, 0, &l2cc); + + msgpack_unpacked_init(&msg); + msgpack_unpack_next(&msg, writer.buffer, writer.position - writer.buffer, NULL); + msgpack_object_print_buffer(printbuf, sizeof(printbuf), msg.data); + + TEST_CHECK(strcmp(printbuf, expected) == 0); + TEST_MSG("Expected: %s", expected); + TEST_MSG("Actual: %s", buf); + + msgpack_unpacked_destroy(&msg); + lua_close(l); +} + + +static void test_lua_arraylength() +{ + lua_State *l; + int i; + int len; + int size = 10; + + l = luaL_newstate(); + if (!TEST_CHECK(l != NULL)) { + TEST_MSG("luaL_newstate faild"); + return; + } + luaL_openlibs(l); + + /* create array. */ + lua_createtable(l, size, 0); + + for (i=1; i<=size; i++) { + lua_pushinteger(l, i); /* set an index of array */ + lua_pushinteger(l, 3+i); /* set a value */ + lua_settable(l, -3); /* points created table */ + } + + len = flb_lua_arraylength(l, -1); + if (!TEST_CHECK(len == size)) { + TEST_MSG("size error. got=%d expect=%d", len, size); + } + lua_pop(l, 1); + + lua_close(l); +} + +static void test_lua_arraylength_with_index() +{ + lua_State *l; + int i; + int len; + int size = 10; + + l = luaL_newstate(); + if (!TEST_CHECK(l != NULL)) { + TEST_MSG("luaL_newstate faild"); + return; + } + luaL_openlibs(l); + + /* create array. */ + lua_createtable(l, size, 0); + + for (i=1; i<=size; i++) { + lua_pushinteger(l, i); /* set an index of array */ + lua_pushinteger(l, 3+i); /* set a value */ + lua_settable(l, -3); /* points created table */ + } + + /* push 2 values */ + lua_pushinteger(l, 100); + lua_pushinteger(l, 101); + + len = flb_lua_arraylength(l, -3); /* points array. -1 points 101, -2 points 100 */ + if (!TEST_CHECK(len == size)) { + TEST_MSG("size error. got=%d expect=%d", len, size); + } + lua_pop(l, 1); + + lua_close(l); +} + +static void test_lua_arraylength_for_array_contains_nil() +{ + lua_State *l; + int i; + int len; + int size = 10; + + l = luaL_newstate(); + if (!TEST_CHECK(l != NULL)) { + TEST_MSG("luaL_newstate faild"); + return; + } + luaL_openlibs(l); + + /* create array. */ + lua_createtable(l, size, 0); + + for (i=1; i<=size; i++) { + lua_pushinteger(l, i); /* set an index of array */ + if (i == 7) { + lua_pushnil(l); + } + else { + lua_pushinteger(l, 3+i); /* set a value */ + } + lua_settable(l, -3); /* points created table */ + } + + len = flb_lua_arraylength(l, -1); + if (!TEST_CHECK(len == size)) { + TEST_MSG("size error. got=%d expect=%d", len, size); + } + lua_pop(l, 1); + + lua_close(l); +} + + +TEST_LIST = { + { "lua_is_valid_func" , test_is_valid_func}, + { "lua_pushtimetable" , test_pushtimetable}, + { "lua_pushmsgpack" , test_pushmsgpack }, + { "lua_pushmpack" , test_pushmpack }, + { "lua_tomsgpack" , test_tomsgpack }, + { "lua_tompack" , test_tompack }, + { "lua_arraylength" , test_lua_arraylength }, + { "lua_arraylength_with_index" , test_lua_arraylength_with_index }, + { "lua_arraylength_for_array_contains_nil", test_lua_arraylength_for_array_contains_nil}, + { 0 } +}; |