From 6928974a9357b1de963b72428e397f508328c175 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 9 Mar 2021 15:48:09 -0500 Subject: [PATCH] lua: added integration tests and a few bug fixes --- lib/hooks/lua.cpp | 31 +++++--- tests/integration/hook-lua.sh | 82 ++++++++++++++++++++ tests/integration/hook-lua_script.sh | 112 +++++++++++++++++++++++++++ 3 files changed, 216 insertions(+), 9 deletions(-) create mode 100755 tests/integration/hook-lua.sh create mode 100755 tests/integration/hook-lua_script.sh diff --git a/lib/hooks/lua.cpp b/lib/hooks/lua.cpp index 2d0d60fbc..fe9a4eaec 100644 --- a/lib/hooks/lua.cpp +++ b/lib/hooks/lua.cpp @@ -148,24 +148,32 @@ lua_tosignaldata(lua_State *L, union signal_data *data, enum SignalType targetTy static void lua_tosample(lua_State *L, struct sample *smp, struct vlist *signals, bool use_names = true, int idx = -1) { - lua_getfield(L, idx, "sequence"); - smp->sequence = lua_tonumber(L, -1); - lua_pop(L, 1); + int ret; - lua_getfield(L, idx, "flags"); - smp->flags = lua_tonumber(L, -1); + smp->flags = 0; + + ret = lua_getfield(L, idx, "sequence"); + if (ret != LUA_TNIL) { + smp->sequence = lua_tonumber(L, -1); + smp->flags |= (int) SampleFlags::HAS_SEQUENCE; + } lua_pop(L, 1); lua_getfield(L, idx, "ts_origin"); - lua_totimespec(L, &smp->ts.origin); + if (ret != LUA_TNIL) { + lua_totimespec(L, &smp->ts.origin); + smp->flags |= (int) SampleFlags::HAS_TS_ORIGIN; + } lua_pop(L, 1); lua_getfield(L, idx, "ts_received"); - lua_totimespec(L, &smp->ts.received); + if (ret != LUA_TNIL) { + lua_totimespec(L, &smp->ts.received); + smp->flags |= (int) SampleFlags::HAS_TS_RECEIVED; + } lua_pop(L, 1); lua_getfield(L, idx, "data"); - for (unsigned i = 0; i < smp->length; i++) { struct signal *sig = (struct signal *) vlist_at(signals, i); @@ -178,8 +186,10 @@ lua_tosample(lua_State *L, struct sample *smp, struct vlist *signals, bool use_n lua_pop(L, 1); } - lua_pop(L, 1); + + if (smp->length > 0) + smp->flags |= (int) SampleFlags::HAS_DATA; } static void @@ -534,6 +544,9 @@ LuaHook::loadScript() { int ret; + if (script.empty()) + return; /* No script given. */ + ret = luaL_loadfile(L, script.c_str()); if (ret) throw LuaError(L, ret); diff --git a/tests/integration/hook-lua.sh b/tests/integration/hook-lua.sh new file mode 100755 index 000000000..51772008e --- /dev/null +++ b/tests/integration/hook-lua.sh @@ -0,0 +1,82 @@ +#!/bin/bash +# +# Integration test for scale hook. +# +# @author Steffen Vogel +# @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC +# @license GNU General Public License (version 3) +# +# VILLASnode +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +################################################################################## + +INPUT_FILE=$(mktemp) +OUTPUT_FILE=$(mktemp) +EXPECT_FILE=$(mktemp) +CONFIG_FILE=$(mktemp) + +cat < ${CONFIG_FILE} +{ + "signals": [ + { "name": "signal1_positive", "expression": "smp.data.signal1 >= 0", "type": "boolean" }, + { "name": "abs(signal1)", "expression": "math.abs(smp.data.signal1)" }, + { "name": "signal4_scaled", "expression": "smp.data.signal4 * 100 + 55" }, + { "name": "sequence", "expression": "smp.sequence", "type": "integer" }, + { "name": "ts_origin", "expression": "smp.ts_origin[0] + smp.ts_origin[1] * 1e-9" } + ] +} +EOF + +cat < ${INPUT_FILE} +# seconds.nanoseconds(sequence) random sine square triangle ramp +1551015508.801653200(0) 0.022245 0.000000 -1.000000 1.000000 0.000000 +1551015508.901653200(1) 0.015339 0.587785 -1.000000 0.600000 0.100000 +1551015509.001653200(2) 0.027500 0.951057 -1.000000 0.200000 0.200000 +1551015509.101653200(3) 0.040320 0.951057 -1.000000 -0.200000 0.300000 +1551015509.201653200(4) 0.026079 0.587785 -1.000000 -0.600000 0.400000 +1551015509.301653200(5) 0.049262 0.000000 1.000000 -1.000000 0.500000 +1551015509.401653200(6) 0.014883 -0.587785 1.000000 -0.600000 0.600000 +1551015509.501653200(7) 0.023232 -0.951057 1.000000 -0.200000 0.700000 +1551015509.601653200(8) 0.015231 -0.951057 1.000000 0.200000 0.800000 +1551015509.701653200(9) 0.060849 -0.587785 1.000000 0.600000 0.900000 +EOF + +cat < ${EXPECT_FILE} +# seconds.nanoseconds+offset(sequence) signal1_positive abs(signal1) signal4_scaled sequence ts_origin +1551015508.801653200+6.430676e+07(0) 1 0.000000 55.000000 0 1551015508.801653 +1551015508.901653200+6.430676e+07(1) 1 0.587785 65.000000 1 1551015508.901653 +1551015509.001653200+6.430676e+07(2) 1 0.951057 75.000000 2 1551015509.001653 +1551015509.101653200+6.430676e+07(3) 1 0.951057 85.000000 3 1551015509.101653 +1551015509.201653200+6.430676e+07(4) 1 0.587785 95.000000 4 1551015509.201653 +1551015509.301653200+6.430676e+07(5) 1 0.000000 105.000000 5 1551015509.301653 +1551015509.401653200+6.430676e+07(6) 0 0.587785 115.000000 6 1551015509.401653 +1551015509.501653200+6.430676e+07(7) 0 0.951057 125.000000 7 1551015509.501653 +1551015509.601653200+6.430676e+07(8) 0 0.951057 135.000000 8 1551015509.601653 +1551015509.701653200+6.430676e+07(9) 0 0.587785 145.000000 9 1551015509.701653 +EOF + +villas-hook lua -c ${CONFIG_FILE} < ${INPUT_FILE} > ${OUTPUT_FILE} + +cat ${INPUT_FILE} +echo +cat ${OUTPUT_FILE} + +# Compare only the data values +villas-test-cmp ${OUTPUT_FILE} ${EXPECT_FILE} +RC=$? + +rm -f ${INPUT_FILE} ${OUTPUT_FILE} ${EXPECT_FILE} ${CONFIG_FILE} + +exit ${RC} diff --git a/tests/integration/hook-lua_script.sh b/tests/integration/hook-lua_script.sh new file mode 100755 index 000000000..aa8eec655 --- /dev/null +++ b/tests/integration/hook-lua_script.sh @@ -0,0 +1,112 @@ +#!/bin/bash +# +# Integration test for scale hook. +# +# @author Steffen Vogel +# @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC +# @license GNU General Public License (version 3) +# +# VILLASnode +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +################################################################################## + +INPUT_FILE=$(mktemp) +OUTPUT_FILE=$(mktemp) +EXPECT_FILE=$(mktemp) +CONFIG_FILE=$(mktemp) +SCRIPT_FILE=$(mktemp) + +cat < ${SCRIPT_FILE} +global_var = 555 +counter = 111 + +function prepare(cfg) + assert(true) + assert(cfg.custom.variable - 123.456 < 1e-9) + assert(cfg.custom.list[0] == 1) + assert(cfg.custom.list[1] - 2.0 < 1e-9) + assert(cfg.custom.list[2] == true) +end + +function start() + counter = 0 +end + +function process(smp) + assert(counter == smp.sequence) + + counter = counter + 1 + + smp.data.signal1 = smp.data.signal2 + smp.data.signal3 + + return 0 +end +EOF + +cat < ${CONFIG_FILE} +{ + "script": "${SCRIPT_FILE}", + "custom": { + "variable": 123.456, + "list": [1, 2.0, true] + }, + "signals": [ + { "name": "global_var", "expression": "global_var" }, + { "name": "counter", "expression": "counter" }, + { "name": "signal1", "expression": "smp.data.signal1" }, + { "name": "ts_origin.sec", "expression": "smp.ts_origin.sec" }, + { "name": "ts_origin.sec", "expression": "smp.ts_origin.nsec" }, + { "name": "sequence", "expression": "smp.sequence" } + ] +} +EOF + +cat < ${INPUT_FILE} +# seconds.nanoseconds(sequence) random sine square triangle ramp +1551015508.801653200(0) 0.022245 0.000000 -1.000000 1.000000 0.000000 +1551015508.901653200(1) 0.015339 0.587785 -1.000000 0.600000 0.100000 +1551015509.001653200(2) 0.027500 0.951057 -1.000000 0.200000 0.200000 +1551015509.101653200(3) 0.040320 0.951057 -1.000000 -0.200000 0.300000 +1551015509.201653200(4) 0.026079 0.587785 -1.000000 -0.600000 0.400000 +1551015509.301653200(5) 0.049262 0.000000 1.000000 -1.000000 0.500000 +1551015509.401653200(6) 0.014883 -0.587785 1.000000 -0.600000 0.600000 +1551015509.501653200(7) 0.023232 -0.951057 1.000000 -0.200000 0.700000 +1551015509.601653200(8) 0.015231 -0.951057 1.000000 0.200000 0.800000 +1551015509.701653200(9) 0.060849 -0.587785 1.000000 0.600000 0.900000 +EOF + +cat < ${EXPECT_FILE} +# seconds.nanoseconds+offset(sequence) global_var counter signal1 ts_origin.sec ts_origin.sec sequence +1551015508.801653200+6.430638e+07(0) 555.000000 1.000000 0.000000 1.000000 0.000000 0.000000 +1551015508.901653200+6.430638e+07(1) 555.000000 2.000000 -0.400000 0.600000 0.100000 1.000000 +1551015509.001653200+6.430638e+07(2) 555.000000 3.000000 -0.800000 0.200000 0.200000 2.000000 +1551015509.101653200+6.430638e+07(3) 555.000000 4.000000 -1.200000 -0.200000 0.300000 3.000000 +1551015509.201653200+6.430638e+07(4) 555.000000 5.000000 -1.600000 -0.600000 0.400000 4.000000 +1551015509.301653200+6.430638e+07(5) 555.000000 6.000000 0.000000 -1.000000 0.500000 5.000000 +1551015509.401653200+6.430638e+07(6) 555.000000 7.000000 0.400000 -0.600000 0.600000 6.000000 +1551015509.501653200+6.430638e+07(7) 555.000000 8.000000 0.800000 -0.200000 0.700000 7.000000 +1551015509.601653200+6.430638e+07(8) 555.000000 9.000000 1.200000 0.200000 0.800000 8.000000 +1551015509.701653200+6.430638e+07(9) 555.000000 10.000000 1.600000 0.600000 0.900000 9.000000 +EOF + +villas-hook lua -c ${CONFIG_FILE} < ${INPUT_FILE} > ${OUTPUT_FILE} + +# Compare only the data values +villas-test-cmp ${OUTPUT_FILE} ${EXPECT_FILE} +RC=$? + +rm -f ${INPUT_FILE} ${OUTPUT_FILE} ${EXPECT_FILE} ${CONFIG_FILE} + +exit ${RC}