The Assimilation Project  based on Assimilation version 1.1.7.1474836767
gtest02.c
Go to the documentation of this file.
1 
24 #include <projectcommon.h>
25 #ifdef HAVE_MCHECK_H
26 # include <mcheck.h>
27 #endif
28 #include <string.h>
29 #include <resourcecmd.h>
30 #include <resourcequeue.h>
31 #include <childprocess.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <malloc.h>
35 
36 FSTATIC void test_all_freed(void);
37 FSTATIC gboolean logfatal_function(const gchar*, GLogLevelFlags, const gchar*,gpointer);
38 FSTATIC void set_expected_failures(const char** the_usual_suspects);
42 
43 char * bad_msg = NULL;
44 const char ** expected_msgs = NULL;
45 
46 FSTATIC void
47 set_expected_failures(const char** the_usual_suspects)
48 {
49  g_log_set_fatal_mask(G_LOG_DOMAIN, 0);
50  g_test_log_set_fatal_handler (logfatal_function, the_usual_suspects);
51  expected_msgs = the_usual_suspects;
52 }
53 
54 FSTATIC void
56 {
57  int live_obj_count = proj_class_live_object_count();
58  const char ** mptr;
59 
60  if (live_obj_count > 0) {
62  g_assert_cmpint(live_obj_count, ==, 0);
63  }
64  if (bad_msg) {
65  g_message("Message [\"%s\"] not found in expected messages for this test."
66  , bad_msg);
67  fflush(stdout);
68  for (mptr = expected_msgs; mptr && *mptr; ++mptr) {
69  g_message("Expected message: \"%s\"", *mptr);
70  fflush(stdout);
71  }
72  g_assert(bad_msg == NULL);
73  free(bad_msg);
74  bad_msg = NULL;
75  }
76 }
77 
78 FSTATIC gboolean
80  const gchar * log_domain
81 , GLogLevelFlags log_level
82 , const gchar * message
83 , gpointer user_data)
84 {
85  const char ** messagelist = (const char **)user_data;
86 
87  const char ** mptr;
88  int msgcount = 0;
89 
90  (void)log_domain;
91  (void)log_level;
92 
93  if (log_level >= G_LOG_LEVEL_MESSAGE) {
94  return FALSE;
95  }
96  // Old versions of glib don't seem to handle user_data...
97  if (messagelist == NULL) {
98  messagelist = expected_msgs;
99  }
100  for (mptr = messagelist; mptr && *mptr; ++mptr) {
101  ++ msgcount;
102  if (strstr(message, *mptr) != NULL) {
103  return FALSE;
104  }
105  }
106  g_message("Message [\"%s\"] not found in %d expected messages."
107  , message, msgcount);
108  fflush(stdout);
109  for (mptr = messagelist; mptr && *mptr; ++mptr) {
110  g_message("Expected message: \"%s\"", *mptr);
111  fflush(stdout);
112  }
113  g_message("ABORTING: message was not an expected failure.");
114  fflush(stdout);
115  g_message("No further gtest02 tests will be run. Bye bye!");
116  fflush(stdout);
117  if (!bad_msg) {
118  bad_msg = strdup(message);
119  expected_msgs = messagelist;
120  }
121  return FALSE;
122 }
123 
125 #define DUMB "\""CONFIGNAME_INSTANCE"\":\"dumb\""
126 #define PROV ",\"" REQPROVIDERNAMEFIELD "\": \"heartbeat\"}"
127 
128 
129 
130 FSTATIC void
132 {
133  ChildProcess* my_child_is_a_failure;
134  char devnull [] = "/dev/null";
135  char* argv[] = {devnull, NULL};
136  const char * expected_failures[] = {"Failed to execute child process \"/dev/null\"", NULL};
137 
138  set_expected_failures(expected_failures);
139 
140  my_child_is_a_failure = childprocess_new(0
141  , argv // command and arguments
142  , NULL // envp
143  , NULL // envmod
144  , "/" // curdir
145  , NULL // notify process
146  , FALSE // save_stdout
147  , "foo" // logdomain
148  , "bar" // logprefix
149  , 0 // GLogLevelFlags loglevel
150  , 0 // timeout seconds
151  , NULL // user_data
152  , CHILD_LOGALL // ChildErrLogMode logmode
153  , "failurechild" // logname
154  );
155  g_assert(my_child_is_a_failure == NULL);
156  test_all_freed();
157 }
158 
159 FSTATIC void
161 {
162 
163  const char * json_cmds[] = {
164  "{}",
165 
166  "{\"" REQCLASSNAMEFIELD "\": \"NOSUCHRESOURCECLASS\","DUMB PROV,
167 
168  "{\"" REQCLASSNAMEFIELD "\":\"ocf\"" PROV,
169 
170  "{\"" REQCLASSNAMEFIELD "\":\"ocf\"," DUMB PROV,
171 
172  "{\"" REQCLASSNAMEFIELD "\":\"ocf\", \"" CONFIGNAME_TYPE "\":\"NOSUCHOCFRESOURCETYPE\","DUMB PROV,
173 
174  "{\"" REQCLASSNAMEFIELD "\":\"ocf\", \"" CONFIGNAME_TYPE "\":\"NOSUCHOCFRESOURCETYPE\",\""
175  REQOPERATIONNAMEFIELD"\":\"monitor\","DUMB PROV,
176 
177  "{\"" REQCLASSNAMEFIELD "\":\"ocf\", \"" CONFIGNAME_TYPE "\":\"NOSUCHOCFRESOURCETYPE\",\""
178  REQOPERATIONNAMEFIELD"\":\"monitor\","
179  "\""REQENVIRONNAMEFIELD"\":\"notahash\","DUMB PROV,
180 
181  "{\"" REQCLASSNAMEFIELD "\":\"lsb\", \"" CONFIGNAME_TYPE "\":\"NOSUCHOCFRESOURCETYPE\",\""
182  REQOPERATIONNAMEFIELD"\":\"monitor\"}",
183  NULL
184  };
185  const char * expected_failures[] = {
186  ": No class name in request [{}]",
187  ": No resource name in request [{\"class\":\"ocf\",\"provider\":\"heartbeat\"}]",
188  ": Invalid resource class [NOSUCHRESOURCECLASS]",
189  ": NULL resourcecmd request",
190  ": No type field in OCF agent request.",
191  ": No operation field in OCF agent request.",
192  ": No OCF Resource agent [/usr/lib/ocf/resource.d/heartbeat/NOSUCHOCFRESOURCETYPE]",
193  ": No LSB Resource agent [/etc/init.d/NOSUCHOCFRESOURCETYPE]",
194  ": environ field in OCF request is invalid.",
195  NULL
196  };
197  guint j;
198 
199  set_expected_failures(expected_failures);
200 
201  for (j=0; j < DIMOF(json_cmds); ++j) {
202  ConfigContext* request = NULL;
203  ResourceCmd* rcmd;
204  if (json_cmds[j] != NULL) {
205  request = configcontext_new_JSON_string(json_cmds[j]);
206  g_assert(request != NULL);
207  }
208  rcmd = resourcecmd_new(request, NULL, NULL);
209  g_assert(NULL == rcmd);
210  if (NULL != rcmd) {
211  UNREF(rcmd);
212  }
213  if (NULL != request) {
214  UNREF(request);
215  }
216  }
217  test_all_freed();
218 }
219 
220 FSTATIC void
222 {
224  const char * json_cmds[] = {
225  "{\"" REQCLASSNAMEFIELD "\":\"ocf\", \"" CONFIGNAME_TYPE "\":\"Dummy\","
226  "\""REQENVIRONNAMEFIELD"\":{},"
227  "\""REQOPERATIONNAMEFIELD"\":\"monitor\","DUMB PROV,
228  };
229  unsigned j;
230  const char * expected_failures[] = {
231  ": Request rejected - no request id",
232  ": NULL resourcecmd request",
233  NULL,
234  };
235 
236  set_expected_failures(expected_failures);
237 
238 
239  g_assert_cmpint(rq->Qcmd(rq, NULL, NULL, NULL), ==, 0);
240 
241 
242  for (j=0; j < DIMOF(json_cmds); ++j) {
243  ConfigContext* cfg = configcontext_new_JSON_string(json_cmds[j]);
244  g_assert_cmpint(rq->Qcmd(rq, cfg, NULL, NULL), ==, 0);
245  UNREF(cfg);
246  }
247  UNREF(rq);
248  test_all_freed();
249 }
250 
251 
253 int
254 main(int argc, char ** argv)
255 {
256 #ifdef HAVE_MCHECK_PEDANTIC
257  // Unfortunately sometimes being first thing in main isn't soon enough :-(
258  mcheck_pedantic(NULL);
259 #else
260 # ifdef HAVE_MCHECK
261  // Unfortunately sometimes being first thing in main isn't soon enough :-(
262  mcheck(NULL);
263 # endif
264 #endif
265  g_setenv("G_MESSAGES_DEBUG", "all", TRUE);
266  g_log_set_fatal_mask(NULL, 0); // I know G_LOG_LEVEL_ERROR is fatal anyway...
267  g_test_init(&argc, &argv, NULL);
268  g_log_set_fatal_mask(NULL, 0);
269  g_test_add_func("/gtest02/test_childprocess_failure", test_childprocess_failure);
270  g_test_add_func("/gtest02/test_invalid_resourcecmd", test_invalid_resourcecmd);
271  g_test_add_func("/gtest02/test_invalid_queuecmd", test_invalid_queuecmd);
272  return g_test_run();
273 }
ConfigContext * configcontext_new_JSON_string(const char *jsontext)
Construct a ConfigContext object from the given JSON string.
Log all exits - normal or abnormal.
Definition: childprocess.h:49
gboolean(* Qcmd)(ResourceQueue *self, ConfigContext *request, ResourceCmdCallback callback, gpointer user_data)
Definition: resourcequeue.h:55
#define CONFIGNAME_TYPE
Type of resource or discovery.
#define PROV
Definition: gtest02.c:126
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
FSTATIC void test_invalid_queuecmd(void)
Definition: gtest02.c:221
#define REQOPERATIONNAMEFIELD
Definition: resourcecmd.h:71
#define REQCLASSNAMEFIELD
Definition: resourcecmd.h:69
#define FSTATIC
Definition: projectcommon.h:31
FSTATIC void test_all_freed(void)
gtest02.c - miscellaneous client-only tests not requiring mainloop.
Definition: gtest02.c:55
FSTATIC void test_childprocess_failure(void)
Definition: gtest02.c:131
const char ** expected_msgs
Definition: gtest02.c:44
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
FSTATIC void test_invalid_resourcecmd(void)
Definition: gtest02.c:160
char * bad_msg
Definition: gtest02.c:43
#define DUMB
Definition: gtest02.c:125
ResourceQueue * resourcequeue_new(guint structsize)
Construct a new ResourceQueue system (you probably only need one)
Definition: resourcequeue.c:80
#define REQENVIRONNAMEFIELD
Definition: resourcecmd.h:72
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
Implements the resource queue class.
FSTATIC void set_expected_failures(const char **the_usual_suspects)
Definition: gtest02.c:47
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
FSTATIC gboolean logfatal_function(const gchar *, GLogLevelFlags, const gchar *, gpointer)
Try various invalid resource command initializers.
Definition: gtest02.c:79
Implements Child Process class.
#define UNREF(obj)
Definition: assimobj.h:35
int main(int argc, char **argv)
Test main program (&#39;/gtest02&#39;) using the glib test fixtures.
Definition: gtest02.c:254