From ba2e1cd2d25d50ab2636a6283521842438b610c8 Mon Sep 17 00:00:00 2001 From: Antoine Merle Date: Mon, 25 Nov 2024 11:21:22 +0100 Subject: [PATCH 1/3] Fix: dispatching any action causes actmon/actlog to crash with SIGSEGV * Rename Svr -> Srv * Always use 2 arguments for callback_done signature --- actions/actmon.c | 1 - include/servershr.h | 8 ++++---- servershr/Client.h | 4 ++-- servershr/Job.h | 14 +++++++------- servershr/ServerCreatePulse.c | 2 +- servershr/ServerDispatchAction.c | 2 +- servershr/ServerDispatchCommand.c | 2 +- servershr/ServerDispatchPhase.c | 8 ++++---- servershr/ServerMonitorCheckin.c | 2 +- servershr/ServerQAction.c | 32 +++++++++++++++---------------- servershr/ServerSendMessage.c | 6 +++--- servershr/servershrp.h | 26 ++++++++++++------------- tcl/tcl_dispatch.c | 2 +- 13 files changed, 54 insertions(+), 55 deletions(-) diff --git a/actions/actmon.c b/actions/actmon.c index 9a05a3043d..c585ca35ed 100644 --- a/actions/actmon.c +++ b/actions/actmon.c @@ -66,7 +66,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include static void Exit(Widget w, int *tag, XtPointer callback_data); -static void MessageAst(); static void EventUpdate(); static void Phase(LinkedEvent *event); static void Dispatched(LinkedEvent *event); diff --git a/include/servershr.h b/include/servershr.h index 2e4ba4b3b9..7677304973 100644 --- a/include/servershr.h +++ b/include/servershr.h @@ -28,17 +28,17 @@ EXPORT extern int ServerBuildDispatchTable(char *wildcard, char *monitor_name, void **table); EXPORT extern int ServerCloseTrees(char *server); EXPORT extern int ServerCreatePulse(int *id, char *server, char *tree, int shot, - void (*ast)(), void *astprm, int *retstatus, + void (*ast)(void *, char *), void *astprm, int *retstatus, pthread_rwlock_t *lock, void (*before_ast)()); EXPORT extern int ServerDispatchAction(int *id, char *server, char *tree, - int shot, int nid, void (*ast)(), + int shot, int nid, void (*ast)(void *, char *), void *astprm, int *retstatus, pthread_rwlock_t *lock, int *socket, void (*before_ast)()); EXPORT extern int ServerDispatchClose(void *vtable); EXPORT extern int ServerDispatchCommand(int *id, char *server, char *cli, - char *command, void (*ast)(), + char *command, void (*ast)(void *, char *), void *astprm, int *retstatus, pthread_rwlock_t *lock, void (*before_ast)()); @@ -51,7 +51,7 @@ EXPORT extern int ServerDispatchPhase(int *id, void *vtable, char *phasenam, const char *monitor); EXPORT extern int ServerFailedEssential(void *vtable, int reset); EXPORT extern char *ServerFindServers(void **ctx, char *wild_match); -EXPORT extern int ServerMonitorCheckin(char *server, void (*ast)(), +EXPORT extern int ServerMonitorCheckin(char *server, void (*ast)(void *, char *), void *astparam); EXPORT extern int ServerSetLogging(char *server, char logging_mode); EXPORT extern int ServerStartServer(char *server); diff --git a/servershr/Client.h b/servershr/Client.h index f213582749..0f7c45a8b7 100644 --- a/servershr/Client.h +++ b/servershr/Client.h @@ -108,7 +108,7 @@ static void Client_cleanup_jobs(Client *c, fd_set *fdactive) Job *j = Job_pop_by_conid(conid); if (j) { - Job_callback_done(j, ServerPATH_DOWN, FALSE); + Job_callback_done(j, ServerPATH_DOWN, NULL, FALSE); free(j); } else @@ -198,7 +198,7 @@ static void Client_do_message(Client *c, fd_set *fdactive) j = Job_get_by_jobid(MonJob); if (j) { - Job_callback_done(j, status, TRUE); + Job_callback_done(j, status, msg, TRUE); } else { diff --git a/servershr/Job.h b/servershr/Job.h index dc1aa79990..ccdaae7377 100644 --- a/servershr/Job.h +++ b/servershr/Job.h @@ -11,7 +11,7 @@ typedef struct job int conid; int *retstatus; pthread_rwlock_t *lock; - void (*callback_done)(); + void (*callback_done)(void *, char*); void (*callback_before)(); void *callback_param; pthread_cond_t *cond; @@ -30,7 +30,7 @@ static Job *Jobs = NULL; static int MonJob = -1; static Job *newJob(int conid, int *retstatus, pthread_rwlock_t *lock, - void (*callback_done)(void *), + void (*callback_done)(void *, char *), void *callback_param, void (*callback_before)(void *)) { @@ -71,7 +71,7 @@ static void Job_pop(Job *job) static int Job_register(int *msgid, int conid, int *retstatus, pthread_rwlock_t *lock, void *callback_param, - void (*callback_done)(void *), + void (*callback_done)(void *, char *), void (*callback_before)(void *)) { Job *j = newJob(conid, retstatus, lock, callback_param, callback_done, callback_before); @@ -107,10 +107,10 @@ static void Job_callback_before(Job *job) } /// returns true if job was popped -static int Job_callback_done(Job *j, int status, int remove) +static int Job_callback_done(Job *j, int status, char *msg, int remove) { MDSDBG(JOB_PRI " status=%d, remove=%d", JOB_VAR(j), status, remove); - void (*callback_done)(void *); + void (*callback_done)(void *, char *); const int is_mon = j->jobid == MonJob; if (j->lock) pthread_rwlock_wrlock(j->lock); @@ -122,7 +122,7 @@ static int Job_callback_done(Job *j, int status, int remove) if (j->lock) pthread_rwlock_unlock(j->lock); if (callback_done) - callback_done(j->callback_param); + callback_done(j->callback_param, msg); /**** If job has a condition, RemoveJob will not remove it. ***/ if (remove && !is_mon) { @@ -258,7 +258,7 @@ static void Job_cleanup(int status, int jobid) do { MDSDBG(JOB_PRI " done", JOB_VAR(j)); - Job_callback_done(j, status, FALSE); + Job_callback_done(j, status, NULL, FALSE); free(j); j = Job_pop_by_conid(conid); } while (j); diff --git a/servershr/ServerCreatePulse.c b/servershr/ServerCreatePulse.c index 3e9b8b53e6..6dd0777365 100644 --- a/servershr/ServerCreatePulse.c +++ b/servershr/ServerCreatePulse.c @@ -59,7 +59,7 @@ dsc$descriptor *tree, int *shot, void (*ast)(), int astprm, int *netid, void #include "servershrp.h" EXPORT int ServerCreatePulse(int *id, char *server, char *tree, int shot, - void (*ast)(), void *astprm, int *retstatus, + void (*ast)(void *, char *), void *astprm, int *retstatus, pthread_rwlock_t *lock, void (*before_ast)()) { struct descrip p1, p2; diff --git a/servershr/ServerDispatchAction.c b/servershr/ServerDispatchAction.c index cdba034100..96a8f8e21e 100644 --- a/servershr/ServerDispatchAction.c +++ b/servershr/ServerDispatchAction.c @@ -59,7 +59,7 @@ dsc$descriptor *tree, int *shot, int *nid, void (*ast)(), int astprm, int #include "servershrp.h" EXPORT int ServerDispatchAction(int *id, char *server, char *tree, int shot, - int nid, void (*ast)(), void *astprm, + int nid, void (*ast)(void *, char*), void *astprm, int *retstatus, pthread_rwlock_t *lock, int *socket, void (*before_ast)()) { diff --git a/servershr/ServerDispatchCommand.c b/servershr/ServerDispatchCommand.c index 7151ea0b3b..35bbec702c 100644 --- a/servershr/ServerDispatchCommand.c +++ b/servershr/ServerDispatchCommand.c @@ -59,7 +59,7 @@ int *netid, void (*link_down)(), void (*before_ast)()) #include "servershrp.h" EXPORT int ServerDispatchCommand(int *id, char *server, char *cli, - char *command, void (*ast)(), void *astprm, + char *command, void (*ast)(void *, char *), void *astprm, int *retstatus, pthread_rwlock_t *lock, void (*before_ast)()) { diff --git a/servershr/ServerDispatchPhase.c b/servershr/ServerDispatchPhase.c index 300ac6001e..dbb32649c7 100644 --- a/servershr/ServerDispatchPhase.c +++ b/servershr/ServerDispatchPhase.c @@ -86,7 +86,7 @@ extern int ProgLoc; static void dispatch(int idx); static void send_monitor(int mode, int idx); -static void action_done(intptr_t idx); +static void action_done(); static void action_done_action_locked(int idx); static void action_done_action_unlocked(int idx); static void before(int idx); @@ -723,7 +723,7 @@ static void action_done_action_unlocked(int idx) UNLOCK_ACTION(cidx, ad_fte); WRLOCK_ACTION(cidx, ad_fte); actions[cidx].status = ServerINVALID_DEPENDENCY; - action_done(cidx); + action_done(cidx, NULL); UNLOCK_ACTION(cidx, ad_fte); action_done_action_unlocked(cidx); } @@ -836,7 +836,7 @@ static void action_done_thread() pthread_cleanup_pop(1); } -static void action_done(intptr_t i) +static void action_done(intptr_t i, char *dummy __attribute__((unused))) { INIT_STATUS; static pthread_t thread; @@ -846,7 +846,7 @@ static void action_done(intptr_t i) perror("action_done: pthread creation failed"); } #else -static inline void action_done(intptr_t i) +static inline void action_done(intptr_t i, char *dummy __attribute__((unused))) { return action_done_do(i); } diff --git a/servershr/ServerMonitorCheckin.c b/servershr/ServerMonitorCheckin.c index fa1971c9a9..2e1414f2ee 100644 --- a/servershr/ServerMonitorCheckin.c +++ b/servershr/ServerMonitorCheckin.c @@ -101,7 +101,7 @@ static inline int using_events(char *server, void (*ast)(), void *astprm) return yesno; } -EXPORT int ServerMonitorCheckin(char *server, void (*ast)(), void *astprm) +EXPORT int ServerMonitorCheckin(char *server, void (*ast)(void *, char *), void *astprm) { if (using_events(server, ast, astprm)) return MDSplusSUCCESS; diff --git a/servershr/ServerQAction.c b/servershr/ServerQAction.c index 1f32e5ce58..812a6677d8 100644 --- a/servershr/ServerQAction.c +++ b/servershr/ServerQAction.c @@ -196,12 +196,12 @@ EXPORT int ServerQAction(uint32_t *addrp, uint16_t *portp, int *op, int *flags, job.nid = *(int *)p3; if (job.h.addr) { - MDSDBG(SVRACTIONJOB_PRI, SVRACTIONJOB_VAR(&job)); + MDSDBG(SRVACTIONJOB_PRI, SRVACTIONJOB_VAR(&job)); status = QJob((SrvJob *)&job); } else { - MDSWRN(SVRACTIONJOB_PRI " No Addr", SVRACTIONJOB_VAR(&job)); + MDSWRN(SRVACTIONJOB_PRI " No Addr", SRVACTIONJOB_VAR(&job)); status = DoSrvAction((SrvJob *)&job); } break; @@ -217,12 +217,12 @@ EXPORT int ServerQAction(uint32_t *addrp, uint16_t *portp, int *op, int *flags, job.h.jobid = *jobid; if (job.h.addr) { - MDSDBG(SVRCLOSEJOB_PRI, SVRCLOSEJOB_VAR(&job)); + MDSDBG(SRVCLOSEJOB_PRI, SRVCLOSEJOB_VAR(&job)); status = QJob((SrvJob *)&job); } else { - MDSWRN(SVRCLOSEJOB_PRI " No Addr", SVRCLOSEJOB_VAR(&job)); + MDSWRN(SRVCLOSEJOB_PRI " No Addr", SRVCLOSEJOB_VAR(&job)); status = DoSrvClose((SrvJob *)&job); } break; @@ -240,12 +240,12 @@ EXPORT int ServerQAction(uint32_t *addrp, uint16_t *portp, int *op, int *flags, job.shot = *(int *)p2; if (job.h.addr) { - MDSDBG(SVRCREATEPULSEJOB_PRI, SVRCREATEPULSEJOB_VAR(&job)); + MDSDBG(SRVCREATEPULSEJOB_PRI, SRVCREATEPULSEJOB_VAR(&job)); status = QJob((SrvJob *)&job); } else { - MDSWRN(SVRCREATEPULSEJOB_PRI " No Addr", SVRCREATEPULSEJOB_VAR(&job)); + MDSWRN(SRVCREATEPULSEJOB_PRI " No Addr", SRVCREATEPULSEJOB_VAR(&job)); status = DoSrvCreatePulse((SrvJob *)&job); } break; @@ -271,12 +271,12 @@ EXPORT int ServerQAction(uint32_t *addrp, uint16_t *portp, int *op, int *flags, job.command = strdup((char *)p2); if (job.h.addr) { - MDSDBG(SVRCOMMANDJOB_PRI, SVRCOMMANDJOB_VAR(&job)); + MDSDBG(SRVCOMMANDJOB_PRI, SRVCOMMANDJOB_VAR(&job)); status = QJob((SrvJob *)&job); } else { - MDSWRN(SVRCOMMANDJOB_PRI " No Addr", SVRCOMMANDJOB_VAR(&job)); + MDSWRN(SRVCOMMANDJOB_PRI " No Addr", SRVCOMMANDJOB_VAR(&job)); status = DoSrvCommand((SrvJob *)&job); } break; @@ -300,12 +300,12 @@ EXPORT int ServerQAction(uint32_t *addrp, uint16_t *portp, int *op, int *flags, job.status = *(int *)p8; if (job.h.addr) { - MDSDBG(SVRMONITORJOB_PRI, SVRMONITORJOB_VAR(&job)); + MDSDBG(SRVMONITORJOB_PRI, SRVMONITORJOB_VAR(&job)); status = QJob((SrvJob *)&job); } else { - MDSWRN(SVRMONITORJOB_PRI " No Addr", SVRMONITORJOB_VAR(&job)); + MDSWRN(SRVMONITORJOB_PRI " No Addr", SRVMONITORJOB_VAR(&job)); status = MDSplusERROR; } break; @@ -429,7 +429,7 @@ static int RemoveLast() JobQueueNext->h.next = 0; else JobQueue = 0; - MDSMSG(SVRJOB_PRI "Removed pending action", SVRJOB_VAR(job)); + MDSMSG(SRVJOB_PRI "Removed pending action", SRVJOB_VAR(job)); FreeJob(job); status = MDSplusSUCCESS; } @@ -948,7 +948,7 @@ static SOCKET setup_client(SrvJob *job) if (sock != INVALID_SOCKET) { add_client(addr, port, sock); - MDSMSG("setup connection %" PRI_SOCKET " " SVRJOB_PRI, sock, SVRJOB_VAR(job)); + MDSMSG("setup connection %" PRI_SOCKET " " SRVJOB_PRI, sock, SRVJOB_VAR(job)); } } return sock; @@ -961,11 +961,11 @@ static void cleanup_client(SrvJob *job) close_socket(sock); if (STATIC_Debug) { - MDSMSG("cleanup connection %" PRI_SOCKET " " SVRJOB_PRI, sock, SVRJOB_VAR(job)); + MDSMSG("cleanup connection %" PRI_SOCKET " " SRVJOB_PRI, sock, SRVJOB_VAR(job)); } else { - MDSDBG("cleanup connection %" PRI_SOCKET " " SVRJOB_PRI, sock, SVRJOB_VAR(job)); + MDSDBG("cleanup connection %" PRI_SOCKET " " SRVJOB_PRI, sock, SRVJOB_VAR(job)); } } @@ -992,7 +992,7 @@ static int send_all(SOCKET sock, char *msg, int len) static int send_reply(SrvJob *job, int replyType, int status_in, int length, char *msg) { - MDSDBG(SVRJOB_PRI " %d", SVRJOB_VAR(job), replyType); + MDSDBG(SRVJOB_PRI " %d", SRVJOB_VAR(job), replyType); int status = MDSplusERROR; long msg_len = msg ? (long)strlen(msg) : 0; int try_again = FALSE; @@ -1005,7 +1005,7 @@ static int send_reply(SrvJob *job, int replyType, int status_in, int length, cha SOCKET sock = setup_client(job); if (sock == INVALID_SOCKET) { - MDSMSG(SVRJOB_PRI " break connection", SVRJOB_VAR(job)); + MDSMSG(SRVJOB_PRI " break connection", SRVJOB_VAR(job)); cleanup_client(job); break; } diff --git a/servershr/ServerSendMessage.c b/servershr/ServerSendMessage.c index 7626c41acf..ba1f8466cf 100644 --- a/servershr/ServerSendMessage.c +++ b/servershr/ServerSendMessage.c @@ -106,7 +106,7 @@ static SOCKET get_socket_by_conid(int conid) // Each thread uses a different port, thus a different network connection. // Connections persist and thus handle all traffic between the endpoints. int ServerSendMessage(int *msgid, char *server, int op, int *retstatus, - pthread_rwlock_t *lock, int *conid_out, void (*callback_done)(), + pthread_rwlock_t *lock, int *conid_out, void (*callback_done)(void *, char *), void *callback_param, void (*callback_before)(), int numargs_in, ...) { @@ -125,7 +125,7 @@ int ServerSendMessage(int *msgid, char *server, int op, int *retstatus, MDSWRN("failed to connect"); } if (callback_done) - callback_done(callback_param); + callback_done(callback_param, NULL); return ServerPATH_DOWN; } INIT_STATUS; @@ -155,7 +155,7 @@ int ServerSendMessage(int *msgid, char *server, int op, int *retstatus, { MDSWRN("could not resolve address socket %" PRI_SOCKET " is bound to", sock); if (callback_done) - callback_done(callback_param); + callback_done(callback_param, NULL); return ServerSOCKET_ADDR_ERROR; } jobid = Job_register(msgid, conid, retstatus, lock, callback_done, callback_param, callback_before); diff --git a/servershr/servershrp.h b/servershr/servershrp.h index 8d6b84bbe1..070185fa7a 100644 --- a/servershr/servershrp.h +++ b/servershr/servershrp.h @@ -83,8 +83,8 @@ typedef struct _SrvJob { JHeader h; } SrvJob; -#define SVRJOB_PRI "SvrJob" JHEADER_PRI -#define SVRJOB_VAR(j) JHEADER_VAR(&(j)->h) +#define SRVJOB_PRI "SrvJob" JHEADER_PRI +#define SRVJOB_VAR(j) JHEADER_VAR(&(j)->h) typedef struct { @@ -93,15 +93,15 @@ typedef struct int shot; int nid; } SrvActionJob; -#define SVRACTIONJOB_PRI "SrvActionJob(" JHEADER_PRI ", tree='%s', shot=%d, nid=%d)" -#define SVRACTIONJOB_VAR(j) JHEADER_VAR(&(j)->h), (j)->tree, (j)->shot, (j)->nid +#define SRVACTIONJOB_PRI "SrvActionJob(" JHEADER_PRI ", tree='%s', shot=%d, nid=%d)" +#define SRVACTIONJOB_VAR(j) JHEADER_VAR(&(j)->h), (j)->tree, (j)->shot, (j)->nid typedef struct { JHeader h; } SrvCloseJob; -#define SVRCLOSEJOB_PRI "SrvCloseJob(" JHEADER_PRI ")" -#define SVRCLOSEJOB_VAR(j) JHEADER_VAR(&(j)->h) +#define SRVCLOSEJOB_PRI "SrvCloseJob(" JHEADER_PRI ")" +#define SRVCLOSEJOB_VAR(j) JHEADER_VAR(&(j)->h) typedef struct { @@ -109,8 +109,8 @@ typedef struct char *tree; int shot; } SrvCreatePulseJob; -#define SVRCREATEPULSEJOB_PRI "SrvCreatePulseJob(" JHEADER_PRI ", tree='%s', shot=%d)" -#define SVRCREATEPULSEJOB_VAR(j) JHEADER_VAR(&(j)->h), (j)->tree, (j)->shot +#define SRVCREATEPULSEJOB_PRI "SrvCreatePulseJob(" JHEADER_PRI ", tree='%s', shot=%d)" +#define SRVCREATEPULSEJOB_VAR(j) JHEADER_VAR(&(j)->h), (j)->tree, (j)->shot typedef struct { @@ -118,8 +118,8 @@ typedef struct char *table; char *command; } SrvCommandJob; -#define SVRCOMMANDJOB_PRI "SrvCommandJob(" JHEADER_PRI ", table='%s', command='%s')" -#define SVRCOMMANDJOB_VAR(j) JHEADER_VAR(&(j)->h), (j)->table, (j)->command +#define SRVCOMMANDJOB_PRI "SrvCommandJob(" JHEADER_PRI ", table='%s', command='%s')" +#define SRVCOMMANDJOB_VAR(j) JHEADER_VAR(&(j)->h), (j)->table, (j)->command typedef struct { @@ -133,8 +133,8 @@ typedef struct char *server; int status; } SrvMonitorJob; -#define SVRMONITORJOB_PRI "SrvMonitorJob(" JHEADER_PRI ", tree='%s', shot=%d, phase=%d, nid=%d, on=%d, mode=%d, server='%s', status=%d)" -#define SVRMONITORJOB_VAR(j) JHEADER_VAR(&(j)->h), (j)->tree, (j)->shot, (j)->phase, (j)->nid, (j)->on, (j)->mode, (j)->server, (j)->status +#define SRVMONITORJOB_PRI "SrvMonitorJob(" JHEADER_PRI ", tree='%s', shot=%d, phase=%d, nid=%d, on=%d, mode=%d, server='%s', status=%d)" +#define SRVMONITORJOB_VAR(j) JHEADER_VAR(&(j)->h), (j)->tree, (j)->shot, (j)->phase, (j)->nid, (j)->on, (j)->mode, (j)->server, (j)->status typedef struct { @@ -179,7 +179,7 @@ typedef struct #ifndef _NO_SERVER_SEND_MESSAGE_PROTO extern int ServerSendMessage(int *msgid, char *server, int op, int *retstatus, - pthread_rwlock_t *lock, int *socket, void (*ast)(), + pthread_rwlock_t *lock, int *socket, void (*ast)(void *, char *), void *astparam, void (*before_ast)(), int numargs_in, ...); #endif diff --git a/tcl/tcl_dispatch.c b/tcl/tcl_dispatch.c index 1732fd6ac1..6a96d96c7b 100644 --- a/tcl/tcl_dispatch.c +++ b/tcl/tcl_dispatch.c @@ -436,7 +436,7 @@ typedef struct char *command; } DispatchedCommand; -static void CommandDone(DispatchedCommand *command) +static void CommandDone(DispatchedCommand *command, char *dummy __attribute__((unused))) { if (IS_NOT_OK(command->status)) { From 1fc957fe35ad8edf8d94fc6ab37c5b3161c6a5c7 Mon Sep 17 00:00:00 2001 From: Antoine Merle Date: Tue, 26 Nov 2024 12:32:59 +0100 Subject: [PATCH 2/3] Fix: recursive calls to CheckIn --- actions/actlogp.h | 1 - 1 file changed, 1 deletion(-) diff --git a/actions/actlogp.h b/actions/actlogp.h index a0cc90d388..8d5eb6d02b 100644 --- a/actions/actlogp.h +++ b/actions/actlogp.h @@ -203,7 +203,6 @@ static void MessageAst(void *dummy __attribute__((unused)), char *reply) } free(event->msg); free(event); - CheckIn(0); } inline static void _EventUpdate(LinkedEvent *event) From 64a75bf442655fdcd40210e5a615728b1128e788 Mon Sep 17 00:00:00 2001 From: Antoine Merle Date: Tue, 26 Nov 2024 12:33:53 +0100 Subject: [PATCH 3/3] Add skeleton for actlog test --- actions/testing/ServerShrTest.sh | 16 ++++++++++++++++ actions/testing/build_tree.tcl | 7 +++++++ actions/testing/test_action.tcl | 6 ++++++ 3 files changed, 29 insertions(+) create mode 100755 actions/testing/ServerShrTest.sh create mode 100644 actions/testing/build_tree.tcl create mode 100644 actions/testing/test_action.tcl diff --git a/actions/testing/ServerShrTest.sh b/actions/testing/ServerShrTest.sh new file mode 100755 index 0000000000..b65e347ecc --- /dev/null +++ b/actions/testing/ServerShrTest.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +export distest_path=/tmp/$USER/distest + +mkdir -p $distest_path + +mdsip -p 9997 -s > server_9997.log 2> server_9997.err & # Monitor server +mdsip -p 9998 -s > server_9998.log 2> server_9998.err & # Action server +mdsip -p 9999 -s > server_9999.log 2> server_9999.err & # Dispatch server +actlog -monitor localhost:9997 > actlog.log 2> actlog.err & + +mdstcl @build_tree + +mdstcl @test_action + +pkill -P $$ diff --git a/actions/testing/build_tree.tcl b/actions/testing/build_tree.tcl new file mode 100644 index 0000000000..f7694a96f4 --- /dev/null +++ b/actions/testing/build_tree.tcl @@ -0,0 +1,7 @@ +edit distest /shot=1 /new +add node act01 /usage=action +write +put/extend ACT01 +Build_Action(Build_Dispatch(2,"localhost:9998","INIT",10,*),BUILD_FUNCTION(BUILTIN_OPCODE("COMMA"),BUILD_FUNCTION(BUILTIN_OPCODE("WRITE"),*,"Test action"),1)) + +close diff --git a/actions/testing/test_action.tcl b/actions/testing/test_action.tcl new file mode 100644 index 0000000000..cf1dcf503f --- /dev/null +++ b/actions/testing/test_action.tcl @@ -0,0 +1,6 @@ +dispatch /command /server=localhost:9999 set tree distest /shot=1 +wait 1 +dispatch /command /server=localhost:9999 dispatch/build/monitor=localhost:9997 +wait 1 +dispatch /command /server=localhost:9999 dispatch/phase/monitor=localhost:9997 init +wait 1