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
20 * Szabo, Janos Zoltan – initial implementation
21 * Zalanyi, Balazs Andor
23 ******************************************************************************/
25 // Description: Header file for MainController
26 // Author: Janos Zoltan Szabo
27 // mail: tmpjsz@eth.ericsson.se
29 // Copyright (c) 2000-2015 Ericsson Telecom AB
31 #ifndef MCTR_MAINCONTROLLER_H
32 #define MCTR_MAINCONTROLLER_H
33 //----------------------------------------------------------------------------
36 #include <sys/types.h>
37 #include <netinet/in.h>
39 #include "../../core/Types.h"
40 #include "../../common/NetworkHandler.hh"
43 #include "UserInterface.h"
53 //----------------------------------------------------------------------------
57 //----------------------------------------------------------------------------
59 /* Type definitions */
61 /** For representing the global state of MC */
63 MC_INACTIVE
, MC_LISTENING
, MC_LISTENING_CONFIGURED
, MC_HC_CONNECTED
,
64 MC_CONFIGURING
, MC_ACTIVE
, MC_SHUTDOWN
, MC_CREATING_MTC
, MC_READY
,
65 MC_TERMINATING_MTC
, MC_EXECUTING_CONTROL
, MC_EXECUTING_TESTCASE
,
66 MC_TERMINATING_TESTCASE
, MC_PAUSED
69 /** Data structure for unknown incoming connections (before receiving
70 * the first message) */
71 struct unknown_connection
{
75 unknown_connection
*prev
, *next
;
76 bool unix_socket
; // true only if the connection is through unix domain socket
79 /** Data structure for describing the component location
86 /** Data structure for describing the component location
88 struct host_group_struct
{
90 boolean has_all_hosts
, has_all_components
;
91 string_set host_members
, assigned_components
;
94 /** Possible states of a HC */
95 enum hc_state_enum
{ HC_IDLE
, HC_CONFIGURING
, HC_ACTIVE
, HC_OVERLOADED
,
96 HC_CONFIGURING_OVERLOADED
, HC_EXITING
, HC_DOWN
};
98 /** Data structure for each host (and the corresponding HC) */
101 char *hostname
; /**< hostname retrieved from DNS */
102 char *hostname_local
; /**< hostname sent in VERSION message */
105 char *system_release
;
106 char *system_version
;
107 boolean transport_supported
[TRANSPORT_NUM
];
109 hc_state_enum hc_state
;
113 component
*components
;
114 /* to implement load balancing mechanisms */
115 string_set allowed_components
;
116 boolean all_components_allowed
;
117 boolean local_hostname_different
;
118 int n_active_components
;
121 struct component_struct
;
123 /** Container of test components (when a pending operation can be
124 * requested by several components) */
125 struct requestor_struct
{
128 component_struct
*the_component
;
129 component_struct
**components
;
133 /** Possible states of a port connection or mapping */
134 enum conn_state_enum
{ CONN_LISTENING
, CONN_CONNECTING
, CONN_CONNECTED
,
135 CONN_DISCONNECTING
, CONN_MAPPING
, CONN_MAPPED
, CONN_UNMAPPING
};
137 /** Data structure for representing a port connection */
138 struct port_connection
{
139 conn_state_enum conn_state
;
140 transport_type_enum transport_type
;
144 port_connection
*next
, *prev
;
146 requestor_struct requestors
;
150 /** Structure for timers */
151 struct timer_struct
{
155 component_struct
*component_ptr
;
157 timer_struct
*prev
, *next
;
160 /** Possible states of a TC (MTC or PTC) */
161 enum tc_state_enum
{ TC_INITIAL
, TC_IDLE
, TC_CREATE
, TC_START
, TC_STOP
, TC_KILL
,
162 TC_CONNECT
, TC_DISCONNECT
, TC_MAP
, TC_UNMAP
, TC_STOPPING
, TC_EXITING
,
164 MTC_CONTROLPART
, MTC_TESTCASE
, MTC_ALL_COMPONENT_STOP
,
165 MTC_ALL_COMPONENT_KILL
, MTC_TERMINATING_TESTCASE
, MTC_PAUSED
,
166 PTC_FUNCTION
, PTC_STARTING
, PTC_STOPPED
, PTC_KILLING
, PTC_STOPPING_KILLING
,
167 PTC_STALE
, TC_SYSTEM
};
169 /** Data structure for each TC */
170 struct component_struct
{
172 qualified_name comp_type
;
174 char *log_source
; /**< used for console log messages. format: name\@host */
175 host_struct
*comp_location
;
176 tc_state_enum tc_state
;
177 verdicttype local_verdict
;
178 char* verdict_reason
;
181 /** Identifier of the TTCN-3 testcase or function that is currently being
182 * executed on the test component */
183 qualified_name tc_fn_name
;
184 /* fields for implementing the construct 'value returning done' */
186 int return_value_len
;
189 boolean stop_requested
; /**< only for 'all component.running' */
190 boolean process_killed
;
192 /** used in state TC_INITIAL */
194 component_struct
*create_requestor
;
197 /** used in state PTC_STARTING */
199 component_struct
*start_requestor
;
202 requestor_struct cancel_done_sent_to
;
204 /** used in states TC_STOPPING, PTC_STOPPING_KILLING, PTC_KILLING */
206 requestor_struct stop_requestors
;
207 requestor_struct kill_requestors
;
210 requestor_struct done_requestors
;
211 requestor_struct killed_requestors
;
212 requestor_struct cancel_done_sent_for
;
213 timer_struct
*kill_timer
;
214 /* fields for registering port connections */
215 port_connection
*conn_head_list
, *conn_tail_list
;
216 int conn_head_count
, conn_tail_count
;
219 /** Selector for the table of file descriptors */
220 enum fd_type_enum
{ FD_UNUSED
, FD_PIPE
, FD_SERVER
, FD_UNKNOWN
, FD_HC
, FD_TC
};
222 /** Element of the file descriptor table. The table is indexed by the
224 struct fd_table_struct
{
225 fd_type_enum fd_type
;
227 unknown_connection
*unknown_ptr
;
228 host_struct
*host_ptr
;
229 component_struct
*component_ptr
;
234 /** Structure for storing the checksum of a module */
235 struct module_version_info
{
238 unsigned char *module_checksum
;
241 /** Possible reasons for waking up the MC thread from the main thread. */
242 enum wakeup_reason_t
{ REASON_NOTHING
, REASON_SHUTDOWN
, REASON_MTC_KILL_TIMER
};
244 /** Structure for storing the settings needed to initialize the debugger of a
245 * newly connected HC */
246 struct debugger_settings_struct
{
250 char* error_behavior
;
251 char* error_batch_file
;
253 char* fail_batch_file
;
254 char* global_batch_state
;
255 char* global_batch_file
;
256 char* function_calls_cfg
;
257 char* function_calls_file
;
259 struct breakpoint_struct
{
266 struct debug_command_struct
{
271 /** The MainController class. The collection of all functions and data
273 class MainController
{
274 /* private members */
275 static UserInterface
*ui
;
276 static NetworkHandler nh
;
278 static mc_state_enum mc_state
;
279 static char *mc_hostname
;
281 static int server_fd
;
282 static int server_fd_unix
; // for efficient local communication
283 static boolean server_fd_disabled
;
284 static void disable_server_fd();
285 static void enable_server_fd();
287 static pthread_mutex_t mutex
;
289 static void unlock();
292 static const int EPOLL_SIZE_HINT
= 1000;
293 static const int EPOLL_MAX_EVENTS
= 250;
294 static epoll_event
*epoll_events
;
297 static unsigned int nfds
, new_nfds
;
298 static struct pollfd
*ufds
, *new_ufds
;
299 static boolean pollfds_modified
;
300 static void update_pollfds();
302 static void add_poll_fd(int fd
);
303 static void remove_poll_fd(int fd
);
305 static int fd_table_size
;
306 static fd_table_struct
*fd_table
;
307 static void add_fd_to_table(int fd
);
308 static void remove_fd_from_table(int fd
);
310 static void set_close_on_exec(int fd
);
312 static unknown_connection
*unknown_head
, *unknown_tail
;
313 static unknown_connection
*new_unknown_connection(bool unix_socket
);
314 static void delete_unknown_connection(unknown_connection
*conn
);
315 static void close_unknown_connection(unknown_connection
*conn
);
317 static void init_string_set(string_set
*set
);
318 static void free_string_set(string_set
*set
);
319 static void add_string_to_set(string_set
*set
, const char *str
);
320 static void remove_string_from_set(string_set
*set
, const char *str
);
321 static boolean
set_has_string(const string_set
*set
, const char *str
);
322 static const char *get_string_from_set(const string_set
*set
, int index
);
324 static int n_host_groups
;
325 static host_group_struct
*host_groups
;
326 static string_set assigned_components
;
327 static boolean all_components_assigned
;
328 static host_group_struct
*add_host_group(const char *group_name
);
329 static host_group_struct
*lookup_host_group(const char *group_name
);
330 static boolean
is_similar_hostname(const char *host1
, const char *host2
);
331 static boolean
host_has_name(const host_struct
*host
, const char *name
);
332 static boolean
member_of_group(const host_struct
*host
,
333 const host_group_struct
*group
);
334 static void add_allowed_components(host_struct
*host
);
335 static host_struct
*choose_ptc_location(const char *component_type
,
336 const char *component_name
, const char *component_location
);
339 static host_struct
**hosts
;
340 static char *config_str
;
341 static debugger_settings_struct debugger_settings
;
342 static debug_command_struct last_debug_command
;
343 static host_struct
*add_new_host(unknown_connection
*conn
);
344 static void close_hc_connection(host_struct
*hc
);
345 static boolean
is_hc_in_state(hc_state_enum checked_state
);
346 static boolean
all_hc_in_state(hc_state_enum checked_state
);
347 static void configure_host(host_struct
*host
, boolean should_notify
);
348 static void check_all_hc_configured();
349 static void add_component_to_host(host_struct
*host
,
350 component_struct
*comp
);
351 static void remove_component_from_host(component_struct
*comp
);
353 static boolean version_known
;
354 static int n_modules
;
355 static module_version_info
*modules
;
356 static boolean
check_version(unknown_connection
*conn
);
358 static int n_components
, n_active_ptcs
, max_ptcs
;
359 static component_struct
**components
;
360 static component_struct
*mtc
, *system
;
361 static const component_struct
* debugger_active_tc
;
362 static component next_comp_ref
, tc_first_comp_ref
;
363 static boolean any_component_done_requested
, any_component_done_sent
,
364 all_component_done_requested
, any_component_killed_requested
,
365 all_component_killed_requested
;
366 static void add_component(component_struct
*comp
);
367 static component_struct
*lookup_component(component comp_ref
);
368 static void destroy_all_components();
369 static void close_tc_connection(component_struct
*comp
);
370 static boolean stop_after_tc
, stop_requested
;
371 static boolean
ready_to_finish_testcase();
372 static void finish_testcase();
373 static boolean
message_expected(component_struct
*from
,
374 const char *message_name
);
375 static boolean
request_allowed(component_struct
*from
,
376 const char *message_name
);
377 static boolean
valid_endpoint(component component_reference
,
378 boolean new_connection
, component_struct
*requestor
,
379 const char *operation
);
380 static void destroy_connection(port_connection
*conn
, component_struct
*tc
);
381 static void destroy_mapping(port_connection
*conn
);
382 static boolean
stop_all_components();
383 static void check_all_component_stop();
384 static void send_stop_ack_to_requestors(component_struct
*tc
);
385 static boolean
kill_all_components(boolean testcase_ends
);
386 static void check_all_component_kill();
387 static void send_kill_ack_to_requestors(component_struct
*tc
);
388 static void send_component_status_to_requestor(component_struct
*tc
,
389 component_struct
*requestor
, boolean done_status
,
390 boolean killed_status
);
391 static void component_stopped(component_struct
*tc
);
392 static void component_terminated(component_struct
*tc
);
393 static void done_cancelled(component_struct
*from
,
394 component_struct
*started_tc
);
395 static void start_kill_timer(component_struct
*tc
);
397 static boolean
component_is_alive(component_struct
*tc
);
398 static boolean
component_is_running(component_struct
*tc
);
399 static boolean
component_is_done(component_struct
*tc
);
400 static boolean
is_any_component_alive();
401 static boolean
is_all_component_alive();
402 static boolean
is_any_component_running();
403 static boolean
is_all_component_running();
404 static boolean
is_any_component_done();
406 static void init_connections(component_struct
*tc
);
407 static void add_connection(port_connection
*c
);
408 static void remove_connection(port_connection
*c
);
409 static port_connection
*find_connection(component head_comp
,
410 const char *head_port
, component tail_comp
, const char *tail_port
);
411 static void remove_all_connections(component head_or_tail
);
412 static transport_type_enum
choose_port_connection_transport(
413 component head_comp
, component tail_comp
);
414 static void send_connect_ack_to_requestors(port_connection
*conn
);
415 static void send_error_to_connect_requestors(port_connection
*conn
,
416 const char *fmt
, ...)
417 __attribute__ ((__format__ (__printf__
, 2, 3)));
418 static void send_disconnect_to_server(port_connection
*conn
);
419 static void send_disconnect_ack_to_requestors(port_connection
*conn
);
421 static void init_requestors(requestor_struct
*reqs
, component_struct
*tc
);
422 static void add_requestor(requestor_struct
*reqs
, component_struct
*tc
);
423 static void remove_requestor(requestor_struct
*reqs
, component_struct
*tc
);
424 static boolean
has_requestor(const requestor_struct
*reqs
,
425 component_struct
*tc
);
426 static component_struct
*get_requestor(const requestor_struct
*reqs
,
428 static void free_requestors(requestor_struct
*reqs
);
430 static void init_qualified_name(qualified_name
*name
);
431 static void free_qualified_name(qualified_name
*name
);
433 static double kill_timer
;
434 static double time_now();
435 static timer_struct
*timer_head
, *timer_tail
;
436 static void register_timer(timer_struct
*timer
);
437 static void cancel_timer(timer_struct
*timer
);
438 static int get_poll_timeout();
439 static void handle_expired_timers();
440 static void handle_kill_timer(timer_struct
*timer
);
442 // Custom signal handling for termination signals to remove temporary
443 // files /tmp/ttcn3-mctr-*. Related to HP67376.
444 static struct sigaction new_action
, old_action
;
445 static void register_termination_handlers();
446 static void termination_handler(int signum
);
448 static void execute_batch_file(const char* file_name
);
451 static void error(const char *fmt
, ...)
452 __attribute__ ((__format__ (__printf__
, 1, 2)));
454 static void notify(const char *fmt
, ...)
455 __attribute__ ((__format__ (__printf__
, 1, 2)));
456 static void notify(const struct timeval
*timestamp
, const char *source
,
457 int severity
, const char *message
);
458 static void status_change();
460 static void fatal_error(const char *fmt
, ...)
461 __attribute__ ((__format__ (__printf__
, 1, 2), __noreturn__
));
463 static void *thread_main(void *arg
);
464 static void dispatch_socket_event(int fd
);
465 static int pipe_fd
[2];
466 static wakeup_reason_t wakeup_reason
;
467 static void wakeup_thread(wakeup_reason_t reason
);
469 static void handle_pipe();
470 static void handle_incoming_connection(int p_serverfd
);
471 static int recv_to_buffer(int fd
, Text_Buf
& text_buf
,
472 boolean recv_from_socket
);
473 static void handle_unknown_data(unknown_connection
*conn
);
474 static void handle_hc_data(host_struct
*hc
, boolean recv_from_socket
);
475 static void handle_tc_data(component_struct
*tc
, boolean recv_from_socket
);
477 static void unlink_unix_socket(int socket_fd
);
479 static void shutdown_server();
480 static void perform_shutdown();
482 static void clean_up();
484 static const char *get_host_name(const struct in_addr
*ip_address
);
485 static boolean
get_ip_address(struct in_addr
*ip_address
,
486 const char *host_name
);
488 /* Messages to HCs */
489 static void send_configure(host_struct
*hc
, const char *config_file
);
490 static void send_exit_hc(host_struct
*hc
);
491 static void send_create_mtc(host_struct
*hc
);
492 static void send_create_ptc(host_struct
*hc
, component component_reference
,
493 const qualified_name
& component_type
, const char *component_name
,
494 boolean is_alive
, const qualified_name
& current_testcase
);
495 static void send_kill_process(host_struct
*hc
,
496 component component_reference
);
498 /* Messages to TCs */
499 static void send_create_ack(component_struct
*tc
,
500 component component_reference
);
501 static void send_start_ack(component_struct
*tc
);
502 static void send_stop(component_struct
*tc
);
503 static void send_stop_ack(component_struct
*tc
);
504 static void send_kill_ack(component_struct
*tc
);
505 static void send_running(component_struct
*tc
, boolean answer
);
506 static void send_alive(component_struct
*tc
, boolean answer
);
507 static void send_done_ack(component_struct
*tc
, boolean answer
,
508 const char *return_type
, int return_value_len
,
509 const void *return_value
);
510 static void send_killed_ack(component_struct
*tc
, boolean answer
);
511 static void send_connect_listen(component_struct
*tc
,
512 const char *local_port
, component remote_comp
,
513 const char *remote_comp_name
, const char *remote_port
,
514 transport_type_enum transport_type
);
515 static void send_connect(component_struct
*tc
,
516 const char *local_port
, component remote_comp
,
517 const char *remote_comp_name
, const char *remote_port
,
518 transport_type_enum transport_type
, int remote_address_len
,
519 const void *remote_address
);
520 static void send_connect_ack(component_struct
*tc
);
521 static void send_disconnect(component_struct
*tc
,
522 const char *local_port
, component remote_comp
, const char *remote_port
);
523 static void send_disconnect_ack(component_struct
*tc
);
524 static void send_map(component_struct
*tc
,
525 const char *local_port
, const char *system_port
);
526 static void send_map_ack(component_struct
*tc
);
527 static void send_unmap(component_struct
*tc
,
528 const char *local_port
, const char *system_port
);
529 static void send_unmap_ack(component_struct
*tc
);
530 static void send_debug_command(int fd
, int commandID
, const char* arguments
);
531 static void send_debug_setup(host_struct
*hc
);
533 /* Messages to MTC */
534 static void send_cancel_done_mtc(component component_reference
,
536 static void send_component_status_mtc(component component_reference
,
537 boolean is_done
, boolean is_killed
, boolean is_any_done
,
538 boolean is_all_done
, boolean is_any_killed
, boolean is_all_killed
,
539 const char *return_type
, int return_value_len
,
540 const void *return_value
);
541 static void send_execute_control(const char *module_name
);
542 static void send_execute_testcase(const char *module_name
,
543 const char *testcase_name
);
544 static void send_ptc_verdict(boolean continue_execution
);
545 static void send_continue();
546 static void send_exit_mtc();
548 /** Messages to PTCs */
549 static void send_cancel_done_ptc(component_struct
*tc
,
550 component component_reference
);
551 static void send_component_status_ptc(component_struct
*tc
,
552 component component_reference
,
553 boolean is_done
, boolean is_killed
, const char *return_type
,
554 int return_value_len
, const void *return_value
);
555 static void send_start(component_struct
*tc
,
556 const qualified_name
& function_name
, int arg_len
, const void *arg_ptr
);
557 static void send_kill(component_struct
*tc
);
559 static void send_error(int fd
, const char *fmt
, ...)
560 __attribute__ ((__format__ (__printf__
, 2, 3)));
561 static void send_error_str(int fd
, const char *reason
);
562 static void send_message(int fd
, Text_Buf
& text_buf
);
564 /* Incoming messages on unknown connections (generic and first messages) */
565 static void process_error(unknown_connection
*conn
);
566 static void process_log(unknown_connection
*conn
);
567 static void process_version(unknown_connection
*conn
);
568 static void process_mtc_created(unknown_connection
*conn
);
569 static void process_ptc_created(unknown_connection
*conn
);
571 /* Incoming messages from HCs */
572 static void process_error(host_struct
*hc
);
573 static void process_log(host_struct
*hc
);
574 static void process_configure_ack(host_struct
*hc
);
575 static void process_configure_nak(host_struct
*hc
);
576 static void process_create_nak(host_struct
*hc
);
577 static void process_hc_ready(host_struct
*hc
);
579 /* Incoming messages from TCs */
580 static void process_error(component_struct
*tc
);
581 static void process_log(component_struct
*tc
);
582 static void process_create_req(component_struct
*tc
);
583 static void process_start_req(component_struct
*tc
, int message_end
);
584 static void process_stop_req(component_struct
*tc
);
585 static void process_kill_req(component_struct
*tc
);
586 static void process_is_running(component_struct
*tc
);
587 static void process_is_alive(component_struct
*tc
);
588 static void process_done_req(component_struct
*tc
);
589 static void process_killed_req(component_struct
*tc
);
590 static void process_cancel_done_ack(component_struct
*tc
);
591 static void process_connect_req(component_struct
*tc
);
592 static void process_connect_listen_ack(component_struct
*tc
, int message_end
);
593 static void process_connected(component_struct
*tc
);
594 static void process_connect_error(component_struct
*tc
);
595 static void process_disconnect_req(component_struct
*tc
);
596 static void process_disconnected(component_struct
*tc
);
597 static void process_map_req(component_struct
*tc
);
598 static void process_mapped(component_struct
*tc
);
599 static void process_unmap_req(component_struct
*tc
);
600 static void process_unmapped(component_struct
*tc
);
601 static void process_debug_return_value(Text_Buf
& text_buf
, char* log_source
,
602 int msg_end
, bool from_mtc
);
603 static void process_debug_broadcast_req(component_struct
*tc
, int commandID
);
604 static void process_debug_batch(component_struct
*tc
);
606 /* Incoming messages from MTC */
607 static void process_testcase_started();
608 static void process_testcase_finished();
609 static void process_mtc_ready();
611 /* Incoming messages from PTCs */
612 static void process_stopped(component_struct
*tc
, int message_end
);
613 static void process_stopped_killed(component_struct
*tc
, int message_end
);
614 static void process_killed(component_struct
*tc
);
617 static void initialize(UserInterface
& par_ui
, int par_max_ptcs
);
618 static void terminate();
620 static void add_host(const char *group_name
, const char *host_name
);
621 static void assign_component(const char *host_or_group
,
622 const char *component_id
);
623 static void destroy_host_groups();
625 static void set_kill_timer(double timer_val
);
627 static unsigned short start_session(const char *local_address
,
628 unsigned short tcp_port
, bool unix_sockets_enabled
);
629 static void shutdown_session();
631 static void configure(const char *config_file
);
633 static void create_mtc(int host_index
);
634 static void exit_mtc();
636 static void execute_control(const char *module_name
);
637 static void execute_testcase(const char *module_name
,
638 const char *testcase_name
);
639 static void stop_after_testcase(boolean new_state
);
640 static void continue_testcase();
641 static void stop_execution();
643 static void debug_command(int commandID
, char* arguments
);
645 static mc_state_enum
get_state();
646 static boolean
get_stop_after_testcase();
648 static int get_nof_hosts();
649 static host_struct
*get_host_data(int host_index
);
650 static component_struct
*get_component_data(int component_reference
);
651 static void release_data();
653 static const char *get_mc_state_name(mc_state_enum state
);
654 static const char *get_hc_state_name(hc_state_enum state
);
655 static const char *get_tc_state_name(tc_state_enum state
);
656 static const char *get_transport_name(transport_type_enum transport
);
659 //----------------------------------------------------------------------------
661 } /* namespace mctr */
663 //----------------------------------------------------------------------------
664 #endif // MCTR_MAINCONTROLLER_H
668 // indent-tabs-mode: nil