The Assimilation Project  based on Assimilation version 1.1.7.1474836767
gtest01.c
Go to the documentation of this file.
1 
25 #include <projectcommon.h>
26 #ifdef HAVE_MCHECK_H
27 # include <mcheck.h>
28 #endif
29 #ifdef HAVE_UNISTD_H
30 # include <unistd.h>
31 #endif
32 #include <sys/types.h>
33 #include <signal.h>
34 #include <string.h>
35 #include <glib.h>
36 #include <gmainfd.h>
37 #include <logsourcefd.h>
38 #include <configcontext.h>
39 #include <childprocess.h>
40 #include <resourcecmd.h>
41 #include <resourcelsb.h>
42 #include <resourcequeue.h>
43 
44 GMainLoop* mainloop;
52 FSTATIC void quit_at_child_exit(GPid pid, gint status, gpointer gmainfd);
53 FSTATIC void check_output_at_exit(GPid pid, gint status, gpointer gmainfd);
54 FSTATIC void quit_at_childprocess_exit(ChildProcess*, enum HowDied, int rc, int signal, gboolean core_dumped);
55 FSTATIC void generic_childprocess_test(gchar** argv, ConfigContext*, gboolean save_stdout, char * curdir, int timeout);
60 FSTATIC void test_safe_ocfops(void);
63 FSTATIC void expect_ocf_callback(ConfigContext* request, gpointer user_data, enum HowDied reason
64 , int rc, int signal, gboolean coredump, const char * stringresult);
65 FSTATIC void test_all_freed(void);
66 
67 #define HELLOSTRING ": Hello, world."
68 #define HELLOSTRING_NL (HELLOSTRING "\n")
69 
77 const char * test_expected_string_return = NULL;
78 gboolean no_dummy_RA = FALSE;
79 
80 void
82 {
83  int live_obj_count = proj_class_live_object_count();
84 
85  if (live_obj_count > 0) {
87  g_assert_cmpint(live_obj_count, ==, 0);
88  }
89 }
90 
92 FSTATIC void
93 check_output_at_exit(GPid pid, gint status, gpointer gmainfd)
94 {
95  GMainFd* cmdout = CASTTOCLASS(GMainFd, gmainfd);
96  (void)pid;
97  g_assert_cmpint(status, ==, 0);
98  g_assert(cmdout->textread != NULL);
99  g_assert_cmpint(strnlen(cmdout->textread->str, cmdout->textread->len), ==, cmdout->textread->len);
100  g_assert_cmpstr(cmdout->textread->str, ==, HELLOSTRING "\n");
101  //g_print("GOT [%s]\n", cmdout->textread->str);
102  g_main_loop_quit(mainloop);
103 }
104 
106 FSTATIC void
108 {
109  GPid childpid;
110  gint stdoutfd;
111  GError* failcode = NULL;
112  GMainFd* cmdout;
113  gchar echo[] = "/bin/echo";
114  gchar hello[] = HELLOSTRING;
115  gchar* argv[] = {echo, hello, NULL}; // Broken glib API...
116  gint cmdid;
117  mainloop = g_main_loop_new(g_main_context_default(), TRUE);
118  g_spawn_async_with_pipes(
119  NULL, // Current directory
120  argv, // Arguments
121  NULL, // environment
122  G_SPAWN_DO_NOT_REAP_CHILD, // GSpawnFlags flags,
123  NULL, // GSpawnChildSetupFunc child_setup,
124  NULL, // gpointer user_data,
125  &childpid, // GPid *child_pid,
126  NULL, // gint *standard_input,
127  &stdoutfd, // gint *standard_output,
128  NULL, // gint *standard_error,
129  &failcode); // GError **error
130 
131  cmdout = gmainfd_new(0, stdoutfd, G_PRIORITY_HIGH, g_main_context_default());
132  //g_print("Spawned child %d with fd %d\n", childpid, stdoutfd);
133  g_assert_cmpint(childpid, >, 0);
134  g_assert_cmpint(stdoutfd, >, 0);
135  cmdid = g_child_watch_add(childpid, check_output_at_exit, cmdout);
136  g_assert_cmpint(cmdid, >, 0);
137  g_main_loop_run(mainloop);
138  g_source_unref(&cmdout->baseclass);
139  g_main_loop_unref(mainloop);
140  mainloop=NULL;
141  if (proj_class_live_object_count() != 0) {
143  }
144  g_assert_cmpint(proj_class_live_object_count(), ==, 0);
145 }
146 
148 FSTATIC void
149 quit_at_child_exit(GPid pid, gint status, gpointer logsourcefd)
150 {
151  LogSourceFd* logsrc = CASTTOCLASS(LogSourceFd, logsourcefd);
152 
153  (void)pid;
154  g_assert_cmpint(status, ==, 0);
155  g_assert_cmpint(logsrc->linecount, ==, 1);
156  // sizeof(HELLOSTRING) includes a NULL. echo effectively replaces the NULL with a '\n'
157  g_assert_cmpint(logsrc->charcount, ==, sizeof(HELLOSTRING));
158  g_main_loop_quit(mainloop);
159 }
160 
161 // We logged the output of echo HELLOSTRING to standard output - let's see if it worked...
162 FSTATIC void
163 quit_at_childprocess_exit(ChildProcess*self, enum HowDied notice, int rc, int signal, gboolean core_dumped)
164 {
165  LogSourceFd* stdoutfd;
166  (void)core_dumped;
167 
168  g_assert_cmpint(notice, ==, test_expected_death);
169  if (notice == EXITED_ZERO || notice == EXITED_NONZERO) {
170  g_assert_cmpint(rc, ==, test_expected_exitcode);
171  }
172  if (notice == EXITED_SIGNAL) {
173  g_assert_cmpint(signal, ==, test_expected_signal);
174  }
175  if (test_expected_string_return == NULL) {
176  g_assert_cmpint(OBJ_IS_A(self->stdout_src, "LogSourceFd"), ==, TRUE);
177  stdoutfd = CASTTOCLASS(LogSourceFd, self->stdout_src);
178  g_assert_cmpint(stdoutfd->charcount, ==, test_expected_charcount);
179  g_assert_cmpint(stdoutfd->linecount, ==, test_expected_linecount);
180  }else{
181  g_assert(self->stdout_src->textread != NULL);
182  if (self->stdout_src->textread != NULL) {
183  g_assert(self->stdout_src->textread->str != NULL);
184  g_assert_cmpstr(self->stdout_src->textread->str, ==, test_expected_string_return);
185  }
186  }
187  g_assert_cmpint(self->stderr_src->charcount, ==, test_expected_stderr_charcount);
188  g_assert_cmpint(self->stderr_src->linecount, ==, test_expected_stderr_linecount);
189 
190  g_main_loop_quit(mainloop);
191 }
192 
194 FSTATIC void
196 {
197  GPid childpid;
198  gint stdoutfd;
199  GError* failcode = NULL;
200  LogSourceFd* cmdlog;
201  gchar echo[] = "/bin/echo";
202  gchar hello[] = HELLOSTRING;
203  gchar* argv[] = {echo, hello, NULL}; // Broken glib API...
204  gint cmdid;
205  //proj_class_incr_debug(NULL);
206  //proj_class_incr_debug(NULL);
207  //proj_class_incr_debug(NULL);
208  mainloop = g_main_loop_new(g_main_context_default(), TRUE);
209  g_spawn_async_with_pipes(
210  NULL, // Current directory
211  argv, // Arguments
212  NULL, // environment
213  G_SPAWN_DO_NOT_REAP_CHILD, // GSpawnFlags flags,
214  NULL, // GSpawnChildSetupFunc child_setup,
215  NULL, // gpointer user_data,
216  &childpid, // GPid *child_pid,
217  NULL, // gint *standard_input,
218  &stdoutfd, // gint *standard_output,
219  NULL, // gint *standard_error,
220  &failcode); // GError **error
221 
222  cmdlog = logsourcefd_new(0, stdoutfd, G_PRIORITY_HIGH, g_main_context_default()
223  , G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, __FUNCTION__);
224  //g_print("Spawned child %d with fd %d\n", childpid, stdoutfd);
225  g_assert_cmpint(childpid, >, 0);
226  g_assert_cmpint(stdoutfd, >, 0);
227  cmdid = g_child_watch_add(childpid, quit_at_child_exit, cmdlog);
228  g_assert_cmpint(cmdid, >, 0);
229  g_main_loop_run(mainloop);
230  g_source_unref(&cmdlog->baseclass.baseclass);
231  g_main_loop_unref(mainloop);
232  mainloop=NULL;
233  if (proj_class_live_object_count() != 0) {
235  }
236  g_assert_cmpint(proj_class_live_object_count(), ==, 0);
237 }
238 
240 FSTATIC void
241 generic_childprocess_test(gchar** argv, ConfigContext* envmod, gboolean save_stdout, char * curdir, int timeout)
242 {
243  ChildProcess* child;
244 
245  mainloop = g_main_loop_new(g_main_context_default(), TRUE);
246  child = childprocess_new(0 // object size (0 == default size)
247 , argv // char** argv
248 , NULL // char** envp
249 , envmod // ConfigContext*envmod
250 , curdir // const char* curdir
252  //gboolean (*notify)(ChildProcess*, enum HowDied, int rc, int signal, gboolean core_dumped)
253 , save_stdout // gboolean save_stdout
254 , G_LOG_DOMAIN // const char * logdomain
255 , __FUNCTION__ // const char * logprefix
256 , G_LOG_LEVEL_MESSAGE // GLogLevelFlags loglevel
257 , timeout //guint32 timeout_seconds);
258 , NULL // gpointer user_data
259 , CHILD_NOLOG // exit logging mode
260 , NULL // logging name - defaults to argv[0]
261  );
262  g_main_loop_run(mainloop);
263  UNREF(child);
264  g_main_loop_unref(mainloop);
265  mainloop=NULL;
266  if (envmod) {
267  UNREF(envmod);
268  }
269  if (proj_class_live_object_count() != 0) {
271  }
272  g_assert_cmpint(proj_class_live_object_count(), ==, 0);
273 }
274 
276 FSTATIC void
278 {
279  gchar echo[] = "/bin/echo";
280  gchar hello[] = HELLOSTRING;
281  gchar* argv[] = {echo, hello, NULL}; // Broken glib API...
282 
287  test_expected_charcount = sizeof(hello);
291  generic_childprocess_test(argv, NULL, FALSE, NULL, 0);
292 }
293 
295 FSTATIC void
297 {
298  gchar false[] = "/bin/false";
299  gchar* argv[] = {false, NULL}; // Broken glib API...
300 
309  generic_childprocess_test(argv, NULL, FALSE, NULL, 0);
310 }
311 
313 FSTATIC void
315 {
316  gchar echo[] = "/bin/echo";
317  gchar hello[] = HELLOSTRING;
318  gchar* argv[] = {echo, hello, NULL}; // Broken glib API...
319 
328  generic_childprocess_test(argv, NULL, TRUE, NULL, 0);
329 }
330 FSTATIC void
332 {
333  gchar shell[] = "/bin/sh";
334  gchar dashc[] = "-c";
335  gchar echocmd[] = "echo $TRITE $HOME";
336  gchar* argv[] = {shell, dashc, echocmd, NULL}; // Broken glib API...
337  NetAddr* home = netaddr_string_new("127.0.0.1");
338  ConfigContext* envmod = configcontext_new_JSON_string("{\"TRITE\":\"There's no place like\"}");
339 
340  envmod->setaddr(envmod, "HOME", home);
341  UNREF(home);
349  test_expected_string_return = "There's no place like 127.0.0.1\n";
350  generic_childprocess_test(argv, envmod, TRUE, NULL, 0);
351 }
352 
355 FSTATIC void
357 {
358  gchar shell[] = "/bin/sh";
359  gchar dashc[] = "-c";
360  gchar hello[] = "echo \""HELLOSTRING"\"; sleep 100";
361  gchar* argv[] = {shell, dashc, hello, NULL}; // Broken glib API...
362 
371  generic_childprocess_test(argv, NULL, TRUE, NULL, 1);
372 }
373 
376 FSTATIC void
378 {
379  gchar shell[] = "/bin/sh";
380  gchar dashc[] = "-c";
381  // Signal 9 is SIGKILL - should terminate most any process
382  gchar hello[] = "echo \""HELLOSTRING"\"; kill -9 $$";
383  gchar* argv[] = {shell, dashc, hello, NULL}; // Broken glib API...
384 
393  generic_childprocess_test(argv, NULL, TRUE, NULL, 1);
394 }
397 FSTATIC void
399 {
400  gchar shell[] = "/bin/sh";
401  gchar dashc[] = "-c";
402  // Signal 9 is SIGKILL - should terminate most any process
403  gchar hello[] = "echo \""HELLOSTRING"\"; echo \""HELLOSTRING"\" >&2";
404  gchar* argv[] = {shell, dashc, hello, NULL}; // Broken glib API...
405 
414  generic_childprocess_test(argv, NULL, TRUE, NULL, 1);
415 }
416 
419 FSTATIC void
421 {
422  gchar sleep[] = "/bin/sleep";
423  gchar number[] = "100";
424  gchar* argv[] = {sleep, number, NULL}; // Broken glib API...
425 
434  generic_childprocess_test(argv, NULL, FALSE, NULL, 1);
435 }
436 
437 #define OCFCLASS "\"" REQCLASSNAMEFIELD "\": \"ocf\""
438 #define LSBCLASS "\"" REQCLASSNAMEFIELD "\": \"lsb\""
439 #define HBPROVIDER "\"" REQPROVIDERNAMEFIELD "\": \"heartbeat\""
440 #define DUMMYTYPE "\"" CONFIGNAME_TYPE "\": \"Dummy\""
441 #define NANOTYPE "\"" CONFIGNAME_TYPE "\": \"nanoprobe\""
442 #define STARTOP "\"" REQOPERATIONNAMEFIELD "\": \"start\""
443 #define STOPOP "\"" REQOPERATIONNAMEFIELD "\": \"stop\""
444 #define MONOP "\"" REQOPERATIONNAMEFIELD "\": \"monitor\""
445 #define METAOP "\"" REQOPERATIONNAMEFIELD "\": \"meta-data\""
446 #define RESOURCENAME "\"" CONFIGNAME_INSTANCE "\": \"DummyTestGTest01\""
447 #define NULLPARAMS "\"" REQENVIRONNAMEFIELD "\": {}," "\"" REQCANCELONFAILFIELD "\": true"
448 #define REQID "\"" REQIDENTIFIERNAMEFIELD "\": 42"
449 
450 struct ocf_expect {
451  gint minstrlen;
452  gint maxstrlen;
454  int rc;
455  int signal;
456  gboolean coredump;
457  gboolean quit_after_done;
458 };
459 
460 FSTATIC void
461 expect_ocf_callback(ConfigContext* request, gpointer user_data, enum HowDied reason, int rc
462 , int signal, gboolean coredump, const char * stringresult)
463 {
464  struct ocf_expect * expect = (struct ocf_expect *)user_data;
465  int stringlen = (stringresult ? (gint)strlen(stringresult) : -1);
466 
467  (void)request;
468  if (expect->maxstrlen >= 0) {
469  g_assert(stringlen <= expect->maxstrlen);
470  }
471  g_assert(stringlen >= expect->minstrlen);
472 
473  g_assert(reason == expect->death);
474  g_assert(rc == expect->rc);
475  g_assert(signal == expect->signal);
476  g_assert(coredump == expect->coredump);
477  if (expect->quit_after_done) {
478  g_main_loop_quit(mainloop);
479  }
480 }
481 
482 FSTATIC void
484 {
485  const char * stop =
486  "{" OCFCLASS "," DUMMYTYPE "," RESOURCENAME "," STOPOP "," HBPROVIDER "," NULLPARAMS "}";
487  const char * start =
488  "{" OCFCLASS "," DUMMYTYPE "," RESOURCENAME "," STARTOP "," HBPROVIDER "," NULLPARAMS "}";
489  const char * monitor =
490  "{" OCFCLASS "," DUMMYTYPE "," RESOURCENAME "," MONOP "," HBPROVIDER "," NULLPARAMS "}";
491  const char * metadata =
492  "{" OCFCLASS "," DUMMYTYPE "," RESOURCENAME "," METAOP "," HBPROVIDER "," NULLPARAMS "}";
493 
494  struct ocf_expect success = {
495  -1, // gint minstrlen;
496  0, // gint maxstrlen;
497  EXITED_ZERO, // enum HowDied death;
498  0, // int rc;
499  0, // int signal;
500  FALSE, // gboolean coredump;
501  TRUE, // quit_after_done
502  };
503  struct ocf_expect stop_fail = {
504  -1, // gint minstrlen;
505  0, // gint maxstrlen;
506  EXITED_NONZERO, // enum HowDied death;
507  7, // int rc;
508  0, // int signal;
509  FALSE, // gboolean coredump;
510  TRUE, // quit_after_done
511  };
512 
513  struct ocf_expect meta_success = {
514  200, // gint minstrlen;
515  50000, // gint maxstrlen;
516  EXITED_ZERO, // enum HowDied death;
517  0, // int rc;
518  0, // int signal;
519  FALSE, // gboolean coredump;
520  TRUE, // quit_after_done
521  };
522 
523  const char * operations[] =
524  {metadata, stop, monitor, start, monitor, stop, monitor };
525  struct ocf_expect* expectations [] =
526  {&meta_success, &success, &stop_fail, &success, &success, &success, &stop_fail};
527  guint j;
528 
529 #ifdef HAVE_GETEUID
530  if (geteuid() != 0) {
531  g_message("Test %s skipped - must be root.", __FUNCTION__);
532  return;
533  }
534 #endif
535 
536  for (j=0; j < DIMOF(operations); ++j) {
537  ResourceCmd* cmd;
538  ConfigContext* op = configcontext_new_JSON_string(operations[j]);
539 
540  g_assert(op != NULL);
541  mainloop = g_main_loop_new(g_main_context_default(), TRUE);
542  cmd = resourcecmd_new(op, expectations[j], expect_ocf_callback);
543  if (NULL == cmd) {
544  g_message("Cannot create Dummy OCF resource agent object"
545  " -- is the Dummy RA installed? - test %s skipped.", __FUNCTION__);
546  no_dummy_RA = TRUE;
547  UNREF(op);
548  g_main_loop_unref(mainloop);
549  return;
550  }
551  cmd->execute(cmd);
552  g_main_loop_run(mainloop);
553  g_main_loop_unref(mainloop);
554  UNREF(cmd);
555  UNREF(op);
556  }
557  test_all_freed();
558 }
559 
560 #define PREFIX REQID "," OCFCLASS "," DUMMYTYPE "," RESOURCENAME "," HBPROVIDER
561 FSTATIC void
563 {
564  const char * stop =
565  "{" PREFIX "," STOPOP "," HBPROVIDER "," NULLPARAMS "}";
566  const char * start =
567  "{" PREFIX "," STARTOP "," HBPROVIDER "," NULLPARAMS "}";
568  const char * monitor =
569  "{" PREFIX "," MONOP "," HBPROVIDER "," NULLPARAMS "}";
570  const char * metadata =
571  "{" REQID "," OCFCLASS "," DUMMYTYPE "," RESOURCENAME "," METAOP "," HBPROVIDER "," NULLPARAMS "}";
572 
573  struct ocf_expect success = {
574  -1, // gint minstrlen;
575  0, // gint maxstrlen;
576  EXITED_ZERO, // enum HowDied death;
577  0, // int rc;
578  0, // int signal;
579  FALSE, // gboolean coredump;
580  FALSE, // quit_after_done
581  };
582  struct ocf_expect stop_fail = {
583  -1, // gint minstrlen;
584  0, // gint maxstrlen;
585  EXITED_NONZERO, // enum HowDied death;
586  7, // int rc;
587  0, // int signal;
588  FALSE, // gboolean coredump;
589  FALSE, // quit_after_done
590  };
591  struct ocf_expect stop_fail_and_quit = {
592  -1, // gint minstrlen;
593  0, // gint maxstrlen;
594  EXITED_NONZERO, // enum HowDied death;
595  7, // int rc;
596  0, // int signal;
597  FALSE, // gboolean coredump;
598  TRUE, // quit_after_done
599  };
600 
601  struct ocf_expect meta_success = {
602  200, // gint minstrlen;
603  50000, // gint maxstrlen;
604  EXITED_ZERO, // enum HowDied death;
605  0, // int rc;
606  0, // int signal;
607  FALSE, // gboolean coredump;
608  FALSE, // quit_after_done
609  };
610 
611  const char * operations[] =
612  {metadata, stop, monitor, start, monitor, stop, monitor };
613  struct ocf_expect* expectations [] =
614  {&meta_success, &success, &stop_fail, &success, &success, &success, &stop_fail_and_quit};
615 
616  guint j;
617  ResourceQueue* rscq;
618 
619 #ifdef HAVE_GETEUID
620  if (geteuid() != 0) {
621  g_message("Test %s skipped - must be root.", __FUNCTION__);
622  return;
623  }
624 #endif
625  if (no_dummy_RA) {
626  g_message("Apparently No dummy RA - installed - test %s skipped.", __FUNCTION__);
627  return;
628  }
629  //proj_class_incr_debug(NULL);
630  //proj_class_incr_debug(NULL);
631  //proj_class_incr_debug(NULL);
632 
633  rscq = resourcequeue_new(0);
634  mainloop = g_main_loop_new(g_main_context_default(), TRUE);
635  // Queue all the commands up at once, then run them
636  for (j=0; j < DIMOF(operations); ++j) {
637  ConfigContext* op = configcontext_new_JSON_string(operations[j]);
638  g_assert(op != NULL);
639  g_assert(rscq->Qcmd(rscq, op, expect_ocf_callback, expectations[j]) == TRUE);
640  UNREF(op);
641  }
642  g_main_loop_run(mainloop);
643  g_main_loop_unref(mainloop);
644  UNREF(rscq); rscq = NULL;
645  test_all_freed();
646 }
647 
648 #define LSBPREFIX REQID "," LSBCLASS "," NANOTYPE "," RESOURCENAME
649 
650 FSTATIC void
652 {
653  const char * stop =
654  "{" LSBPREFIX "," STOPOP "," NULLPARAMS "}";
655  const char * start =
656  "{" LSBPREFIX "," STARTOP "," NULLPARAMS "}";
657  const char * monitor =
658  "{" LSBPREFIX "," MONOP "," NULLPARAMS "}";
659  const char * metadata =
660  "{" LSBPREFIX "," METAOP "," NULLPARAMS "}";
661 
662  struct ocf_expect success = {
663  -1, // gint minstrlen;
664  0, // gint maxstrlen;
665  EXITED_ZERO, // enum HowDied death;
666  0, // int rc;
667  0, // int signal;
668  FALSE, // gboolean coredump;
669  FALSE, // quit_after_done
670  };
671  struct ocf_expect stop_fail = {
672  -1, // gint minstrlen;
673  0, // gint maxstrlen;
674  EXITED_NONZERO, // enum HowDied death;
675  7, // int rc;
676  0, // int signal;
677  FALSE, // gboolean coredump;
678  FALSE, // quit_after_done
679  };
680  struct ocf_expect stop_fail_and_quit = {
681  -1, // gint minstrlen;
682  0, // gint maxstrlen;
683  EXITED_NONZERO, // enum HowDied death;
684  7, // int rc;
685  0, // int signal;
686  FALSE, // gboolean coredump;
687  TRUE, // quit_after_done
688  };
689 
690  struct ocf_expect meta_success = {
691  200, // gint minstrlen;
692  50000, // gint maxstrlen;
693  EXITED_ZERO, // enum HowDied death;
694  0, // int rc;
695  0, // int signal;
696  FALSE, // gboolean coredump;
697  FALSE, // quit_after_done
698  };
699 
700  const char * operations[] =
701  {metadata, stop, monitor, start, monitor, stop, monitor };
702  struct ocf_expect* expectations [] =
703  {&meta_success, &success, &stop_fail, &success, &success, &success, &stop_fail_and_quit};
704 
705  guint j;
706  ResourceQueue* rscq;
707  const char * initpath = LSB_ROOT "/nanoprobe";
708 
709 #ifdef HAVE_GETEUID
710  if (geteuid() != 0) {
711  g_message("Test %s skipped - must be root.", __FUNCTION__);
712  return;
713  }
714 #endif
715  if ( !g_file_test(initpath, G_FILE_TEST_IS_REGULAR)
716  || !g_file_test(initpath, G_FILE_TEST_IS_EXECUTABLE)) {
717  g_message("Test %s skipped No LSB Resource agent [%s]", __FUNCTION__, initpath);
718  return;
719  }
720 
721  //proj_class_incr_debug(NULL);
722  //proj_class_incr_debug(NULL);
723  //proj_class_incr_debug(NULL);
724 
725  rscq = resourcequeue_new(0);
726  mainloop = g_main_loop_new(g_main_context_default(), TRUE);
727  // Queue all the commands up at once, then run them
728  for (j=0; j < DIMOF(operations); ++j) {
729  ConfigContext* op = configcontext_new_JSON_string(operations[j]);
730  g_assert(op != NULL);
731  //g_message("Running operation %d: %s", j, operations[j]);
732  g_assert(rscq->Qcmd(rscq, op, expect_ocf_callback, expectations[j]) == TRUE);
733  UNREF(op);
734  }
735  g_main_loop_run(mainloop);
736  g_main_loop_unref(mainloop);
737  UNREF(rscq); rscq = NULL;
738  test_all_freed();
739 }
740 
742 int
743 main(int argc, char ** argv)
744 {
745  gboolean can_kill;
746 #if 0
747  #ifdef HAVE_MCHECK_PEDANTIC
748  // Unfortunately, even being the first code in main is not soon enough :-(
749  g_assert(mcheck_pedantic(NULL) == 0);
750  #else
751  # ifdef HAVE_MCHECK
752  g_assert(mcheck(NULL) == 0);
753  # endif
754  #endif
755 #endif
756  // Processes run as part of "docker build" can't kill(2) any processes
757  can_kill = (kill(getpid(), 0) == 0);
758  if (!can_kill) {
759  g_message("Tests that kill processes not run.");
760  }
761  g_setenv("G_MESSAGES_DEBUG", "all", TRUE);
762  g_test_init(&argc, &argv, NULL);
763  g_test_add_func("/gtest01/gmain/command-output", test_read_command_output_at_EOF);
764  g_test_add_func("/gtest01/gmain/log-command-output", test_log_command_output);
765  g_test_add_func("/gtest01/gmain/childprocess_log_all", test_childprocess_log_all);
766  g_test_add_func("/gtest01/gmain/childprocess_false", test_childprocess_false);
767  if (can_kill) {
768  g_test_add_func("/gtest01/gmain/childprocess_timeout", test_childprocess_timeout);
769  }
770  g_test_add_func("/gtest01/gmain/childprocess_save_command_output"
772  if (can_kill) {
773  g_test_add_func("/gtest01/gmain/childprocess_save_command_output_timeout"
775  g_test_add_func("/gtest01/gmain/childprocess_save_command_output_signal"
777  }
778  g_test_add_func("/gtest01/gmain/childprocess_stderr_logging"
780  g_test_add_func("/gtest01/gmain/childprocess_modenv", test_childprocess_modenv);
781  g_test_add_func("/gtest01/gmain/safe_ocfops", test_safe_ocfops);
782  g_test_add_func("/gtest01/gmain/safe_queue_ocfops", test_safe_queue_ocfops);
783 #if 0
784  // LSB status operation is broken under systemd.
785  g_test_add_func("/gtest01/gmain/safe_queue_lsbops", test_safe_queue_lsbops);
786 #endif
787  return g_test_run();
788 }
GSource baseclass
Our base class - NOT an AssimObj.
Definition: gmainfd.h:35
ConfigContext * configcontext_new_JSON_string(const char *jsontext)
Construct a ConfigContext object from the given JSON string.
gint maxstrlen
Definition: gtest01.c:452
gboolean(* Qcmd)(ResourceQueue *self, ConfigContext *request, ResourceCmdCallback callback, gpointer user_data)
Definition: resourcequeue.h:55
#define DUMMYTYPE
Definition: gtest01.c:440
void(* setaddr)(ConfigContext *, const char *, NetAddr *)
Set NetAddr value.
Definition: configcontext.h:93
FSTATIC void quit_at_childprocess_exit(ChildProcess *, enum HowDied, int rc, int signal, gboolean core_dumped)
Definition: gtest01.c:163
#define OCFCLASS
Definition: gtest01.c:437
gboolean no_dummy_RA
Definition: gtest01.c:78
WINEXPORT ChildProcess * childprocess_new(gsize cpsize, char **argv, const char **envp, ConfigContext *envmod, const char *curdir, void(*notify)(ChildProcess *, enum HowDied, int rc, int signal, gboolean core_dumped), gboolean save_stdout, const char *logdomain, const char *logprefix, GLogLevelFlags loglevel, guint32 timeout_seconds, gpointer user_data, enum ChildErrLogMode logmode, const char *logname)
ChildProcess class. constructor.
Definition: childprocess.c:85
GMainLoop * mainloop
gtest01.c - miscellaneous glib mainloop-based tests.
Definition: gtest01.c:44
FSTATIC void check_output_at_exit(GPid pid, gint status, gpointer gmainfd)
Make sure we read our HELLOSTRING when the process exits.
Definition: gtest01.c:93
FSTATIC void expect_ocf_callback(ConfigContext *request, gpointer user_data, enum HowDied reason, int rc, int signal, gboolean coredump, const char *stringresult)
Definition: gtest01.c:461
#define MONOP
Definition: gtest01.c:444
int charcount
How many characters have been logged (read).
Definition: logsourcefd.h:39
#define LSB_ROOT
Definition: resourcelsb.h:52
FSTATIC void quit_at_child_exit(GPid pid, gint status, gpointer gmainfd)
Quit when the child exits - look for HELLOSTRING characters being logged.
Definition: gtest01.c:149
void(* execute)(ResourceCmd *self)
Execute this resource command.
Definition: resourcecmd.h:58
#define STOPOP
Definition: gtest01.c:443
FSTATIC void test_childprocess_save_command_output(void)
This test outputs a string which is then saved.
Definition: gtest01.c:314
enum HowDied death
Definition: gtest01.c:453
FSTATIC void test_safe_queue_lsbops(void)
Definition: gtest01.c:651
FSTATIC void test_safe_queue_ocfops(void)
Definition: gtest01.c:562
#define FSTATIC
Definition: projectcommon.h:31
FSTATIC void test_log_command_output(void)
A test for just testing our ability to log things we read from a pipe.
Definition: gtest01.c:195
int test_expected_charcount
Definition: gtest01.c:74
int signal
Definition: childprocess.c:238
LogSourceFd * logsourcefd_new(gsize cpsize, int fd, int priority, GMainContext *context, const char *logdomain, GLogLevelFlags loglevel, const char *prefix)
Construct a new LogSourceFd class. object and return it.
Definition: logsourcefd.c:39
#define HELLOSTRING_NL
Definition: gtest01.c:68
int test_expected_linecount
Definition: gtest01.c:73
#define __FUNCTION__
Exited with a signal.
Definition: childprocess.h:39
#define OBJ_IS_A(obj, Cclass)
Definition: proj_classes.h:72
FSTATIC void test_childprocess_timeout(void)
This process just exceeds its timeout via a sleep.
Definition: gtest01.c:420
GString * textread
The text we&#39;ve read so far.
Definition: gmainfd.h:37
#define STARTOP
Definition: gtest01.c:442
#define RESOURCENAME
Definition: gtest01.c:446
GMainFd baseclass
Our base class - NOT an AssimObj.
Definition: logsourcefd.h:35
Definition: hello.py:1
guint32 proj_class_live_object_count(void)
Return the count of live C class objects.
Definition: proj_classes.c:406
Project common header file.
#define DIMOF(a)
Definition: lldp_min.c:30
Don&#39;t log anything when it quits.
Definition: childprocess.h:46
enum HowDied test_expected_death
Definition: gtest01.c:70
Implements Configuration Context class.
int test_expected_stderr_linecount
Definition: gtest01.c:75
#define LSBPREFIX
Definition: gtest01.c:648
FSTATIC void test_childprocess_stderr_logging(void)
We produce some to stderr, and some to stdout Verify capturing the stdout, and the char counts of std...
Definition: gtest01.c:398
The NetAddr class class represents a general network address - whether IP, MAC, or any other type of ...
Definition: netaddr.h:43
ResourceQueue * resourcequeue_new(guint structsize)
Construct a new ResourceQueue system (you probably only need one)
Definition: resourcequeue.c:80
FSTATIC void test_childprocess_false(void)
This test exits with return code 1 (the false command)
Definition: gtest01.c:296
HowDied
Definition: childprocess.h:35
Exited with nonzero return code.
Definition: childprocess.h:38
FSTATIC void test_safe_ocfops(void)
Definition: gtest01.c:483
#define REQID
Definition: gtest01.c:448
int main(int argc, char **argv)
Test main program (&#39;/gtest01&#39;) using the glib test fixtures.
Definition: gtest01.c:743
Implements the LSB (Linux Standard Base aka SysV Init script) resource class.
#define METAOP
Definition: gtest01.c:445
#define HELLOSTRING
Definition: gtest01.c:67
FSTATIC void test_read_command_output_at_EOF(void)
Test to run a command and verify that we can capture its output in a string in the gmainloop environm...
Definition: gtest01.c:107
#define HBPROVIDER
Definition: gtest01.c:439
int test_expected_exitcode
Definition: gtest01.c:71
FSTATIC void test_childprocess_modenv(void)
Definition: gtest01.c:331
ResourceCmd * resourcecmd_new(ConfigContext *request, gpointer user_data, ResourceCmdCallback callback)
Our ResourceCmd Factory object - constructs an object of the proper subclass for the given instantiat...
Definition: resourcecmd.c:65
FSTATIC void test_childprocess_log_all(void)
This test produces output which is logged. We verify the character and line counts.
Definition: gtest01.c:277
FSTATIC void test_childprocess_save_command_output_signal(void)
We produce some output, then kill ourselves with a signal.
Definition: gtest01.c:377
Implements the resource queue class.
Timed out and was killed.
Definition: childprocess.h:40
Exited with zero return code.
Definition: childprocess.h:37
Implements the resource command abstract class.
void proj_class_dump_live_objects(void)
Dump all live C class objects (address and Class)
Definition: proj_classes.c:356
#define PREFIX
Definition: gtest01.c:560
int signal
Definition: gtest01.c:455
gint minstrlen
Definition: gtest01.c:451
Implements a gmainloop source for reading file descriptor pipes.
int rc
Definition: gtest01.c:454
int test_expected_signal
Definition: gtest01.c:72
NetAddr * netaddr_string_new(const char *addrstr)
Create a NetAddr from an ipv4, ipv6 or MAC address string.
Definition: netaddr.c:976
GMainFd * gmainfd_new(gsize cpsize, int fd, int priority, GMainContext *context)
Construct a new GMainFd object and return it.
Definition: gmainfd.c:64
int test_expected_stderr_charcount
Definition: gtest01.c:76
FSTATIC void test_childprocess_save_command_output_timeout(void)
We produce some output, then exceed our timeout with a sleep.
Definition: gtest01.c:356
int linecount
How many lines have been logged.
Definition: logsourcefd.h:41
Implements Child Process class.
#define CASTTOCLASS(Cclass, obj)
Safely cast &#39;obj&#39; to C-class &#39;class&#39; - verifying that it was registerd as being of type class ...
Definition: proj_classes.h:66
#define UNREF(obj)
Definition: assimobj.h:35
FSTATIC void test_all_freed(void)
Definition: gtest01.c:81
gboolean coredump
Definition: gtest01.c:456
Implements a gmainloop source for reading file descriptor pipes.
const char * test_expected_string_return
Definition: gtest01.c:77
FSTATIC void generic_childprocess_test(gchar **argv, ConfigContext *, gboolean save_stdout, char *curdir, int timeout)
A generic helper function for testing things about childprocess_new()
Definition: gtest01.c:241
gboolean quit_after_done
Definition: gtest01.c:457
#define NULLPARAMS
Definition: gtest01.c:447
FSTATIC void test_save_command_output(void)