static char* test_api_assertion() { lsb_lua_sandbox *sb = lsb_create(NULL, "lua/counter.lua", "", NULL); lsb_err_value ret = lsb_init(sb, NULL); mu_assert(!ret, "lsb_init() received: %s", ret); lsb_stop_sandbox(NULL); mu_assert(lsb_destroy(NULL) == NULL, "not null"); mu_assert(lsb_usage(NULL, 0, 0) == 0, "not 0"); mu_assert(lsb_usage(sb, LSB_UT_MAX, 0) == 0, "not 0"); mu_assert(lsb_usage(sb, 0, LSB_US_MAX) == 0, "not 0"); mu_assert(strcmp(lsb_get_error(NULL), "") == 0, "not empty"); lsb_set_error(NULL, "foo"); mu_assert(lsb_get_lua(NULL) == NULL, "not null"); mu_assert(lsb_get_lua_file(NULL) == NULL, "not null"); mu_assert(lsb_get_parent(NULL) == NULL, "not null"); mu_assert(lsb_get_logger(NULL) == NULL, "not null"); mu_assert(lsb_get_state(NULL) == LSB_UNKNOWN, "not unknown"); lsb_add_function(NULL, lsb_test_write_output, "foo"); lsb_add_function(sb, NULL, "foo"); lsb_add_function(sb, lsb_test_write_output, NULL); mu_assert(lsb_pcall_setup(NULL, "foo") == LSB_ERR_UTIL_NULL, "not null"); mu_assert(lsb_pcall_setup(sb, NULL) == LSB_ERR_UTIL_NULL, "not null"); lsb_add_function(NULL, NULL, NULL); lsb_pcall_teardown(NULL); lsb_terminate(NULL, NULL); lsb_terminate(sb, NULL); lsb_add_function(sb, lsb_test_write_output, "write_output"); e = lsb_destroy(sb); mu_assert(!e, "lsb_destroy() received: %s", e); return NULL; }
static char* test_restore() { const char *output_file = "restore.preserve"; remove(output_file); lsb_lua_sandbox *sb = lsb_create(NULL, "lua/restore.lua", test_cfg, NULL); mu_assert(sb, "lsb_create() received: NULL"); lsb_err_value ret = lsb_init(sb, output_file); mu_assert(!ret, "lsb_init() received: %s", ret); lsb_add_function(sb, &lsb_test_write_output, "write_output"); int result = lsb_test_process(sb, 0); mu_assert(result == 0, "process() received: %d %s", result, lsb_get_error(sb)); mu_assert(strcmp("101", lsb_test_output) == 0, "test: initial load received: %s", lsb_test_output); e = lsb_destroy(sb); mu_assert(!e, "lsb_destroy() received: %s", e); // re-load to test the preserved data sb = lsb_create(NULL, "lua/restore.lua", test_cfg, NULL); mu_assert(sb, "lsb_create() received: NULL"); ret = lsb_init(sb, output_file); mu_assert(!ret, "lsb_init() received: %s", ret); lsb_add_function(sb, &lsb_test_write_output, "write_output"); result = lsb_test_process(sb, 0); mu_assert(result == 0, "process() received: %d %s", result, lsb_get_error(sb)); mu_assert(strcmp("102", lsb_test_output) == 0, "test: reload received: %s", lsb_test_output); result = lsb_test_report(sb, 2); // change the preservation version mu_assert(result == 0, "report() received: %d", result); e = lsb_destroy(sb); mu_assert(!e, "lsb_destroy() received: %s", e); // re-load to test the preserved data with a version change sb = lsb_create(NULL, "lua/restore.lua", test_cfg, NULL); mu_assert(sb, "lsb_create() received: NULL"); ret = lsb_init(sb, output_file); mu_assert(!ret, "lsb_init() received: %s", ret); lsb_add_function(sb, &lsb_test_write_output, "write_output"); result = lsb_test_process(sb, 0); mu_assert(result == 0, "process() received: %d %s", result, lsb_get_error(sb)); mu_assert(strcmp("101", lsb_test_output) == 0, "test: reload with version change received: %s", lsb_test_output); e = lsb_destroy(sb); mu_assert(!e, "lsb_destroy() received: %s", e); return NULL; }
static char* test_output_errors() { const char *tests[] = { "process() lua/output_errors.lua:10: bad argument #1 to 'output' (unsupported type)" , "process() lua/output_errors.lua:16: output_limit exceeded" , "process() lua/output_errors.lua:18: bad argument #1 to 'write_output' (unknown userdata type)" , NULL }; for (int i = 0; tests[i]; ++i) { lsb_lua_sandbox *sb = lsb_create(NULL, "lua/output_errors.lua", MODULE_PATH "output_limit = 128", NULL); mu_assert(sb, "lsb_create() received: NULL"); lsb_err_value ret = lsb_init(sb, NULL); mu_assert(!ret, "lsb_init() received: %s", ret); lsb_add_function(sb, &lsb_test_write_output, "write_output"); int result = lsb_test_process(sb, i); mu_assert(result == 1, "test: %d received: %d", i, result); const char *le = lsb_get_error(sb); mu_assert(le, "test: %d received NULL", i); mu_assert(strcmp(tests[i], le) == 0, "test: %d received: %s", i, le); e = lsb_destroy(sb); mu_assert(!e, "lsb_destroy() received: %s", e); } return NULL; }
static char* test_output() { const char *outputs[] = { "1.2 string nil true false", "foo", NULL }; lsb_lua_sandbox *sb = lsb_create(NULL, "lua/output.lua", test_cfg, NULL); mu_assert(sb, "lsb_create() received: NULL"); add_ud_module(sb); lsb_err_value ret = lsb_init(sb, NULL); mu_assert(!ret, "lsb_init() received: %s", ret); lsb_add_function(sb, &lsb_test_write_output, "write_output"); for (int x = 0; outputs[x]; ++x) { int result = lsb_test_process(sb, x); mu_assert(!result, "process() test: %d failed: %d %s", x, result, lsb_get_error(sb)); if (outputs[x][0]) { mu_assert(strcmp(outputs[x], lsb_test_output) == 0, "test: %d received: %s", x, lsb_test_output); } } e = lsb_destroy(sb); mu_assert(!e, "lsb_destroy() received: %s", e); return NULL; }
static hs_output_plugin* create_output_plugin(const hs_config* cfg, hs_sandbox_config* sbc) { hs_output_plugin* p = calloc(1, sizeof(hs_output_plugin)); if (!p) return NULL; p->list_index = -1; if (pthread_mutex_init(&p->cp_lock, NULL)) { perror("cp_lock pthread_mutex_init failed"); exit(EXIT_FAILURE); } p->sb = hs_create_output_sandbox(p, cfg, sbc); if (!p->sb) { free(p); hs_log(g_module, 3, "lsb_create_custom failed: %s/%s", sbc->dir, sbc->filename); return NULL; } if (sbc->async_buffer_size > 0) { p->async_len = sbc->async_buffer_size; p->async_cp = calloc(p->async_len, sizeof(hs_checkpoint_pair)); if (!p->async_cp) { hs_free_sandbox(p->sb); free(p); hs_log(g_module, 3, "failed allocating the async buffer"); return NULL; } lsb_add_function(p->sb->lsb, &async_checkpoint_update, "async_checkpoint_update"); } return p; }
static char* test_cbuf() { const char* outputs[] = { "{\"time\":0,\"rows\":3,\"columns\":3,\"seconds_per_row\":1,\"column_info\":[{\"name\":\"Add_column\",\"unit\":\"count\",\"aggregation\":\"sum\"},{\"name\":\"Set_column\",\"unit\":\"count\",\"aggregation\":\"sum\"},{\"name\":\"Get_column\",\"unit\":\"count\",\"aggregation\":\"sum\"}]}\n0\t0\t0\n0\t0\t0\n0\t0\t0\n" , "{\"time\":0,\"rows\":3,\"columns\":3,\"seconds_per_row\":1,\"column_info\":[{\"name\":\"Add_column\",\"unit\":\"count\",\"aggregation\":\"sum\"},{\"name\":\"Set_column\",\"unit\":\"count\",\"aggregation\":\"sum\"},{\"name\":\"Get_column\",\"unit\":\"count\",\"aggregation\":\"sum\"}]}\n1\t1\t1\n2\t1\t2\n3\t1\t3\n" , "{\"time\":2,\"rows\":3,\"columns\":3,\"seconds_per_row\":1,\"column_info\":[{\"name\":\"Add_column\",\"unit\":\"count\",\"aggregation\":\"sum\"},{\"name\":\"Set_column\",\"unit\":\"count\",\"aggregation\":\"sum\"},{\"name\":\"Get_column\",\"unit\":\"count\",\"aggregation\":\"sum\"}]}\n3\t1\t3\n0\t0\t0\n1\t1\t1\n" , "{\"time\":8,\"rows\":3,\"columns\":3,\"seconds_per_row\":1,\"column_info\":[{\"name\":\"Add_column\",\"unit\":\"count\",\"aggregation\":\"sum\"},{\"name\":\"Set_column\",\"unit\":\"count\",\"aggregation\":\"sum\"},{\"name\":\"Get_column\",\"unit\":\"count\",\"aggregation\":\"sum\"}]}\n0\t0\t0\n0\t0\t0\n1\t1\t1\n" , NULL }; lua_sandbox* sb = lsb_create(NULL, "lua/circular_buffer.lua", 32767, 1000, 32767); mu_assert(sb, "lsb_create() received: NULL"); int result = lsb_init(sb, NULL); mu_assert(result == 0, "lsb_init() received: %d %s", result, lsb_get_error(sb)); lsb_add_function(sb, &write_output, "write"); result = report(sb, 0); mu_assert(lsb_get_state(sb) == LSB_RUNNING, "error %s", lsb_get_error(sb)); mu_assert(strcmp(outputs[0], written_data) == 0, "received: %s", written_data); process(sb, 0); process(sb, 1e9); process(sb, 1e9); process(sb, 2e9); process(sb, 2e9); process(sb, 2e9); result = report(sb, 0); mu_assert(result == 0, "report() received: %d", result); mu_assert(strcmp(outputs[1], written_data) == 0, "received: %s", written_data); process(sb, 4e9); result = report(sb, 0); mu_assert(result == 0, "report() received: %d", result); mu_assert(strcmp(outputs[2], written_data) == 0, "received: %s", written_data); process(sb, 10e9); result = report(sb, 0); mu_assert(result == 0, "report() received: %d", result); mu_assert(strcmp(outputs[3], written_data) == 0, "received: %s", written_data); result = report(sb, 1); mu_assert(result == 0, "report() received: %d", result); result = report(sb, 3); mu_assert(result == 0, "report() received: %d", result); e = lsb_destroy(sb, "circular_buffer.preserve"); mu_assert(!e, "lsb_destroy() received: %s", e); return NULL; }
int hs_init_analysis_sandbox(hs_sandbox* sb, lua_CFunction im_fp) { if (!im_fp) return -1; lsb_add_function(sb->lsb, &read_message, "read_message"); lsb_add_function(sb->lsb, im_fp, "inject_message"); lsb_add_function(sb->lsb, &inject_payload, "inject_payload"); int ret = lsb_init(sb->lsb, sb->state); if (ret) return ret; lua_State* lua = lsb_get_lua(sb->lsb); // rename output to add_to_payload lua_getglobal(lua, "output"); lua_setglobal(lua, "add_to_payload"); lua_pushnil(lua); lua_setglobal(lua, "output"); return 0; }
int hs_init_output_sandbox(hs_sandbox* sb) { lsb_add_function(sb->lsb, &read_message, "read_message"); int ret = lsb_init(sb->lsb, sb->state); if (ret) return ret; lua_State* lua = lsb_get_lua(sb->lsb); // remove output function lua_pushnil(lua); lua_setglobal(lua, "output"); return 0; }
static char* benchmark_lua_types_output() { int iter = 1000000; lsb_lua_sandbox *sb = lsb_create(NULL, "lua/output.lua", test_cfg, NULL); mu_assert(sb, "lsb_create() received: NULL"); lsb_err_value ret = lsb_init(sb, NULL); mu_assert(!ret, "lsb_init() received: %s", ret); lsb_add_function(sb, &lsb_test_write_output, "write_output"); clock_t t = clock(); for (int x = 0; x < iter; ++x) { mu_assert(0 == lsb_test_process(sb, 0), "%s", lsb_get_error(sb)); } t = clock() - t; e = lsb_destroy(sb); mu_assert(!e, "lsb_destroy() received: %s", e); printf("benchmark_lua_types_output() %g seconds\n", ((double)t) / CLOCKS_PER_SEC / iter); return NULL; }
static char* benchmark_table_output() { int iter = 100000; lua_sandbox* sb = lsb_create(NULL, "lua/output.lua", 100000, 1000, 1024 * 63); mu_assert(sb, "lsb_create() received: NULL"); int result = lsb_init(sb, NULL); mu_assert(result == 0, "lsb_init() received: %d %s", result, lsb_get_error(sb)); lsb_add_function(sb, &write_output, "write"); clock_t t = clock(); for (int x = 0; x < iter; ++x) { process(sb, 2); } t = clock() - t; e = lsb_destroy(sb, NULL); mu_assert(!e, "lsb_destroy() received: %s", e); printf("benchmark_table_output() %g seconds\n", ((float)t) / CLOCKS_PER_SEC / iter); return NULL; }
static char* test_lpeg() { const char* expected = "{\"table\":[\"1\",\"string with spaces\"," "\"quoted string, with comma and \\\"quoted\\\" text\"]}\n"; lua_sandbox* sb = lsb_create(NULL, "lua/lpeg_csv.lua", 100000, 1000, 8000); mu_assert(sb, "lsb_create() received: NULL"); int result = lsb_init(sb, NULL); mu_assert(result == 0, "lsb_init() received: %d %s", result, lsb_get_error(sb)); lsb_add_function(sb, &write_output, "write"); result = process(sb, 0); mu_assert(result == 0, "process() received: %d %s", result, lsb_get_error(sb)); mu_assert(strcmp(expected, written_data) == 0, "received: %s", written_data); e = lsb_destroy(sb, NULL); mu_assert(!e, "lsb_destroy() received: %s", e); return NULL; }
lsb_heka_sandbox* lsb_heka_create_output(void *parent, const char *lua_file, const char *state_file, const char *lsb_cfg, lsb_logger logger, lsb_heka_update_checkpoint ucp) { if (!lua_file) { if (logger) logger(__FUNCTION__, 3, "lua_file must be specified"); return NULL; } if (!ucp) { if (logger) logger(__FUNCTION__, 3, "update_checkpoint callback must be " "specified"); return NULL; } lsb_heka_sandbox *hsb = calloc(1, sizeof(lsb_heka_sandbox)); if (!hsb) { if (logger) logger(__FUNCTION__, 3, "memory allocation failed"); return NULL; } hsb->type = 'o'; hsb->parent = parent; hsb->msg = NULL; hsb->cb.ucp = ucp; hsb->name = NULL; hsb->hostname = NULL; hsb->lsb = lsb_create(hsb, lua_file, lsb_cfg, logger); if (!hsb->lsb) { free(hsb); return NULL; } lua_State *lua = lsb_get_lua(hsb->lsb); set_restrictions(lua, hsb); // todo link print to the logger or a no-op lsb_add_function(hsb->lsb, heka_decode_message, "decode_message"); lsb_add_function(hsb->lsb, heka_encode_message, "encode_message"); lsb_add_function(hsb->lsb, update_checkpoint, "update_checkpoint"); if (lsb_init(hsb->lsb, state_file)) { if (logger) logger(hsb->name, 3, lsb_get_error(hsb->lsb)); lsb_destroy(hsb->lsb); free(hsb->hostname); free(hsb->name); free(hsb); return NULL; } // remove output function lua_pushnil(lua); lua_setglobal(lua, "output"); return hsb; }
lsb_heka_sandbox* lsb_heka_create_analysis(void *parent, const char *lua_file, const char *state_file, const char *lsb_cfg, lsb_logger logger, lsb_heka_im_analysis im) { if (!lua_file) { if (logger) logger(__FUNCTION__, 3, "lua_file must be specified"); return NULL; } if (!im) { if (logger) logger(__FUNCTION__, 3, "inject_message callback must be " "specified"); return NULL; } lsb_heka_sandbox *hsb = calloc(1, sizeof(lsb_heka_sandbox)); if (!hsb) { if (logger) logger(__FUNCTION__, 3, "memory allocation failed"); return NULL; } hsb->type = 'a'; hsb->parent = parent; hsb->msg = NULL; hsb->cb.aim = im; hsb->name = NULL; hsb->hostname = NULL; hsb->lsb = lsb_create(hsb, lua_file, lsb_cfg, logger); if (!hsb->lsb) { free(hsb); return NULL; } lua_State *lua = lsb_get_lua(hsb->lsb); set_restrictions(lua, hsb); // todo link print to the logger or a no-op lsb_add_function(hsb->lsb, heka_decode_message, "decode_message"); lsb_add_function(hsb->lsb, read_message, "read_message"); lsb_add_function(hsb->lsb, inject_message_analysis, "inject_message"); lsb_add_function(hsb->lsb, inject_payload, "inject_payload"); // rename output to add_to_payload lua_getglobal(lua, "output"); lua_setglobal(lua, "add_to_payload"); lua_pushnil(lua); lua_setglobal(lua, "output"); if (lsb_init(hsb->lsb, state_file)) { if (logger) logger(hsb->name, 3, lsb_get_error(hsb->lsb)); lsb_destroy(hsb->lsb); free(hsb->hostname); free(hsb->name); free(hsb); return NULL; } return hsb; }
lsb_heka_sandbox* lsb_heka_create_input(void *parent, const char *lua_file, const char *state_file, const char *lsb_cfg, lsb_logger logger, lsb_heka_im_input im) { if (!lua_file) { if (logger) logger(__FUNCTION__, 3, "lua_file must be specified"); return NULL; } if (!im) { if (logger) logger(__FUNCTION__, 3, "inject_message callback must be " "specified"); return NULL; } lsb_heka_sandbox *hsb = calloc(1, sizeof(lsb_heka_sandbox)); if (!hsb) { if (logger) logger(__FUNCTION__, 3, "memory allocation failed"); return NULL; } hsb->type = 'i'; hsb->parent = parent; hsb->msg = NULL; hsb->cb.iim = im; hsb->name = NULL; hsb->hostname = NULL; hsb->lsb = lsb_create(hsb, lua_file, lsb_cfg, logger); if (!hsb->lsb) { free(hsb); return NULL; } lua_State *lua = lsb_get_lua(hsb->lsb); set_restrictions(lua, hsb); // todo link print to the logger or a no-op lsb_add_function(hsb->lsb, heka_decode_message, "decode_message"); lsb_add_function(hsb->lsb, read_message, "read_message"); lsb_add_function(hsb->lsb, inject_message_input, "inject_message"); // inject_payload is intentionally excluded from input plugins // you can construct whatever you need with inject_message // preload the Heka stream reader module luaL_findtable(lua, LUA_REGISTRYINDEX, "_PRELOADED", 1); lua_pushstring(lua, mozsvc_heka_stream_reader_table); lua_pushcfunction(lua, luaopen_heka_stream_reader); lua_rawset(lua, -3); lua_pop(lua, 1); // remove the preloaded table if (lsb_init(hsb->lsb, state_file)) { if (logger) logger(hsb->name, 3, lsb_get_error(hsb->lsb)); lsb_destroy(hsb->lsb); free(hsb->hostname); free(hsb->name); free(hsb); return NULL; } // remove output function lua_pushnil(lua); lua_setglobal(lua, "output"); return hsb; }
static char* test_output() { const char* outputs[] = { "{\"table\":{\"value\":1}}\n1.2 string nil true false" , "" #ifdef LUA_JIT , "{\"table\":{\"Timestamp\":0,\"Value\":0,\"StatisticValues\":[{\"SampleCount\":0,\"Sum\":0,\"Maximum\":0,\"Minimum\":0},{\"SampleCount\":0,\"Sum\":0,\"Maximum\":0,\"Minimum\":0}],\"Unit\":\"s\",\"MetricName\":\"example\",\"Dimensions\":[{\"Name\":\"d1\",\"Value\":\"v1\"},{\"Name\":\"d2\",\"Value\":\"v2\"}]}}\n" #else , "{\"table\":{\"StatisticValues\":[{\"Minimum\":0,\"SampleCount\":0,\"Sum\":0,\"Maximum\":0},{\"Minimum\":0,\"SampleCount\":0,\"Sum\":0,\"Maximum\":0}],\"Dimensions\":[{\"Name\":\"d1\",\"Value\":\"v1\"},{\"Name\":\"d2\",\"Value\":\"v2\"}],\"MetricName\":\"example\",\"Timestamp\":0,\"Value\":0,\"Unit\":\"s\"}}\n" #endif , "{\"table\":{\"a\":{\"y\":2,\"x\":1}}}\n" , "{\"table\":[1,2,3]}\n" , "{\"table\":{\"x\":1}}\n" , "{\"array\":[1,2,3]}\n" , "{\"table\":{}}\n" , "{\"table\":{\"special\\tcharacters\":\"\\\"\\t\\r\\n\\b\\f\\\\\\/\"}}\n" , "\x10\x80\x94\xeb\xdc\x03\x1a\x04\x74\x79\x70\x65\x22\x06\x6c\x6f\x67\x67\x65\x72\x28\x09\x32\x07\x70\x61\x79\x6c\x6f\x61\x64\x3a\x0b\x65\x6e\x76\x5f\x76\x65\x72\x73\x69\x6f\x6e\x4a\x08\x68\x6f\x73\x74\x6e\x61\x6d\x65" , "\x10\x80\x94\xeb\xdc\x03\x52\x12\x0a\x05\x63\x6f\x75\x6e\x74\x10\x03\x39\x00\x00\x00\x00\x00\x00\xf0\x3f" , "\x10\x80\x94\xeb\xdc\x03\x52\x25\x0a\x06\x63\x6f\x75\x6e\x74\x73\x10\x03\x39\x00\x00\x00\x00\x00\x00\x00\x40\x39\x00\x00\x00\x00\x00\x00\x08\x40\x39\x00\x00\x00\x00\x00\x00\x10\x40" , "\x10\x80\x94\xeb\xdc\x03\x52\x19\x0a\x05\x63\x6f\x75\x6e\x74\x10\x03\x1a\x05\x63\x6f\x75\x6e\x74\x39\x00\x00\x00\x00\x00\x00\x14\x40" , "\x10\x80\x94\xeb\xdc\x03\x52\x2c\x0a\x06\x63\x6f\x75\x6e\x74\x73\x10\x03\x1a\x05\x63\x6f\x75\x6e\x74\x39\x00\x00\x00\x00\x00\x00\x18\x40\x39\x00\x00\x00\x00\x00\x00\x1c\x40\x39\x00\x00\x00\x00\x00\x00\x20\x40" #ifdef LUA_JIT , "\x10\x80\x94\xeb\xdc\x03\x52\x13\x0a\x06\x6e\x75\x6d\x62\x65\x72\x10\x03\x39\x00\x00\x00\x00\x00\x00\xf0\x3f\x52\x0f\x0a\x05\x62\x6f\x6f\x6c\x73\x10\x04\x40\x01\x40\x00\x40\x00\x52\x10\x0a\x06\x73\x74\x72\x69\x6e\x67\x22\x06\x73\x74\x72\x69\x6e\x67\x52\x0a\x0a\x04\x62\x6f\x6f\x6c\x10\x04\x40\x01\x52\x2d\x0a\x07\x6e\x75\x6d\x62\x65\x72\x73\x10\x03\x1a\x05\x63\x6f\x75\x6e\x74\x39\x00\x00\x00\x00\x00\x00\xf0\x3f\x39\x00\x00\x00\x00\x00\x00\x00\x40\x39\x00\x00\x00\x00\x00\x00\x08\x40\x52\x15\x0a\x07\x73\x74\x72\x69\x6e\x67\x73\x22\x02\x73\x31\x22\x02\x73\x32\x22\x02\x73\x33" #else , "\x10\x80\x94\xeb\xdc\x03\x52\x13\x0a\x06\x6e\x75\x6d\x62\x65\x72\x10\x03\x39\x00\x00\x00\x00\x00\x00\xf0\x3f\x52\x2d\x0a\x07\x6e\x75\x6d\x62\x65\x72\x73\x10\x03\x1a\x05\x63\x6f\x75\x6e\x74\x39\x00\x00\x00\x00\x00\x00\xf0\x3f\x39\x00\x00\x00\x00\x00\x00\x00\x40\x39\x00\x00\x00\x00\x00\x00\x08\x40\x52\x0f\x0a\x05\x62\x6f\x6f\x6c\x73\x10\x04\x40\x01\x40\x00\x40\x00\x52\x0a\x0a\x04\x62\x6f\x6f\x6c\x10\x04\x40\x01\x52\x10\x0a\x06\x73\x74\x72\x69\x6e\x67\x22\x06\x73\x74\x72\x69\x6e\x67\x52\x15\x0a\x07\x73\x74\x72\x69\x6e\x67\x73\x22\x02\x73\x31\x22\x02\x73\x32\x22\x02\x73\x33" #endif , "\x10\x80\x94\xeb\xdc\x03\x52\x8d\x01\x0a\x06\x73\x74\x72\x69\x6e\x67\x22\x82\x01\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39" , NULL }; lua_sandbox* sb = lsb_create(NULL, "lua/output.lua", 100000, 1000, 63 * 1024); mu_assert(sb, "lsb_create() received: NULL"); int result = lsb_init(sb, NULL); mu_assert(result == 0, "lsb_init() received: %d %s", result, lsb_get_error(sb)); lsb_add_function(sb, &write_output, "write"); for (int x = 0; outputs[x]; ++x) { result = process(sb, x); mu_assert(!result, "process() failed: %d %s", result, lsb_get_error(sb)); if (outputs[x][0]) { if (outputs[x][0] == 0x10) { size_t header = 18; if (memcmp(outputs[x], written_data + header, written_data_len - header) != 0) { char hex_data[LSB_OUTPUT + 1]; size_t z = 0; for (size_t y = header; y < written_data_len; ++y, z += 3) { snprintf(hex_data + z, LSB_OUTPUT - z, "%02x ", (unsigned char)written_data[y]); } hex_data[z] = 0; mu_assert(0, "test: %d received: %s", x, hex_data); } } else { mu_assert(strcmp(outputs[x], written_data) == 0, "test: %d received: %s", x, written_data); } } } e = lsb_destroy(sb, "circular_buffer.preserve"); mu_assert(!e, "lsb_destroy() received: %s", e); return NULL; }