FOSSology  4.4.0
Open Source License Compliance by Open Source Software
testInterface.c
Go to the documentation of this file.
1 /*
2  SPDX-FileCopyrightText: © 2011 Hewlett-Packard Development Company, L.P.
3 
4  SPDX-License-Identifier: GPL-2.0-only
5 */
11 /* include functions to test */
12 #include <testRun.h>
13 
14 /* scheduler includes */
15 #include <event.h>
16 #include <host.h>
17 #include <interface.h>
18 #include <scheduler.h>
19 
20 /* library includes */
21 #include <gio/gio.h>
22 #include <glib.h>
23 #include <sys/socket.h>
24 #include <sys/types.h>
25 #include <netinet/in.h>
26 #include <netdb.h>
27 #include <unistd.h>
28 
29 /* ************************************************************************** */
30 /* **** local declarations ************************************************** */
31 /* ************************************************************************** */
32 
36 #if defined(__amd64__)
37  #define mint_t int64_t
38 #else
39  #define mint_t int32_t
40 #endif
41 
51 int socket_connect(char* host, char* port)
52 {
53  int fd;
54  struct addrinfo hints;
55  struct addrinfo* servs, * curr;
56 
57  servs = NULL;
58  curr = NULL;
59 
60  memset(&hints, 0, sizeof(hints));
61  hints.ai_family = AF_UNSPEC;
62  hints.ai_socktype = SOCK_STREAM;
63  if(getaddrinfo(host, port, &hints, &servs) == -1)
64  {
65  fprintf(stderr, "ERROR: %s.%d: unable to connect to %s port: %s\n",
66  __FILE__, __LINE__, host, port);
67  fprintf(stderr, "ERROR: errno: %s\n", strerror(errno));
68  return 0;
69  }
70 
71  for(curr = servs; curr != NULL; curr = curr->ai_next)
72  {
73  if((fd = socket(curr->ai_family, hints.ai_socktype, curr->ai_protocol)) < 0)
74  continue;
75 
76  if(connect(fd, curr->ai_addr, curr->ai_addrlen) == -1)
77  continue;
78 
79  break;
80  }
81 
82  if(curr == NULL)
83  {
84  fprintf(stderr, "ERROR: %s.%d: unable to connect to %s port: %s\n",
85  __FILE__, __LINE__, host, port);
86  return 0;
87  }
88 
89  freeaddrinfo(servs);
90  return fd;
91 }
92 
93 void* interface_listen_thread(void* unused);
94 
95 /* ************************************************************************** */
96 /* **** interface function tests ******************************************** */
97 /* ************************************************************************** */
98 
113 {
114  scheduler_t* scheduler;
115  GThread* interface_thread;
116 
117  scheduler = scheduler_init(testdb, NULL);
118  scheduler_foss_config(scheduler);
119  interface_init(scheduler);
120 
121  FO_ASSERT_TRUE(scheduler->i_created);
122  FO_ASSERT_FALSE(scheduler->i_terminate);
123 
124  FO_ASSERT_PTR_NOT_NULL(scheduler->server);
125  FO_ASSERT_PTR_NOT_NULL(scheduler->workers);
126  FO_ASSERT_PTR_NOT_NULL(scheduler->cancel);
127 
128  interface_thread = scheduler->server;
129  interface_init(scheduler);
130 
131  FO_ASSERT_TRUE(scheduler->i_created);
132  FO_ASSERT_FALSE(scheduler->i_terminate);
133 
134  FO_ASSERT_PTR_NOT_NULL(scheduler->server);
135  FO_ASSERT_PTR_EQUAL(scheduler->server, interface_thread);
136 
137  interface_destroy(scheduler);
138  scheduler_destroy(scheduler);
139 }
140 
151 {
152  scheduler_t* scheduler;
153 
154  scheduler = scheduler_init(testdb, NULL);
155  scheduler_foss_config(scheduler);
156  interface_destroy(scheduler);
157 
158  FO_ASSERT_FALSE(scheduler->i_created);
159  FO_ASSERT_FALSE(scheduler->i_terminate);
160 
161  interface_init(scheduler);
162 
163  FO_ASSERT_TRUE(scheduler->i_created);
164  FO_ASSERT_FALSE(scheduler->i_terminate);
165 
166  interface_destroy(scheduler);
167 
168  FO_ASSERT_FALSE(scheduler->i_created);
169  FO_ASSERT_TRUE(scheduler->i_terminate);
170 
171  scheduler_destroy(scheduler);
172 }
173 
186 {
187  mint_t result;
188  scheduler_t* scheduler;
189 
190  scheduler = scheduler_init(testdb, NULL);
191  scheduler_foss_config(scheduler);
192  scheduler->i_terminate = TRUE;
193  scheduler->i_created = TRUE;
194  result = (mint_t)interface_listen_thread(scheduler);
195  FO_ASSERT_FALSE(result);
196 
197  scheduler->i_terminate = FALSE;
198  scheduler->i_created = FALSE;
199  result = (mint_t)interface_listen_thread(scheduler);
200  FO_ASSERT_FALSE(result);
201 
202  scheduler_destroy(scheduler);
203 }
204 
215 {
216  scheduler_t* scheduler;
217  char buffer[256];
218  int soc;
219 
220  scheduler = scheduler_init(testdb, NULL);
221  scheduler_foss_config(scheduler);
222  scheduler->i_terminate = FALSE;
223  scheduler->i_created = FALSE;
224  interface_init(scheduler);
225  sleep(1);
226 
227  FO_ASSERT_EQUAL(g_thread_pool_get_max_threads(scheduler->workers), CONF_interface_nthreads);
228  FO_ASSERT_EQUAL(g_thread_pool_unprocessed(scheduler->workers), 0);
229 
230  snprintf(buffer, sizeof(buffer), "%d", scheduler->i_port);
231  soc = socket_connect("localhost", buffer);
232  sleep(1);
233 
234  FO_ASSERT_TRUE(soc);
235  FO_ASSERT_EQUAL(g_thread_pool_unprocessed(scheduler->workers), 0);
236 
237  close(soc);
238  interface_destroy(scheduler);
239  scheduler_destroy(scheduler);
240 }
241 
242 /* ************************************************************************** */
243 /* **** test the interface_thread function **** */
244 /* **** The interface thread function is rather complicated, so it **** */
245 /* **** gets its own test suite. **** */
246 /* ************************************************************************** */
247 
248 #define CREATE_INTERFACE(name) \
249  scheduler_t* name; \
250  name = scheduler_init(testdb, NULL); \
251  scheduler_foss_config(name); \
252  scheduler_agent_config(name); \
253  event_loop_destroy(); \
254  interface_init(name)
255 
256 #define SEND_RECEIVE(string, len, res) \
257  snprintf(buffer, sizeof(buffer), string); \
258  result = write(soc, buffer, strlen(buffer)); \
259  FO_ASSERT_EQUAL((int)result, (int)strlen(buffer)); \
260  sleep(1); \
261  memset(buffer, '\0', sizeof(buffer)); \
262  result = read(soc, buffer, sizeof(buffer)); \
263  FO_ASSERT_EQUAL((int)result, (int)len); \
264  FO_ASSERT_STRING_EQUAL(buffer, res)
265 
276 {
277  // buffer for the port that the interface is listening on
278  char buffer[1024];
279  int soc;
280  ssize_t result;
281 
282  // create data structures
283  CREATE_INTERFACE(scheduler);
284 
285  // Create the connection to the scheduler
286  snprintf(buffer, sizeof(buffer), "%d", scheduler->i_port);
287  soc = socket_connect("localhost", buffer);
288  FO_ASSERT_TRUE_FATAL(soc);
289 
290  snprintf(buffer, sizeof(buffer), "close");
291 
292  result = write(soc, buffer, strlen(buffer));
293  FO_ASSERT_EQUAL((int)result, 5);
294  sleep(1);
295 
296  memset(buffer, '\0', sizeof(buffer));
297  result = read(soc, buffer, sizeof(buffer));
298  FO_ASSERT_EQUAL((int)result, 15)
299  FO_ASSERT_STRING_EQUAL(buffer,
300  "received\n"
301  "CLOSE\n");
302 
303  close(soc);
304  interface_destroy(scheduler);
305  scheduler_destroy(scheduler);
306 }
307 
318 {
319  char buffer[1024];
320  int soc;
321  ssize_t result;
322 
323  // create data structures
324  CREATE_INTERFACE(scheduler);
325  host_insert(host_init("localhost", "localhost", "AGENT_DIR", 10), scheduler);
326 
327  // create the connection
328  snprintf(buffer, sizeof(buffer), "%d", scheduler->i_port);
329  soc = socket_connect("localhost", buffer);
330  FO_ASSERT_TRUE_FATAL(soc);
331  SEND_RECEIVE("load", 64,
332  "received\n"
333  "host:localhost address:localhost max:10 running:0\n"
334  "\nend\n");
335 
336  close(soc);
337  interface_destroy(scheduler);
338  scheduler_destroy(scheduler);
339 }
340 
354 {
355  char buffer[1024];
356  int soc;
357  ssize_t result;
358 
359  // create data structures
360  CREATE_INTERFACE(scheduler);
361  sleep(1);
362 
363  // create the connection
364  snprintf(buffer, sizeof(buffer), "%d", scheduler->i_port);
365  soc = socket_connect("localhost", buffer);
366  FO_ASSERT_TRUE_FATAL(soc);
367 
368  /* test no arguments to kill
369  *
370  * Sending: kill
371  * Receive: received
372  * Invalid kill command: "kill"
373  */
374  SEND_RECEIVE("kill", 38,
375  "received\n"
376  "Invalid kill command: \"kill\"\n");
377 
378  /* test one argument to kill
379  *
380  * Sending: kill 1
381  * Receive: received
382  * Invalid kill command: "kill 1"
383  */
384  SEND_RECEIVE("kill 1", 40,
385  "received\n"
386  "Invalid kill command: \"kill 1\"\n");
387 
388  /* test only second argument to kill
389  *
390  * Sending: kill "test"
391  * Receive: received
392  * Invalid kill command: "kill "test""
393  */
394  SEND_RECEIVE("kill \"test\"", 45,
395  "received\n"
396  "Invalid kill command: \"kill \"test\"\"\n");
397 
398  /* test valid kill command
399  *
400  * Sending: kill 1 "test"
401  * Receive: received
402  */
403  SEND_RECEIVE("kill 1 \"test\"", 9,
404  "received\n");
405 
406  result = g_async_queue_length(event_loop_get()->queue);
407  FO_ASSERT_EQUAL((int)result, 1);
408 
409  close(soc);
410  interface_destroy(scheduler);
411  scheduler_destroy(scheduler);
412 }
413 
427 {
428  char buffer[1024];
429  int soc;
430  ssize_t result;
431 
432  // create data structures
433  CREATE_INTERFACE(scheduler);
434 
435  // create the connection
436  snprintf(buffer, sizeof(buffer), "%d", scheduler->i_port);
437  soc = socket_connect("localhost", buffer);
438  FO_ASSERT_TRUE_FATAL(soc);
439 
440  /* Pause command no arguments
441  *
442  * Sending: pause
443  * Receive: received
444  * Invalid pause command: "pause:
445  */
446  SEND_RECEIVE("pause", 40,
447  "received\n"
448  "Invalid pause command: \"pause\"\n");
449 
450  /* Pause command with wrong arugment type
451  *
452  * Sending: pause "test"
453  * Receive: received
454  * Invalid pause command: "pause "test""
455  */
456  SEND_RECEIVE("pause \"test\"", 47,
457  "received\n"
458  "Invalid pause command: \"pause \"test\"\"\n");
459 
460  /* Correct pause command
461  *
462  * Sending: pause 1
463  * Receive: received
464  */
465  SEND_RECEIVE("pause 1", 9,
466  "received\n");
467 
468  result = g_async_queue_length(event_loop_get()->queue);
469  FO_ASSERT_EQUAL((int)result, 1);
470 
471  close(soc);
472  interface_destroy(scheduler);
473  scheduler_destroy(scheduler);
474 }
475 
486 {
487  char buffer[1024];
488  int soc;
489  ssize_t result;
490  event_t* event;
491 
492  // create data structures
493  CREATE_INTERFACE(scheduler);
494 
495  // create the connection
496  snprintf(buffer, sizeof(buffer), "%d", scheduler->i_port);
497  soc = socket_connect("localhost", buffer);
498  FO_ASSERT_TRUE_FATAL(soc);
499 
500  SEND_RECEIVE("reload", 9,
501  "received\n");
502 
503  result = g_async_queue_length(event_loop_get()->queue);
504  event = g_async_queue_pop(event_loop_get()->queue);
505  FO_ASSERT_EQUAL((int)result, 1);
506  FO_ASSERT_PTR_EQUAL((void*)event->func, (void*)scheduler_config_event);
507  FO_ASSERT_STRING_EQUAL(event->source_name, "interface.c");
508 
509  close(soc);
510  interface_destroy(scheduler);
511  scheduler_destroy(scheduler);
512 }
513 
524 {
525  char buffer[1024];
526  int soc;
527  ssize_t result;
528  event_t* event;
529 
530  // create data structures
531  CREATE_INTERFACE(scheduler);
532 
533  // create the connection
534  snprintf(buffer, sizeof(buffer), "%d", scheduler->i_port);
535  soc = socket_connect("localhost", buffer);
536  FO_ASSERT_TRUE_FATAL(soc);
537 
538  SEND_RECEIVE("agents", 9,
539  "received\n");
540 
541  result = g_async_queue_length(event_loop_get()->queue);
542  event = g_async_queue_pop(event_loop_get()->queue);
543  FO_ASSERT_EQUAL((int)result, 1);
544  FO_ASSERT_PTR_EQUAL((void*)event->func, (void*)list_agents_event);
545  FO_ASSERT_STRING_EQUAL(event->source_name, "interface.c");
546 
547  close(soc);
548  interface_destroy(scheduler);
549  scheduler_destroy(scheduler);
550 }
551 
552 /* ************************************************************************** */
553 /* **** suite declaration *************************************************** */
554 /* ************************************************************************** */
555 
556 CU_TestInfo tests_interface[] =
557 {
558  {"Test interface_init", test_interface_init },
559  {"Test interface_destroy", test_interface_destroy },
560  {"Test interface_listen_thread", test_interface_listen_thread },
561  {"Test interface_pool", test_interface_pool },
562  CU_TEST_INFO_NULL
563 };
564 
565 CU_TestInfo tests_interface_thread[] =
566 {
567  {"Test sending \"close\"", test_sending_close },
568  {"Test sending \"load\"", test_sending_load },
569  {"Test sending \"kill\"", test_sending_kill },
570  {"Test sending \"pause\"", test_sending_pause },
571  {"Test sending \"status\"", test_sending_reload },
572  CU_TEST_INFO_NULL
573 };
574 
575 
576 
577 
void list_agents_event(scheduler_t *scheduler, GOutputStream *ostr)
Receive agent on interface.
Definition: agent.c:1118
event_loop_t * event_loop_get()
Definition: event.c:48
Event handling operations.
void host_insert(host_t *host, scheduler_t *scheduler)
Inserts a new host into the scheduler structure.
Definition: host.c:91
host_t * host_init(char *name, char *address, char *agent_dir, int max)
Creates a new host, and adds it to the host list.
Definition: host.c:48
void interface_thread(interface_connection *conn, scheduler_t *scheduler)
Function that will run the thread associated with a particular interface instance.
Definition: interface.c:126
void interface_destroy(scheduler_t *scheduler)
Closes the server socket and thread pool that service UI connections.
Definition: interface.c:588
void * interface_listen_thread(scheduler_t *scheduler)
Function that will listen for new connections to the server sockets.
Definition: interface.c:494
void interface_init(scheduler_t *scheduler)
Create the interface thread and thread pool that handle UI connections.
Definition: interface.c:554
char buffer[2048]
The last thing received from the scheduler.
void scheduler_config_event(scheduler_t *scheduler, void *unused)
Load both the fossology configuration and all the agent configurations.
Definition: scheduler.c:991
scheduler_t * scheduler_init(gchar *sysconfigdir, log_t *log)
Create a new scheduler object.
Definition: scheduler.c:249
void scheduler_foss_config(scheduler_t *scheduler)
Loads the configuration data from fossology.conf.
Definition: scheduler.c:853
void scheduler_destroy(scheduler_t *scheduler)
Free any memory associated with a scheduler_t.
Definition: scheduler.c:362
Definition: event.h:24
char * source_name
Name of the source file creating the event.
Definition: event.h:28
void(* func)(scheduler_t *, void *)
The function that will be executed for this event.
Definition: event.h:25
GThread * server
Thread that is listening to the server socket.
Definition: scheduler.h:167
GThreadPool * workers
Threads to handle incoming network communication.
Definition: scheduler.h:168
gboolean i_terminate
Has the interface been terminated.
Definition: scheduler.h:165
GCancellable * cancel
Used to stop the listening thread when it is running.
Definition: scheduler.h:169
gboolean i_created
Has the interface been created.
Definition: scheduler.h:164
uint16_t i_port
The port that the scheduler is listening on.
Definition: scheduler.h:166
void test_sending_reload()
Test for reload message on interface.
void test_interface_init()
Test for interface_init()
void test_sending_pause()
Test for pause message on interface.
void test_interface_destroy()
Test for interface_destroy()
void test_interface_listen_thread()
Test for interface_listen_thread()
void test_sending_close()
Test for close message on interface.
#define mint_t
Definition: testInterface.c:39
void test_sending_kill()
Test for kill message on interface.
void test_sending_agents()
Test for agent message on interface.
int socket_connect(char *host, char *port)
Create a socket connection.
Definition: testInterface.c:51
void test_interface_pool()
Test for interface_init() thread pool.
void test_sending_load()
Test for load message on interface.