diff options
-rw-r--r-- | conf.d/controller/lua.d/aft.lua | 189 | ||||
-rw-r--r-- | src/aft.c | 10 | ||||
-rw-r--r-- | src/mapis.c | 24 |
3 files changed, 165 insertions, 58 deletions
diff --git a/conf.d/controller/lua.d/aft.lua b/conf.d/controller/lua.d/aft.lua index 918deb1..b9061fb 100644 --- a/conf.d/controller/lua.d/aft.lua +++ b/conf.d/controller/lua.d/aft.lua @@ -22,6 +22,14 @@ local lu = require('luaunit') lu.LuaUnit:setOutputType('JUNIT') lu.LuaUnit.fname = "xUnitResults.xml" +local function table_size(t) + local size = 0 + for _,_ in pairs(t) do + size = size + 1 + end + return size +end + _AFT = { exit = {0, code}, context = _ctx, @@ -98,71 +106,151 @@ function _AFT.registerData(dict, eventData) end end -function _AFT.requestDaemonEventHandler(eventObj) - local eventName = eventObj.data.message - local log = _AFT.monitored_events[eventName] - local api = nil - - if eventObj.daemon then - api = eventObj.daemon.api - elseif eventObj.request then - api = eventObj.request.api +function _AFT.bindingEventHandler(eventObj, uid) + local eventName = nil + local eventListeners = nil + local data = nil + + if uid then + eventName = uid + data = eventObj + elseif eventObj.event.name then + eventName = eventObj.event.name + eventListeners = eventObj.data.result + -- Remove from event to hold the bare event data and be able to assert it + eventObj.data.result = nil + data = eventObj.data end - if log and log.api == api and log.type == eventObj.data.type then + if type(_AFT.monitored_events[eventName]) == 'table' then + if eventListeners then + _AFT.monitored_events[eventName].eventListeners = eventListeners + end + _AFT.incrementCount(_AFT.monitored_events[eventName]) - _AFT.registerData(_AFT.monitored_events[eventName], eventObj.data) + _AFT.registerData(_AFT.monitored_events[eventName], data) end +end +function _evt_catcher_(source, action, eventObj) + local uid = AFB:getuid(source) + if uid == "monitor/trace" then + if eventObj.type == "event" then + _AFT.bindingEventHandler(eventObj) + end + else + _AFT.bindingEventHandler(eventObj, uid) + end end -function _AFT.bindingEventHandler(eventObj) - local eventName = eventObj.event.name - local eventListeners = eventObj.data.result +function _AFT.lockWait(eventName, timeout) + if type(eventName) ~= "string" then + print("Error: wrong argument given to wait an event. 1st argument should be a string") + return 0 + end - -- Remove from event to hold the bare event data and be able to assert it - eventObj.data.result = nil + local count = 0 + if _AFT.monitored_events[eventName].receivedCount and timeout then + count = _AFT.monitored_events[eventName].receivedCount + end - if type(_AFT.monitored_events[eventName]) == 'table' then - _AFT.monitored_events[eventName].eventListeners = eventListeners + while timeout > 0 do + timeout = AFB:lockwait(_AFT.context, timeout) + AFB:lockwait(_AFT.context, 0) --without it _evt_catcher_ cannot received event - _AFT.incrementCount(_AFT.monitored_events[eventName]) - _AFT.registerData(_AFT.monitored_events[eventName], eventObj.data) + if _AFT.monitored_events[eventName].receivedCount == count + 1 then + return 1 + end end + return 0 end -function _evt_catcher_ (source, action, eventObj) - if eventObj.type == "event" then - _AFT.bindingEventHandler(eventObj) - elseif eventObj.type == "daemon" or eventObj.type == "request" then - _AFT.requestDaemonEventHandler(eventObj) +function _AFT.lockWaitGroup(eventGroup, timeout) + if type(eventGroup) ~= "table" then + print("Error: wrong argument given to wait a group of events. 1st argument should be a table") + return 0 + end + local eventGroupCpy = {table.unpack(eventGroup)} + + while timeout > 0 do + timeout = AFB:lockwait(_AFT.context, timeout) + AFB:lockwait(_AFT.context, 0) --without it _evt_catcher_ cannot received event + + for key,event in pairs(eventGroupCpy) do + if _AFT.monitored_events[event.name].receivedCount == event.receivedCount + 1 then + eventGroupCpy[key] = nil + end + end + if table_size(eventGroupCpy) == 0 then return 1 end end + return 0 end --[[ Assert and test functions about the event part. ]] -function _AFT.lockwait(eventName, timeout) - local count = 0 - if _AFT.monitored_events[eventName].receivedCount then - if timeout then - count = _AFT.monitored_events[eventName].receivedCount - end +function _AFT.assertEvtGrpNotReceived(eventGroup, timeout) + local count = 0 + local eventName = "" + for _,event in pairs(eventGroup) do + eventGroup[key] = {name = event, receivedCount = _AFT.monitored_events[event].receivedCount} end - while timeout > 0 do - timeout = AFB:lockwait(_AFT.context, timeout) - AFB:lockwait(_AFT.context, 0) --without it ev catcher cannot received event - if _AFT.monitored_events[eventName].receivedCount == count + 1 then - return 1 - end - end - return 0 + if timeout then + count = _AFT.lockWaitGroup(eventGroup, timeout) + else + for _,v in pairs(eventGroup) do + count = count + v.count + end + end + + for _,event in pairs(eventGroup) do + eventName = eventName .. " " .. event.name + end + _AFT.assertIsTrue(count == 0, "One of the following events has been received: '".. eventName .."' but it shouldn't") + + for _,event in pairs(eventGroup) do + if _AFT.monitored_events[event.name].cb then + local data_n = table_size(_AFT.monitored_events[event.name].data) + _AFT.monitored_events[event.name].cb(v.name, _AFT.monitored_events[event.name].data[data_n]) + end + end +end + +function _AFT.assertEvtGrpReceived(eventGroup, timeout) + local count = 0 + local eventName = "" + for key,event in pairs(eventGroup) do + eventGroup[key] = {name = event, receivedCount = _AFT.monitored_events[event].receivedCount} + end + + if timeout then + count = _AFT.lockWaitGroup(eventGroup, timeout) + else + for _,v in pairs(eventGroup) do + count = count + v.receivedCount + end + end + + for _,event in pairs(eventGroup) do + eventName = eventName .. " " .. event.name + end + _AFT.assertIsTrue(count >= table_size(eventGroup), "None or one of the following events: '".. eventName .."' has not been received") + + for _,event in pairs(eventGroup) do + if _AFT.monitored_events[event.name].cb then + local data_n = table_size(_AFT.monitored_events[event.name].data) + _AFT.monitored_events[event.name].cb(v.name, _AFT.monitored_events[event.name].data[data_n]) + end + end end function _AFT.assertEvtNotReceived(eventName, timeout) - local count = _AFT.lockwait(eventName, timeout) + local count = _AFT.monitored_events[eventName].receivedCount + if timeout then + count = _AFT.lockWait(eventName, timeout) + end _AFT.assertIsTrue(count == 0, "Event '".. eventName .."' received but it shouldn't") @@ -173,7 +261,10 @@ function _AFT.assertEvtNotReceived(eventName, timeout) end function _AFT.assertEvtReceived(eventName, timeout) - local count = _AFT.lockwait(eventName, timeout) + local count = _AFT.monitored_events[eventName].receivedCount + if timeout then + count = _AFT.lockWait(eventName, timeout) + end _AFT.assertIsTrue(count > 0, "No event '".. eventName .."' received") @@ -460,8 +551,10 @@ local function call_tests() local failures="Failures : "..tostring(lu.LuaUnit.result.testCount-lu.LuaUnit.result.passedCount) local evtHandle = AFB:evtmake(_AFT.context, 'results') - AFB:subscribe(_AFT.context,evtHandle) - AFB:evtpush(_AFT.context,evtHandle,{info = success.." "..failures}) + if type(evtHandle) == "userdata" then + AFB:subscribe(_AFT.context,evtHandle) + AFB:evtpush(_AFT.context,evtHandle,{info = success.." "..failures}) + end end function _launch_test(context, args) @@ -470,7 +563,15 @@ function _launch_test(context, args) -- Prepare the tests execution configuring the monitoring and loading -- lua test files to execute in the Framework. AFB:servsync(_AFT.context, "monitor", "set", { verbosity = "debug" }) - AFB:servsync(_AFT.context, "monitor", "trace", { add = { api = args.trace, request = "vverbose", event = "push_after" }}) + if type(args.trace) == "string" then + AFB:servsync(_AFT.context, "monitor", "trace", { add = { api = args.trace, request = "vverbose", event = "push_after" }}) + elseif type(args.trace) == "table" then + for _,v in pairs(args.trace) do + if type(v) == "string" then + AFB:servsync(_AFT.context, "monitor", "trace", { add = { api = v, request = "vverbose", event = "push_after" }}) + end + end + end if args.files and type(args.files) == 'table' then for _,f in pairs(args.files) do dofile('var/'..f) @@ -62,7 +62,7 @@ static AFB_ApiVerbs CtrlApiVerbs[] = { static int CtrlLoadStaticVerbs(afb_dynapi *apiHandle, AFB_ApiVerbs *verbs) { int errcount = 0; - for (int idx = 0; verbs[idx].verb; idx++) { + for(int idx = 0; verbs[idx].verb; idx++) { errcount += afb_dynapi_add_verb( apiHandle, CtrlApiVerbs[idx].verb, NULL, CtrlApiVerbs[idx].callback, (void *)&CtrlApiVerbs[idx], CtrlApiVerbs[idx].auth, 0); @@ -91,7 +91,7 @@ static int CtrlLoadOneApi(void *cbdata, AFB_ApiT apiHandle) { // add static controls verbs int err = CtrlLoadStaticVerbs(apiHandle, CtrlApiVerbs); - if (err) { + if(err) { AFB_ApiError(apiHandle, "CtrlLoadSection fail to register static V2 verbs"); return ERROR; } @@ -132,21 +132,21 @@ int afbBindingEntry(afb_dynapi *apiHandle) { } configPath = CtlConfigSearch(apiHandle, dirList, prefix); - if (!configPath) { + if(!configPath) { AFB_ApiError(apiHandle, "CtlPreInit: No %s* config found in %s ", GetBinderName(), dirList); return ERROR; } // load config file and create API ctrlConfig = CtlLoadMetaDataUsingPrefix(apiHandle, configPath, prefix); - if (!ctrlConfig) { + if(!ctrlConfig) { AFB_ApiError(apiHandle, "CtrlBindingDyn No valid control config file in:\n-- %s", configPath); return ERROR; } - if (!ctrlConfig->api) { + if(!ctrlConfig->api) { AFB_ApiError(apiHandle, "CtrlBindingDyn API Missing from metadata in:\n-- %s", configPath); diff --git a/src/mapis.c b/src/mapis.c index 145c01f..64543e5 100644 --- a/src/mapis.c +++ b/src/mapis.c @@ -16,8 +16,9 @@ * limitations under the License. */ +#include <string.h> #include <mapis.h> -#include <ctl-plugin.h> +#include <ctl-config.h> struct mapisHandleT { AFB_ApiT mainApiHandle; @@ -27,11 +28,11 @@ struct mapisHandleT { json_object *eventsJ; }; -static int LoadOneMapi(void *data, AFB_ApiT apiHandle) -{ - int savedCount = 0, count = 0; +static int LoadOneMapi(void *data, AFB_ApiT apiHandle) { + int savedCount = 0, count = 0, idx = 0; CtlActionT *savedActions = NULL, *newActions = NULL; struct mapisHandleT *mapisHandle = (struct mapisHandleT*)data; + CtlConfigT *ctrlConfig = afb_dynapi_get_userdata(mapisHandle->mainApiHandle); if(PluginConfig(apiHandle, mapisHandle->section, mapisHandle->mapiJ)) { AFB_ApiError(apiHandle, "Problem loading the plugin as an API for %s, see log message above", json_object_get_string(mapisHandle->mapiJ)); @@ -45,7 +46,12 @@ static int LoadOneMapi(void *data, AFB_ApiT apiHandle) } // Add actions to the section to be able to respond to defined events. - savedActions = mapisHandle->section->actions; + for(idx = 0; ctrlConfig->sections[idx].key != NULL; ++idx) { + if(! strcasecmp(ctrlConfig->sections[idx].key, "events")) { + savedActions = ctrlConfig->sections[idx].actions; + break; + } + } newActions = ActionConfig(apiHandle, mapisHandle->eventsJ, 0); if(savedActions) { @@ -71,10 +77,10 @@ static int LoadOneMapi(void *data, AFB_ApiT apiHandle) while(newActions[savedCount].uid != NULL && count <= total) { mergedActions[count] = newActions[savedCount]; count++; - savedActions++; + savedCount++; } - mapisHandle->section->actions = mergedActions; + ctrlConfig->sections[idx].actions = mergedActions; // declare an event event manager for this API; afb_dynapi_on_event(apiHandle, CtrlDispatchApiEvent); @@ -96,8 +102,8 @@ static void OneMapiConfig(void *data, json_object *mapiJ) { "lua", NULL, "verbs", &mapisHandle->verbsJ, "events", &mapisHandle->eventsJ)) { - AFB_ApiError(mapisHandle->mainApiHandle, "Wrong mapis specification, missing uid|[info]|[spath]|libs|[lua]|verbs|[events] for %s", json_object_get_string(mapiJ)); - return; + AFB_ApiError(mapisHandle->mainApiHandle, "Wrong mapis specification, missing uid|[info]|[spath]|libs|[lua]|verbs|[events] for %s", json_object_get_string(mapiJ)); + return; } json_object_get(mapisHandle->verbsJ); |