FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
testInterface.c
Go to the documentation of this file.
1 /*********************************************************************
2 Copyright (C) 2011 Hewlett-Packard Development Company, L.P.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 version 2 as published by the Free Software Foundation.
7 
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 
13 You should have received a copy of the GNU General Public License along
14 with this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 *********************************************************************/
22 /* include functions to test */
23 #include <testRun.h>
24 
25 /* scheduler includes */
26 #include <event.h>
27 #include <host.h>
28 #include <interface.h>
29 #include <scheduler.h>
30 
31 /* library includes */
32 #include <gio/gio.h>
33 #include <glib.h>
34 #include <sys/socket.h>
35 #include <sys/types.h>
36 #include <netinet/in.h>
37 #include <netdb.h>
38 #include <unistd.h>
39 
40 /* ************************************************************************** */
41 /* **** local declarations ************************************************** */
42 /* ************************************************************************** */
43 
47 #if defined(__amd64__)
48  #define mint_t int64_t
49 #else
50  #define mint_t int32_t
51 #endif
52 
62 int socket_connect(char* host, char* port)
63 {
64  int fd;
65  struct addrinfo hints;
66  struct addrinfo* servs, * curr;
67 
68  servs = NULL;
69  curr = NULL;
70 
71  memset(&hints, 0, sizeof(hints));
72  hints.ai_family = AF_UNSPEC;
73  hints.ai_socktype = SOCK_STREAM;
74  if(getaddrinfo(host, port, &hints, &servs) == -1)
75  {
76  fprintf(stderr, "ERROR: %s.%d: unable to connect to %s port: %s\n",
77  __FILE__, __LINE__, host, port);
78  fprintf(stderr, "ERROR: errno: %s\n", strerror(errno));
79  return 0;
80  }
81 
82  for(curr = servs; curr != NULL; curr = curr->ai_next)
83  {
84  if((fd = socket(curr->ai_family, hints.ai_socktype, curr->ai_protocol)) < 0)
85  continue;
86 
87  if(connect(fd, curr->ai_addr, curr->ai_addrlen) == -1)
88  continue;
89 
90  break;
91  }
92 
93  if(curr == NULL)
94  {
95  fprintf(stderr, "ERROR: %s.%d: unable to connect to %s port: %s\n",
96  __FILE__, __LINE__, host, port);
97  return 0;
98  }
99 
100  freeaddrinfo(servs);
101  return fd;
102 }
103 
104 void* interface_listen_thread(void* unused);
105 
106 /* ************************************************************************** */
107 /* **** interface function tests ******************************************** */
108 /* ************************************************************************** */
109 
124 {
125  scheduler_t* scheduler;
126  GThread* interface_thread;
127 
128  scheduler = scheduler_init(testdb, NULL);
129  scheduler_foss_config(scheduler);
130  interface_init(scheduler);
131 
132  FO_ASSERT_TRUE(scheduler->i_created);
133  FO_ASSERT_FALSE(scheduler->i_terminate);
134 
135  FO_ASSERT_PTR_NOT_NULL(scheduler->server);
136  FO_ASSERT_PTR_NOT_NULL(scheduler->workers);
137  FO_ASSERT_PTR_NOT_NULL(scheduler->cancel);
138 
139  interface_thread = scheduler->server;
140  interface_init(scheduler);
141 
142  FO_ASSERT_TRUE(scheduler->i_created);
143  FO_ASSERT_FALSE(scheduler->i_terminate);
144 
145  FO_ASSERT_PTR_NOT_NULL(scheduler->server);
146  FO_ASSERT_PTR_EQUAL(scheduler->server, interface_thread);
147 
148  interface_destroy(scheduler);
149  scheduler_destroy(scheduler);
150 }
151 
162 {
163  scheduler_t* scheduler;
164 
165  scheduler = scheduler_init(testdb, NULL);
166  scheduler_foss_config(scheduler);
167  interface_destroy(scheduler);
168 
169  FO_ASSERT_FALSE(scheduler->i_created);
170  FO_ASSERT_FALSE(scheduler->i_terminate);
171 
172  interface_init(scheduler);
173 
174  FO_ASSERT_TRUE(scheduler->i_created);
175  FO_ASSERT_FALSE(scheduler->i_terminate);
176 
177  interface_destroy(scheduler);
178 
179  FO_ASSERT_FALSE(scheduler->i_created);
180  FO_ASSERT_TRUE(scheduler->i_terminate);
181 
182  scheduler_destroy(scheduler);
183 }
184 
197 {
198  mint_t result;
199  scheduler_t* scheduler;
200 
201  scheduler = scheduler_init(testdb, NULL);
202  scheduler_foss_config(scheduler);
203  scheduler->i_terminate = TRUE;
204  scheduler->i_created = TRUE;
205  result = (mint_t)interface_listen_thread(scheduler);
206  FO_ASSERT_FALSE(result);
207 
208  scheduler->i_terminate = FALSE;
209  scheduler->i_created = FALSE;
210  result = (mint_t)interface_listen_thread(scheduler);
211  FO_ASSERT_FALSE(result);
212 
213  scheduler_destroy(scheduler);
214 }
215 
226 {
227  scheduler_t* scheduler;
228  char buffer[256];
229  int soc;
230 
231  scheduler = scheduler_init(testdb, NULL);
232  scheduler_foss_config(scheduler);
233  scheduler->i_terminate = FALSE;
234  scheduler->i_created = FALSE;
235  interface_init(scheduler);
236  sleep(1);
237 
238  FO_ASSERT_EQUAL(g_thread_pool_get_max_threads(scheduler->workers), CONF_interface_nthreads);
239  FO_ASSERT_EQUAL(g_thread_pool_unprocessed(scheduler->workers), 0);
240 
241  snprintf(buffer, sizeof(buffer), "%d", scheduler->i_port);
242  soc = socket_connect("localhost", buffer);
243  sleep(1);
244 
245  FO_ASSERT_TRUE(soc);
246  FO_ASSERT_EQUAL(g_thread_pool_unprocessed(scheduler->workers), 0);
247 
248  close(soc);
249  interface_destroy(scheduler);
250  scheduler_destroy(scheduler);
251 }
252 
253 /* ************************************************************************** */
254 /* **** test the interface_thread function **** */
255 /* **** The interface thread function is rather complicated, so it **** */
256 /* **** gets its own test suite. **** */
257 /* ************************************************************************** */
258 
259 #define CREATE_INTERFACE(name) \
260  scheduler_t* name; \
261  name = scheduler_init(testdb, NULL); \
262  scheduler_foss_config(name); \
263  scheduler_agent_config(name); \
264  event_loop_destroy(); \
265  interface_init(name)
266 
267 #define SEND_RECEIVE(string, len, res) \
268  snprintf(buffer, sizeof(buffer), string); \
269  result = write(soc, buffer, strlen(buffer)); \
270  FO_ASSERT_EQUAL((int)result, (int)strlen(buffer)); \
271  sleep(1); \
272  memset(buffer, '\0', sizeof(buffer)); \
273  result = read(soc, buffer, sizeof(buffer)); \
274  FO_ASSERT_EQUAL((int)result, (int)len); \
275  FO_ASSERT_STRING_EQUAL(buffer, res)
276 
287 {
288  // buffer for the port that the interface is listening on
289  char buffer[1024];
290  int soc;
291  ssize_t result;
292 
293  // create data structures
294  CREATE_INTERFACE(scheduler);
295 
296  // Create the connection to the scheduler
297  snprintf(buffer, sizeof(buffer), "%d", scheduler->i_port);
298  soc = socket_connect("localhost", buffer);
299  FO_ASSERT_TRUE_FATAL(soc);
300 
301  snprintf(buffer, sizeof(buffer), "close");
302 
303  result = write(soc, buffer, strlen(buffer));
304  FO_ASSERT_EQUAL((int)result, 5);
305  sleep(1);
306 
307  memset(buffer, '\0', sizeof(buffer));
308  result = read(soc, buffer, sizeof(buffer));
309  FO_ASSERT_EQUAL((int)result, 15)
310  FO_ASSERT_STRING_EQUAL(buffer,
311  "received\n"
312  "CLOSE\n");
313 
314  close(soc);
315  interface_destroy(scheduler);
316  scheduler_destroy(scheduler);
317 }
318 
329 {
330  char buffer[1024];
331  int soc;
332  ssize_t result;
333 
334  // create data structures
335  CREATE_INTERFACE(scheduler);
336  host_insert(host_init("localhost", "localhost", "AGENT_DIR", 10), scheduler);
337 
338  // create the connection
339  snprintf(buffer, sizeof(buffer), "%d", scheduler->i_port);
340  soc = socket_connect("localhost", buffer);
341  FO_ASSERT_TRUE_FATAL(soc);
342  SEND_RECEIVE("load", 64,
343  "received\n"
344  "host:localhost address:localhost max:10 running:0\n"
345  "\nend\n");
346 
347  close(soc);
348  interface_destroy(scheduler);
349  scheduler_destroy(scheduler);
350 }
351 
365 {
366  char buffer[1024];
367  int soc;
368  ssize_t result;
369 
370  // create data structures
371  CREATE_INTERFACE(scheduler);
372  sleep(1);
373 
374  // create the connection
375  snprintf(buffer, sizeof(buffer), "%d", scheduler->i_port);
376  soc = socket_connect("localhost", buffer);
377  FO_ASSERT_TRUE_FATAL(soc);
378 
379  /* test no arguments to kill
380  *
381  * Sending: kill
382  * Receive: received
383  * Invalid kill command: "kill"
384  */
385  SEND_RECEIVE("kill", 38,
386  "received\n"
387  "Invalid kill command: \"kill\"\n");
388 
389  /* test one argument to kill
390  *
391  * Sending: kill 1
392  * Receive: received
393  * Invalid kill command: "kill 1"
394  */
395  SEND_RECEIVE("kill 1", 40,
396  "received\n"
397  "Invalid kill command: \"kill 1\"\n");
398 
399  /* test only second argument to kill
400  *
401  * Sending: kill "test"
402  * Receive: received
403  * Invalid kill command: "kill "test""
404  */
405  SEND_RECEIVE("kill \"test\"", 45,
406  "received\n"
407  "Invalid kill command: \"kill \"test\"\"\n");
408 
409  /* test valid kill command
410  *
411  * Sending: kill 1 "test"
412  * Receive: received
413  */
414  SEND_RECEIVE("kill 1 \"test\"", 9,
415  "received\n");
416 
417  result = g_async_queue_length(event_loop_get()->queue);
418  FO_ASSERT_EQUAL((int)result, 1);
419 
420  close(soc);
421  interface_destroy(scheduler);
422  scheduler_destroy(scheduler);
423 }
424 
438 {
439  char buffer[1024];
440  int soc;
441  ssize_t result;
442 
443  // create data structures
444  CREATE_INTERFACE(scheduler);
445 
446  // create the connection
447  snprintf(buffer, sizeof(buffer), "%d", scheduler->i_port);
448  soc = socket_connect("localhost", buffer);
449  FO_ASSERT_TRUE_FATAL(soc);
450 
451  /* Pause command no arguments
452  *
453  * Sending: pause
454  * Receive: received
455  * Invalid pause command: "pause:
456  */
457  SEND_RECEIVE("pause", 40,
458  "received\n"
459  "Invalid pause command: \"pause\"\n");
460 
461  /* Pause command with wrong arugment type
462  *
463  * Sending: pause "test"
464  * Receive: received
465  * Invalid pause command: "pause "test""
466  */
467  SEND_RECEIVE("pause \"test\"", 47,
468  "received\n"
469  "Invalid pause command: \"pause \"test\"\"\n");
470 
471  /* Correct pause command
472  *
473  * Sending: pause 1
474  * Receive: received
475  */
476  SEND_RECEIVE("pause 1", 9,
477  "received\n");
478 
479  result = g_async_queue_length(event_loop_get()->queue);
480  FO_ASSERT_EQUAL((int)result, 1);
481 
482  close(soc);
483  interface_destroy(scheduler);
484  scheduler_destroy(scheduler);
485 }
486 
497 {
498  char buffer[1024];
499  int soc;
500  ssize_t result;
501  event_t* event;
502 
503  // create data structures
504  CREATE_INTERFACE(scheduler);
505 
506  // create the connection
507  snprintf(buffer, sizeof(buffer), "%d", scheduler->i_port);
508  soc = socket_connect("localhost", buffer);
509  FO_ASSERT_TRUE_FATAL(soc);
510 
511  SEND_RECEIVE("reload", 9,
512  "received\n");
513 
514  result = g_async_queue_length(event_loop_get()->queue);
515  event = g_async_queue_pop(event_loop_get()->queue);
516  FO_ASSERT_EQUAL((int)result, 1);
517  FO_ASSERT_PTR_EQUAL((void*)event->func, (void*)scheduler_config_event);
518  FO_ASSERT_STRING_EQUAL(event->source_name, "interface.c");
519 
520  close(soc);
521  interface_destroy(scheduler);
522  scheduler_destroy(scheduler);
523 }
524 
535 {
536  char buffer[1024];
537  int soc;
538  ssize_t result;
539  event_t* event;
540 
541  // create data structures
542  CREATE_INTERFACE(scheduler);
543 
544  // create the connection
545  snprintf(buffer, sizeof(buffer), "%d", scheduler->i_port);
546  soc = socket_connect("localhost", buffer);
547  FO_ASSERT_TRUE_FATAL(soc);
548 
549  SEND_RECEIVE("agents", 9,
550  "received\n");
551 
552  result = g_async_queue_length(event_loop_get()->queue);
553  event = g_async_queue_pop(event_loop_get()->queue);
554  FO_ASSERT_EQUAL((int)result, 1);
555  FO_ASSERT_PTR_EQUAL((void*)event->func, (void*)list_agents_event);
556  FO_ASSERT_STRING_EQUAL(event->source_name, "interface.c");
557 
558  close(soc);
559  interface_destroy(scheduler);
560  scheduler_destroy(scheduler);
561 }
562 
563 /* ************************************************************************** */
564 /* **** suite declaration *************************************************** */
565 /* ************************************************************************** */
566 
567 CU_TestInfo tests_interface[] =
568 {
569  {"Test interface_init", test_interface_init },
570  {"Test interface_destroy", test_interface_destroy },
571  {"Test interface_listen_thread", test_interface_listen_thread },
572  {"Test interface_pool", test_interface_pool },
573  CU_TEST_INFO_NULL
574 };
575 
576 CU_TestInfo tests_interface_thread[] =
577 {
578  {"Test sending \"close\"", test_sending_close },
579  {"Test sending \"load\"", test_sending_load },
580  {"Test sending \"kill\"", test_sending_kill },
581  {"Test sending \"pause\"", test_sending_pause },
582  {"Test sending \"status\"", test_sending_reload },
583  CU_TEST_INFO_NULL
584 };
585 
586 
587 
588 
void test_sending_agents()
Test for agent message on interface.
void interface_thread(interface_connection *conn, scheduler_t *scheduler)
Function that will run the thread associated with a particular interface instance.
Definition: interface.c:137
void list_agents_event(scheduler_t *scheduler, GOutputStream *ostr)
Receive agent on interface.
Definition: agent.c:1129
GCancellable * cancel
Used to stop the listening thread when it is running.
Definition: scheduler.h:180
void interface_destroy(scheduler_t *scheduler)
Closes the server socket and thread pool that service UI connections.
Definition: interface.c:599
void scheduler_destroy(scheduler_t *scheduler)
Free any memory associated with a scheduler_t.
Definition: scheduler.c:373
void test_sending_reload()
Test for reload message on interface.
gboolean i_created
Has the interface been created.
Definition: scheduler.h:175
uint16_t i_port
The port that the scheduler is listening on.
Definition: scheduler.h:177
GThread * server
Thread that is listening to the server socket.
Definition: scheduler.h:178
#define mint_t
Definition: testInterface.c:50
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:60
void test_interface_destroy()
Test for interface_destroy()
void host_insert(host_t *host, scheduler_t *scheduler)
Inserts a new host into the scheduler structure.
Definition: host.c:103
void(* func)(scheduler_t *, void *)
The function that will be executed for this event.
Definition: event.h:36
void test_sending_pause()
Test for pause message on interface.
void scheduler_foss_config(scheduler_t *scheduler)
Loads the configuration data from fossology.conf.
Definition: scheduler.c:864
gboolean i_terminate
Has the interface been terminated.
Definition: scheduler.h:176
scheduler_t * scheduler_init(gchar *sysconfigdir, log_t *log)
Create a new scheduler object.
Definition: scheduler.c:260
void test_interface_init()
Test for interface_init()
char buffer[2048]
The last thing received from the scheduler.
void test_sending_kill()
Test for kill message on interface.
Event handling operations.
void scheduler_config_event(scheduler_t *scheduler, void *unused)
Load both the fossology configuration and all the agent configurations.
Definition: scheduler.c:1002
void interface_init(scheduler_t *scheduler)
Create the interface thread and thread pool that handle UI connections.
Definition: interface.c:565
void * interface_listen_thread(scheduler_t *scheduler)
Function that will listen for new connections to the server sockets.
Definition: interface.c:505
void test_sending_close()
Test for close message on interface.
Definition: event.h:35
void test_interface_pool()
Test for interface_init() thread pool.
int socket_connect(char *host, char *port)
Create a socket connection.
Definition: testInterface.c:62
GThreadPool * workers
Threads to handle incoming network communication.
Definition: scheduler.h:179
void test_interface_listen_thread()
Test for interface_listen_thread()
char * source_name
Name of the source file creating the event.
Definition: event.h:39
event_loop_t * event_loop_get()
Definition: event.c:59
void test_sending_load()
Test for load message on interface.