1bb841e97c0691952e87ff878d65bf6ffdb502b9
[deliverable/titan.core.git] / mctr2 / mctr / MainController.h
1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Baji, Laszlo
10 * Balasko, Jeno
11 * Bene, Tamas
12 * Czimbalmos, Eduard
13 * Feher, Csaba
14 * Forstner, Matyas
15 * Gecse, Roland
16 * Kovacs, Ferenc
17 * Lovassy, Arpad
18 * Raduly, Csaba
19 * Szabo, Janos Zoltan – initial implementation
20 * Zalanyi, Balazs Andor
21 *
22 ******************************************************************************/
23 //
24 // Description: Header file for MainController
25 // Author: Janos Zoltan Szabo
26 // mail: tmpjsz@eth.ericsson.se
27 //
28 // Copyright (c) 2000-2015 Ericsson Telecom AB
29 //
30 #ifndef MCTR_MAINCONTROLLER_H
31 #define MCTR_MAINCONTROLLER_H
32 //----------------------------------------------------------------------------
33
34 #include <pthread.h>
35 #include <sys/types.h>
36 #include <netinet/in.h>
37
38 #include "../../core/Types.h"
39 #include "../../common/NetworkHandler.hh"
40 class Text_Buf;
41
42 #include "UserInterface.h"
43
44 #ifdef USE_EPOLL
45 struct epoll_event;
46 #else
47 struct pollfd;
48 #endif
49
50 struct sigaction;
51
52 //----------------------------------------------------------------------------
53
54 namespace mctr {
55
56 //----------------------------------------------------------------------------
57
58 /* Type definitions */
59
60 /** For representing the global state of MC */
61 enum mc_state_enum {
62 MC_INACTIVE, MC_LISTENING, MC_LISTENING_CONFIGURED, MC_HC_CONNECTED,
63 MC_CONFIGURING, MC_ACTIVE, MC_SHUTDOWN, MC_CREATING_MTC, MC_READY,
64 MC_TERMINATING_MTC, MC_EXECUTING_CONTROL, MC_EXECUTING_TESTCASE,
65 MC_TERMINATING_TESTCASE, MC_PAUSED
66 };
67
68 /** Data structure for unknown incoming connections (before receiving
69 * the first message) */
70 struct unknown_connection {
71 int fd;
72 IPAddress *ip_addr;
73 Text_Buf *text_buf;
74 unknown_connection *prev, *next;
75 bool unix_socket; // true only if the connection is through unix domain socket
76 };
77
78 /** Data structure for describing the component location
79 * constraints */
80 struct string_set {
81 int n_elements;
82 char **elements;
83 };
84
85 /** Data structure for describing the component location
86 * constraints */
87 struct host_group_struct {
88 char *group_name;
89 boolean has_all_hosts, has_all_components;
90 string_set host_members, assigned_components;
91 };
92
93 /** Possible states of a HC */
94 enum hc_state_enum { HC_IDLE, HC_CONFIGURING, HC_ACTIVE, HC_OVERLOADED,
95 HC_CONFIGURING_OVERLOADED, HC_EXITING, HC_DOWN };
96
97 /** Data structure for each host (and the corresponding HC) */
98 struct host_struct {
99 IPAddress *ip_addr;
100 char *hostname; /**< hostname retrieved from DNS */
101 char *hostname_local; /**< hostname sent in VERSION message */
102 char *machine_type;
103 char *system_name;
104 char *system_release;
105 char *system_version;
106 boolean transport_supported[TRANSPORT_NUM];
107 char *log_source;
108 hc_state_enum hc_state;
109 int hc_fd;
110 Text_Buf *text_buf;
111 int n_components;
112 component *components;
113 /* to implement load balancing mechanisms */
114 string_set allowed_components;
115 boolean all_components_allowed;
116 boolean local_hostname_different;
117 int n_active_components;
118 };
119
120 struct component_struct;
121
122 /** Container of test components (when a pending operation can be
123 * requested by several components) */
124 struct requestor_struct {
125 int n_components;
126 union {
127 component_struct *the_component;
128 component_struct **components;
129 };
130 };
131
132 /** Possible states of a port connection or mapping */
133 enum conn_state_enum { CONN_LISTENING, CONN_CONNECTING, CONN_CONNECTED,
134 CONN_DISCONNECTING, CONN_MAPPING, CONN_MAPPED, CONN_UNMAPPING };
135
136 /** Data structure for representing a port connection */
137 struct port_connection {
138 conn_state_enum conn_state;
139 transport_type_enum transport_type;
140 struct {
141 component comp_ref;
142 char *port_name;
143 port_connection *next, *prev;
144 } head, tail;
145 requestor_struct requestors;
146 };
147
148
149 /** Structure for timers */
150 struct timer_struct {
151 double expiration;
152 union {
153 void *dummy_ptr;
154 component_struct *component_ptr;
155 } timer_argument;
156 timer_struct *prev, *next;
157 };
158
159 /** Possible states of a TC (MTC or PTC) */
160 enum tc_state_enum { TC_INITIAL, TC_IDLE, TC_CREATE, TC_START, TC_STOP, TC_KILL,
161 TC_CONNECT, TC_DISCONNECT, TC_MAP, TC_UNMAP, TC_STOPPING, TC_EXITING,
162 TC_EXITED,
163 MTC_CONTROLPART, MTC_TESTCASE, MTC_ALL_COMPONENT_STOP,
164 MTC_ALL_COMPONENT_KILL, MTC_TERMINATING_TESTCASE, MTC_PAUSED,
165 PTC_FUNCTION, PTC_STARTING, PTC_STOPPED, PTC_KILLING, PTC_STOPPING_KILLING,
166 PTC_STALE, TC_SYSTEM };
167
168 /** Data structure for each TC */
169 struct component_struct {
170 component comp_ref;
171 qualified_name comp_type;
172 char *comp_name;
173 char *log_source; /**< used for console log messages. format: name\@host */
174 host_struct *comp_location;
175 tc_state_enum tc_state;
176 verdicttype local_verdict;
177 char* verdict_reason;
178 int tc_fd;
179 Text_Buf *text_buf;
180 /** Identifier of the TTCN-3 testcase or function that is currently being
181 * executed on the test component */
182 qualified_name tc_fn_name;
183 /* fields for implementing the construct 'value returning done' */
184 char *return_type;
185 int return_value_len;
186 void *return_value;
187 boolean is_alive;
188 boolean stop_requested; /**< only for 'all component.running' */
189 boolean process_killed;
190 union {
191 /** used in state TC_INITIAL */
192 struct {
193 component_struct *create_requestor;
194 char *location_str;
195 } initial;
196 /** used in state PTC_STARTING */
197 struct {
198 component_struct *start_requestor;
199 int arguments_len;
200 void *arguments_ptr;
201 requestor_struct cancel_done_sent_to;
202 } starting;
203 /** used in states TC_STOPPING, PTC_STOPPING_KILLING, PTC_KILLING */
204 struct {
205 requestor_struct stop_requestors;
206 requestor_struct kill_requestors;
207 } stopping_killing;
208 };
209 requestor_struct done_requestors;
210 requestor_struct killed_requestors;
211 requestor_struct cancel_done_sent_for;
212 timer_struct *kill_timer;
213 /* fields for registering port connections */
214 port_connection *conn_head_list, *conn_tail_list;
215 int conn_head_count, conn_tail_count;
216 };
217
218 /** Selector for the table of file descriptors */
219 enum fd_type_enum { FD_UNUSED, FD_PIPE, FD_SERVER, FD_UNKNOWN, FD_HC, FD_TC };
220
221 /** Element of the file descriptor table. The table is indexed by the
222 * fd itself. */
223 struct fd_table_struct {
224 fd_type_enum fd_type;
225 union {
226 unknown_connection *unknown_ptr;
227 host_struct *host_ptr;
228 component_struct *component_ptr;
229 void *dummy_ptr;
230 };
231 };
232
233 /** Structure for storing the checksum of a module */
234 struct module_version_info {
235 char *module_name;
236 int checksum_length;
237 unsigned char *module_checksum;
238 };
239
240 /** Possible reasons for waking up the MC thread from the main thread. */
241 enum wakeup_reason_t { REASON_NOTHING, REASON_SHUTDOWN, REASON_MTC_KILL_TIMER };
242
243 /** The MainController class. The collection of all functions and data
244 * structures */
245 class MainController {
246 /* private members */
247 static UserInterface *ui;
248 static NetworkHandler nh;
249
250 static mc_state_enum mc_state;
251 static char *mc_hostname;
252
253 static int server_fd;
254 static int server_fd_unix; // for efficient local communication
255 static boolean server_fd_disabled;
256 static void disable_server_fd();
257 static void enable_server_fd();
258
259 static pthread_mutex_t mutex;
260 static void lock();
261 static void unlock();
262
263 #ifdef USE_EPOLL
264 static const int EPOLL_SIZE_HINT = 1000;
265 static const int EPOLL_MAX_EVENTS = 250;
266 static epoll_event *epoll_events;
267 static int epfd;
268 #else
269 static unsigned int nfds, new_nfds;
270 static struct pollfd *ufds, *new_ufds;
271 static boolean pollfds_modified;
272 static void update_pollfds();
273 #endif
274 static void add_poll_fd(int fd);
275 static void remove_poll_fd(int fd);
276
277 static int fd_table_size;
278 static fd_table_struct *fd_table;
279 static void add_fd_to_table(int fd);
280 static void remove_fd_from_table(int fd);
281
282 static void set_close_on_exec(int fd);
283
284 static unknown_connection *unknown_head, *unknown_tail;
285 static unknown_connection *new_unknown_connection(bool unix_socket);
286 static void delete_unknown_connection(unknown_connection *conn);
287 static void close_unknown_connection(unknown_connection *conn);
288
289 static void init_string_set(string_set *set);
290 static void free_string_set(string_set *set);
291 static void add_string_to_set(string_set *set, const char *str);
292 static void remove_string_from_set(string_set *set, const char *str);
293 static boolean set_has_string(const string_set *set, const char *str);
294 static const char *get_string_from_set(const string_set *set, int index);
295
296 static int n_host_groups;
297 static host_group_struct *host_groups;
298 static string_set assigned_components;
299 static boolean all_components_assigned;
300 static host_group_struct *add_host_group(const char *group_name);
301 static host_group_struct *lookup_host_group(const char *group_name);
302 static boolean is_similar_hostname(const char *host1, const char *host2);
303 static boolean host_has_name(const host_struct *host, const char *name);
304 static boolean member_of_group(const host_struct *host,
305 const host_group_struct *group);
306 static void add_allowed_components(host_struct *host);
307 static host_struct *choose_ptc_location(const char *component_type,
308 const char *component_name, const char *component_location);
309
310 static int n_hosts;
311 static host_struct **hosts;
312 static char *config_str;
313 static host_struct *add_new_host(unknown_connection *conn);
314 static void close_hc_connection(host_struct *hc);
315 static boolean is_hc_in_state(hc_state_enum checked_state);
316 static boolean all_hc_in_state(hc_state_enum checked_state);
317 static void configure_host(host_struct *host, boolean should_notify);
318 static void check_all_hc_configured();
319 static void add_component_to_host(host_struct *host,
320 component_struct *comp);
321 static void remove_component_from_host(component_struct *comp);
322
323 static boolean version_known;
324 static int n_modules;
325 static module_version_info *modules;
326 static boolean check_version(unknown_connection *conn);
327
328 static int n_components, n_active_ptcs, max_ptcs;
329 static component_struct **components;
330 static component_struct *mtc, *system;
331 static component next_comp_ref, tc_first_comp_ref;
332 static boolean any_component_done_requested, any_component_done_sent,
333 all_component_done_requested, any_component_killed_requested,
334 all_component_killed_requested;
335 static void add_component(component_struct *comp);
336 static component_struct *lookup_component(component comp_ref);
337 static void destroy_all_components();
338 static void close_tc_connection(component_struct *comp);
339 static boolean stop_after_tc, stop_requested;
340 static boolean ready_to_finish_testcase();
341 static void finish_testcase();
342 static boolean message_expected(component_struct *from,
343 const char *message_name);
344 static boolean request_allowed(component_struct *from,
345 const char *message_name);
346 static boolean valid_endpoint(component component_reference,
347 boolean new_connection, component_struct *requestor,
348 const char *operation);
349 static void destroy_connection(port_connection *conn, component_struct *tc);
350 static void destroy_mapping(port_connection *conn);
351 static boolean stop_all_components();
352 static void check_all_component_stop();
353 static void send_stop_ack_to_requestors(component_struct *tc);
354 static boolean kill_all_components(boolean testcase_ends);
355 static void check_all_component_kill();
356 static void send_kill_ack_to_requestors(component_struct *tc);
357 static void send_component_status_to_requestor(component_struct *tc,
358 component_struct *requestor, boolean done_status,
359 boolean killed_status);
360 static void component_stopped(component_struct *tc);
361 static void component_terminated(component_struct *tc);
362 static void done_cancelled(component_struct *from,
363 component_struct *started_tc);
364 static void start_kill_timer(component_struct *tc);
365
366 static boolean component_is_alive(component_struct *tc);
367 static boolean component_is_running(component_struct *tc);
368 static boolean component_is_done(component_struct *tc);
369 static boolean is_any_component_alive();
370 static boolean is_all_component_alive();
371 static boolean is_any_component_running();
372 static boolean is_all_component_running();
373 static boolean is_any_component_done();
374
375 static void init_connections(component_struct *tc);
376 static void add_connection(port_connection *c);
377 static void remove_connection(port_connection *c);
378 static port_connection *find_connection(component head_comp,
379 const char *head_port, component tail_comp, const char *tail_port);
380 static void remove_all_connections(component head_or_tail);
381 static transport_type_enum choose_port_connection_transport(
382 component head_comp, component tail_comp);
383 static void send_connect_ack_to_requestors(port_connection *conn);
384 static void send_error_to_connect_requestors(port_connection *conn,
385 const char *fmt, ...)
386 __attribute__ ((__format__ (__printf__, 2, 3)));
387 static void send_disconnect_to_server(port_connection *conn);
388 static void send_disconnect_ack_to_requestors(port_connection *conn);
389
390 static void init_requestors(requestor_struct *reqs, component_struct *tc);
391 static void add_requestor(requestor_struct *reqs, component_struct *tc);
392 static void remove_requestor(requestor_struct *reqs, component_struct *tc);
393 static boolean has_requestor(const requestor_struct *reqs,
394 component_struct *tc);
395 static component_struct *get_requestor(const requestor_struct *reqs,
396 int index);
397 static void free_requestors(requestor_struct *reqs);
398
399 static void init_qualified_name(qualified_name *name);
400 static void free_qualified_name(qualified_name *name);
401
402 static double kill_timer;
403 static double time_now();
404 static timer_struct *timer_head, *timer_tail;
405 static void register_timer(timer_struct *timer);
406 static void cancel_timer(timer_struct *timer);
407 static int get_poll_timeout();
408 static void handle_expired_timers();
409 static void handle_kill_timer(timer_struct *timer);
410
411 // Custom signal handling for termination signals to remove temporary
412 // files /tmp/ttcn3-mctr-*. Related to HP67376.
413 static struct sigaction new_action, old_action;
414 static void register_termination_handlers();
415 static void termination_handler(int signum);
416
417 public:
418 static void error(const char *fmt, ...)
419 __attribute__ ((__format__ (__printf__, 1, 2)));
420 private:
421 static void notify(const char *fmt, ...)
422 __attribute__ ((__format__ (__printf__, 1, 2)));
423 static void notify(const struct timeval *timestamp, const char *source,
424 int severity, const char *message);
425 static void status_change();
426
427 static void fatal_error(const char *fmt, ...)
428 __attribute__ ((__format__ (__printf__, 1, 2), __noreturn__));
429
430 static void *thread_main(void *arg);
431 static void dispatch_socket_event(int fd);
432 static int pipe_fd[2];
433 static wakeup_reason_t wakeup_reason;
434 static void wakeup_thread(wakeup_reason_t reason);
435
436 static void handle_pipe();
437 static void handle_incoming_connection(int p_serverfd);
438 static int recv_to_buffer(int fd, Text_Buf& text_buf,
439 boolean recv_from_socket);
440 static void handle_unknown_data(unknown_connection *conn);
441 static void handle_hc_data(host_struct *hc, boolean recv_from_socket);
442 static void handle_tc_data(component_struct *tc, boolean recv_from_socket);
443
444 static void unlink_unix_socket(int socket_fd);
445
446 static void shutdown_server();
447 static void perform_shutdown();
448
449 static void clean_up();
450
451 static const char *get_host_name(const struct in_addr *ip_address);
452 static boolean get_ip_address(struct in_addr *ip_address,
453 const char *host_name);
454
455 /* Messages to HCs */
456 static void send_configure(host_struct *hc, const char *config_file);
457 static void send_exit_hc(host_struct *hc);
458 static void send_create_mtc(host_struct *hc);
459 static void send_create_ptc(host_struct *hc, component component_reference,
460 const qualified_name& component_type, const char *component_name,
461 boolean is_alive, const qualified_name& current_testcase);
462 static void send_kill_process(host_struct *hc,
463 component component_reference);
464
465 /* Messages to TCs */
466 static void send_create_ack(component_struct *tc,
467 component component_reference);
468 static void send_start_ack(component_struct *tc);
469 static void send_stop(component_struct *tc);
470 static void send_stop_ack(component_struct *tc);
471 static void send_kill_ack(component_struct *tc);
472 static void send_running(component_struct *tc, boolean answer);
473 static void send_alive(component_struct *tc, boolean answer);
474 static void send_done_ack(component_struct *tc, boolean answer,
475 const char *return_type, int return_value_len,
476 const void *return_value);
477 static void send_killed_ack(component_struct *tc, boolean answer);
478 static void send_connect_listen(component_struct *tc,
479 const char *local_port, component remote_comp,
480 const char *remote_comp_name, const char *remote_port,
481 transport_type_enum transport_type);
482 static void send_connect(component_struct *tc,
483 const char *local_port, component remote_comp,
484 const char *remote_comp_name, const char *remote_port,
485 transport_type_enum transport_type, int remote_address_len,
486 const void *remote_address);
487 static void send_connect_ack(component_struct *tc);
488 static void send_disconnect(component_struct *tc,
489 const char *local_port, component remote_comp, const char *remote_port);
490 static void send_disconnect_ack(component_struct *tc);
491 static void send_map(component_struct *tc,
492 const char *local_port, const char *system_port);
493 static void send_map_ack(component_struct *tc);
494 static void send_unmap(component_struct *tc,
495 const char *local_port, const char *system_port);
496 static void send_unmap_ack(component_struct *tc);
497
498 /* Messages to MTC */
499 static void send_cancel_done_mtc(component component_reference,
500 boolean cancel_any);
501 static void send_component_status_mtc(component component_reference,
502 boolean is_done, boolean is_killed, boolean is_any_done,
503 boolean is_all_done, boolean is_any_killed, boolean is_all_killed,
504 const char *return_type, int return_value_len,
505 const void *return_value);
506 static void send_execute_control(const char *module_name);
507 static void send_execute_testcase(const char *module_name,
508 const char *testcase_name);
509 static void send_ptc_verdict(boolean continue_execution);
510 static void send_continue();
511 static void send_exit_mtc();
512
513 /** Messages to PTCs */
514 static void send_cancel_done_ptc(component_struct *tc,
515 component component_reference);
516 static void send_component_status_ptc(component_struct *tc,
517 component component_reference,
518 boolean is_done, boolean is_killed, const char *return_type,
519 int return_value_len, const void *return_value);
520 static void send_start(component_struct *tc,
521 const qualified_name& function_name, int arg_len, const void *arg_ptr);
522 static void send_kill(component_struct *tc);
523
524 static void send_error(int fd, const char *fmt, ...)
525 __attribute__ ((__format__ (__printf__, 2, 3)));
526 static void send_error_str(int fd, const char *reason);
527 static void send_message(int fd, Text_Buf& text_buf);
528
529 /* Incoming messages on unknown connections (generic and first messages) */
530 static void process_error(unknown_connection *conn);
531 static void process_log(unknown_connection *conn);
532 static void process_version(unknown_connection *conn);
533 static void process_mtc_created(unknown_connection *conn);
534 static void process_ptc_created(unknown_connection *conn);
535
536 /* Incoming messages from HCs */
537 static void process_error(host_struct *hc);
538 static void process_log(host_struct *hc);
539 static void process_configure_ack(host_struct *hc);
540 static void process_configure_nak(host_struct *hc);
541 static void process_create_nak(host_struct *hc);
542 static void process_hc_ready(host_struct *hc);
543
544 /* Incoming messages from TCs */
545 static void process_error(component_struct *tc);
546 static void process_log(component_struct *tc);
547 static void process_create_req(component_struct *tc);
548 static void process_start_req(component_struct *tc, int message_end);
549 static void process_stop_req(component_struct *tc);
550 static void process_kill_req(component_struct *tc);
551 static void process_is_running(component_struct *tc);
552 static void process_is_alive(component_struct *tc);
553 static void process_done_req(component_struct *tc);
554 static void process_killed_req(component_struct *tc);
555 static void process_cancel_done_ack(component_struct *tc);
556 static void process_connect_req(component_struct *tc);
557 static void process_connect_listen_ack(component_struct *tc, int message_end);
558 static void process_connected(component_struct *tc);
559 static void process_connect_error(component_struct *tc);
560 static void process_disconnect_req(component_struct *tc);
561 static void process_disconnected(component_struct *tc);
562 static void process_map_req(component_struct *tc);
563 static void process_mapped(component_struct *tc);
564 static void process_unmap_req(component_struct *tc);
565 static void process_unmapped(component_struct *tc);
566
567 /* Incoming messages from MTC */
568 static void process_testcase_started();
569 static void process_testcase_finished();
570 static void process_mtc_ready();
571
572 /* Incoming messages from PTCs */
573 static void process_stopped(component_struct *tc, int message_end);
574 static void process_stopped_killed(component_struct *tc, int message_end);
575 static void process_killed(component_struct *tc);
576
577 public:
578 static void initialize(UserInterface& par_ui, int par_max_ptcs);
579 static void terminate();
580
581 static void add_host(const char *group_name, const char *host_name);
582 static void assign_component(const char *host_or_group,
583 const char *component_id);
584 static void destroy_host_groups();
585
586 static void set_kill_timer(double timer_val);
587
588 static unsigned short start_session(const char *local_address,
589 unsigned short tcp_port, bool unix_sockets_enabled);
590 static void shutdown_session();
591
592 static void configure(const char *config_file);
593
594 static void create_mtc(int host_index);
595 static void exit_mtc();
596
597 static void execute_control(const char *module_name);
598 static void execute_testcase(const char *module_name,
599 const char *testcase_name);
600 static void stop_after_testcase(boolean new_state);
601 static void continue_testcase();
602 static void stop_execution();
603
604 static mc_state_enum get_state();
605 static boolean get_stop_after_testcase();
606
607 static int get_nof_hosts();
608 static host_struct *get_host_data(int host_index);
609 static component_struct *get_component_data(int component_reference);
610 static void release_data();
611
612 static const char *get_mc_state_name(mc_state_enum state);
613 static const char *get_hc_state_name(hc_state_enum state);
614 static const char *get_tc_state_name(tc_state_enum state);
615 static const char *get_transport_name(transport_type_enum transport);
616 };
617
618 //----------------------------------------------------------------------------
619
620 } /* namespace mctr */
621
622 //----------------------------------------------------------------------------
623 #endif // MCTR_MAINCONTROLLER_H
624
625 // Local Variables:
626 // mode: C++
627 // indent-tabs-mode: nil
628 // c-basic-offset: 2
629 // End:
This page took 0.042968 seconds and 4 git commands to generate.