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; }
int report(lua_sandbox* lsb, double tc) { static const char* func_name = "report"; lua_State* lua = lsb_get_lua(lsb); if (!lua) return 1; if (lsb_pcall_setup(lsb, func_name)) return 1; lua_pushnumber(lua, tc); if (lua_pcall(lua, 1, 0, 0) != 0) { char err[LSB_ERROR_SIZE]; int len = snprintf(err, LSB_ERROR_SIZE, "%s() %s", func_name, lua_tostring(lua, -1)); if (len >= LSB_ERROR_SIZE || len < 0) { err[LSB_ERROR_SIZE - 1] = 0; } lsb_terminate(lsb, err); return 1; } lsb_pcall_teardown(lsb); lua_gc(lua, LUA_GCCOLLECT, 0); return 0; }
int lsb_heka_timer_event(lsb_heka_sandbox *hsb, time_t t, bool shutdown) { static const char *func_name = "timer_event"; if (!hsb || (hsb->type != 'o' && hsb->type != 'a')) { return 1; } lua_State *lua = lsb_get_lua(hsb->lsb); if (!lua) return 1; if (lsb_pcall_setup(hsb->lsb, func_name)) { char err[LSB_ERROR_SIZE]; snprintf(err, LSB_ERROR_SIZE, "%s() function was not found", func_name); lsb_terminate(hsb->lsb, err); return 1; } // todo change if we need more than 1 sec resolution lua_pushnumber(lua, t * 1e9); lua_pushboolean(lua, shutdown); unsigned long long start, end; start = lsb_get_time(); if (lua_pcall(lua, 2, 0, 0) != 0) { char err[LSB_ERROR_SIZE]; size_t len = snprintf(err, LSB_ERROR_SIZE, "%s() %s", func_name, lua_tostring(lua, -1)); if (len >= LSB_ERROR_SIZE) { err[LSB_ERROR_SIZE - 1] = 0; } lsb_terminate(hsb->lsb, err); return 1; } end = lsb_get_time(); lsb_update_running_stats(&hsb->stats.te, (double)(end - start)); lsb_pcall_teardown(hsb->lsb); lua_gc(lua, LUA_GCCOLLECT, 0); return 0; }
int process(lua_sandbox* lsb, double ts) { static const char* func_name = "process"; lua_State* lua = lsb_get_lua(lsb); if (!lua) return 1; if (lsb_pcall_setup(lsb, func_name)) return 1; lua_pushnumber(lua, ts); if (lua_pcall(lua, 1, 1, 0) != 0) { char err[LSB_ERROR_SIZE]; int len = snprintf(err, LSB_ERROR_SIZE, "%s() %s", func_name, lua_tostring(lua, -1)); if (len >= LSB_ERROR_SIZE || len < 0) { err[LSB_ERROR_SIZE - 1] = 0; } lsb_terminate(lsb, err); return 1; } if (!lua_isnumber(lua, 1)) { char err[LSB_ERROR_SIZE]; int len = snprintf(err, LSB_ERROR_SIZE, "%s() must return a single numeric value", func_name); if (len >= LSB_ERROR_SIZE || len < 0) { err[LSB_ERROR_SIZE - 1] = 0; } lsb_terminate(lsb, err); return 1; } int status = (int)lua_tointeger(lua, 1); lua_pop(lua, 1); lsb_pcall_teardown(lsb); return status; }
static int process_message(lsb_heka_sandbox *hsb, lsb_heka_message *msg, lua_State *lua, int nargs, bool profile) { unsigned long long start, end; hsb->msg = msg; if (profile) { start = lsb_get_time(); } if (lua_pcall(lua, nargs, 2, 0) != 0) { char err[LSB_ERROR_SIZE]; const char *em = lua_tostring(lua, -1); if (hsb->type == 'i' && strcmp(em, LSB_SHUTTING_DOWN) == 0) { return 0; } size_t len = snprintf(err, LSB_ERROR_SIZE, "%s() %s", pm_func_name, em); if (len >= LSB_ERROR_SIZE) { err[LSB_ERROR_SIZE - 1] = 0; } lsb_terminate(hsb->lsb, err); return 1; } if (profile) { end = lsb_get_time(); lsb_update_running_stats(&hsb->stats.pm, (double)(end - start)); } hsb->msg = NULL; if (lua_type(lua, 1) != LUA_TNUMBER) { char err[LSB_ERROR_SIZE]; size_t len = snprintf(err, LSB_ERROR_SIZE, "%s() must return a numeric status code", pm_func_name); if (len >= LSB_ERROR_SIZE) { err[LSB_ERROR_SIZE - 1] = 0; } lsb_terminate(hsb->lsb, err); return 1; } int status = (int)lua_tointeger(lua, 1); switch (lua_type(lua, 2)) { case LUA_TNIL: lsb_set_error(hsb->lsb, NULL); break; case LUA_TSTRING: lsb_set_error(hsb->lsb, lua_tostring(lua, 2)); break; default: { char err[LSB_ERROR_SIZE]; int len = snprintf(err, LSB_ERROR_SIZE, "%s() must return a nil or string error message", pm_func_name); if (len >= LSB_ERROR_SIZE || len < 0) { err[LSB_ERROR_SIZE - 1] = 0; } lsb_terminate(hsb->lsb, err); return 1; } break; } lua_pop(lua, 2); lsb_pcall_teardown(hsb->lsb); if (status > 0) { char err[LSB_ERROR_SIZE]; size_t len = snprintf(err, LSB_ERROR_SIZE, "%s() received a termination status code", pm_func_name); if (len >= LSB_ERROR_SIZE) { err[LSB_ERROR_SIZE - 1] = 0; } lsb_terminate(hsb->lsb, err); return 1; } else if (status == LSB_HEKA_PM_FAIL) { ++hsb->stats.pm_cnt; ++hsb->stats.pm_failures; } else if (hsb->type != 'o' || status != LSB_HEKA_PM_RETRY) { ++hsb->stats.pm_cnt; } return status; }