diff --git a/tests/.gitignore b/tests/.gitignore index ba74bfbb913d915e7e0a59efc8e1344f81638065..817c704ffab2d8c4b0d9b2a90f928b1828d6331d 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -20,4 +20,5 @@ foo simple_archiver simple_injector simple_group_injector +simple_telemetry_listener coverage \ No newline at end of file diff --git a/tests/Makefile.am b/tests/Makefile.am index b40b04224f18d190c7aaa772a1f8e3b5867e39f8..3a9fb1590f5055c0a86389c6ad289581ec961247 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -115,6 +115,7 @@ check_PROGRAMS = check_version check_init check_uuid \ simple_interlock_client_2 \ simple_injector \ simple_archiver \ + simple_telemetry_listener \ check_events \ coverage diff --git a/tests/simple_telemetry_listener.c b/tests/simple_telemetry_listener.c new file mode 100644 index 0000000000000000000000000000000000000000..795e48691a81b8bf5a13723bf7175a28b06a0708 --- /dev/null +++ b/tests/simple_telemetry_listener.c @@ -0,0 +1,170 @@ +/* Connect to pool and subscribe to all JOIN and all CDO ID creating + * events. Log them. */ +/* + * Copyright (C) 2020 Cray Computer GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* FIXME: set signal handler to flush log and stop cleanly */ + + +#include "maestro.h" +#include "maestro/i_statistics.h" + +#include <unistd.h> + +const mstro_nanosec_t MAX_WAIT = ((mstro_nanosec_t)15)*1000*1000*1000; /* 10s */ +int +main(int argc, char ** argv) +{ + /* FIXME: parse arguments */ + char *component_name = argv[0]; + + mstro_status s=mstro_init(NULL, component_name, 0); + + /* wildcard selector: any CDO */ + mstro_cdo_selector selector=NULL; + s=mstro_cdo_selector_create( + NULL, NULL, + "(has .maestro.core.cdo.name)", + &selector); + + + /* Subscribe to DECLARE and SEAL. + * + * That allows us to log app-id/name/local-id and later + * app-id/local-id/cdo-id + */ + mstro_subscription cdo_subscription=NULL; + s = mstro_subscribe(selector, + MSTRO_POOL_EVENT_DECLARE |MSTRO_POOL_EVENT_SEAL, + MSTRO_SUBSCRIPTION_OPTS_DEFAULT, + &cdo_subscription); + s=mstro_cdo_selector_dispose(selector); + + + /* Subscribe to JOIN and LEAVE. + * + * That allows us to log component names and implement a termination + * criterion like "if component X has left, terminate telemetry + * listener" */ + mstro_subscription join_leave_subscription=NULL; + s=mstro_subscribe( + NULL, + ( MSTRO_POOL_EVENT_APP_JOIN | MSTRO_POOL_EVENT_APP_LEAVE), + MSTRO_SUBSCRIPTION_OPTS_DEFAULT, + &join_leave_subscription); + + + bool done = false; + + mstro_nanosec_t starttime = mstro_clock(); + + /* instead of a busy loop we could use event wait sets -- but we + * don't have them yet */ + while(!done) { + mstro_pool_event e=NULL; + /* poll join/leave */ + s=mstro_subscription_poll(join_leave_subscription, &e); + + if(e!=NULL) { + fprintf(stdout, "JOIN/LEAVE event(s)\n"); + mstro_pool_event tmp=e; + /* handle all */ + while(tmp) { + switch(tmp->kind) { + case MSTRO_POOL_EVENT_APP_JOIN: + fprintf(stdout, "Noticed JOIN event of app %s\n", + tmp->join.component_name); + break; + case MSTRO_POOL_EVENT_APP_LEAVE: + fprintf(stdout, "Noticed LEAVE event of app %" PRIappid "\n", + tmp->leave.appid); + break; + default: + fprintf(stderr, "Unexpected event %d\n", tmp->kind); + } + fflush(stdout); + tmp=tmp->next; + } + + /* acknowledge all */ + s=mstro_subscription_ack(join_leave_subscription, e); + /* dispose all */ + s=mstro_pool_event_dispose(e); + } else { + s=mstro_subscription_poll(cdo_subscription, &e); + if(e!=NULL) { + mstro_pool_event tmp=e; + /* handle all */ + while(tmp) { + switch(tmp->kind) { + case MSTRO_POOL_EVENT_DECLARE: + case MSTRO_POOL_EVENT_SEAL: + fprintf(stdout, "CDO event %s\n", + mstro_pool_event_description(tmp->kind)); + break; + default: + fprintf(stderr, "Unexpected CDO event %d\n", tmp->kind); + } + tmp=tmp->next; + } + /* acknowledge all */ + s=mstro_subscription_ack(cdo_subscription, e); + /* dispose all */ + s=mstro_pool_event_dispose(e); + } else { + sleep(1); /* core will queue up events for us, no need to do + * intensive busy-loop */ + } + } + + if(mstro_clock()>starttime+MAX_WAIT) { + fprintf(stderr, "Waited %" PRIu64 "s and still not done\n", + MAX_WAIT/(1000*1000*1000)); + done=true; + } + if(done) + break; /* from WHILE */ + + } + s= mstro_subscription_dispose(cdo_subscription); + s= mstro_subscription_dispose(join_leave_subscription); + + +BAILOUT: + ; + mstro_status s1=mstro_finalize(); + + if(s1!=MSTRO_OK || s!=MSTRO_OK) + return EXIT_FAILURE; + else + return EXIT_SUCCESS; +} +