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
18 * Szabo, Janos Zoltan – initial implementation
20 * Zalanyi, Balazs Andor
23 ******************************************************************************/
30 #include "../common/dbgnew.hh"
31 #include "../common/version_internal.h"
33 #include "Snapshot.hh"
35 #include "Module_list.hh"
37 #include "Component.hh"
39 #include "TitanLoggerApi.hh"
46 #include "../common/license.h"
51 const char * stored_argv
= "Unidentified program";
53 static const char segfault
[] = ": Segmentation fault occurred\n";
54 static const char abortcall
[] = ": Abort was called\n";
56 void signal_handler(int signum
)
59 retval
= write(STDERR_FILENO
, stored_argv
, strlen(stored_argv
));
61 retval
= write(STDERR_FILENO
, segfault
, sizeof(segfault
)-1); // sizeof includes \0
63 retval
= write(STDERR_FILENO
, abortcall
, sizeof(abortcall
)-1); // sizeof includes \0
68 nptrs
= backtrace(buffer
, 100);
69 backtrace_symbols_fd(buffer
, nptrs
, STDERR_FILENO
);
74 TTCN_Logger::close_file();
76 signal(SIGABRT
, SIG_DFL
);
80 static void usage(const char* program_name
)
83 "usage: %s configuration_file\n"
88 " -l: list startable test cases and control parts\n"
89 " -v: show version and module information\n",
90 program_name
, program_name
, program_name
);
93 int main(int argc
, char *argv
[])
95 stored_argv
= argv
[0];
97 act
.sa_handler
= signal_handler
;
98 sigemptyset(&act
.sa_mask
);
100 sigaction(SIGSEGV
, &act
, 0);
101 sigaction(SIGABRT
, &act
, 0);
104 debug_new_counter
.set_program_name(argv
[0]);
107 int c
, i
, ret_val
= EXIT_SUCCESS
;
108 boolean lflag
= FALSE
, vflag
= FALSE
, errflag
= FALSE
;
109 const char *config_file
= NULL
;
110 TTCN_Module
*only_runnable
= Module_List::single_control_part();
112 while ((c
= getopt(argc
, argv
, "lv")) != -1) {
115 if (lflag
|| vflag
) errflag
= TRUE
; // duplicate or conflicting
119 if (lflag
|| vflag
) errflag
= TRUE
; // duplicate or conflicting
127 if (lflag
|| vflag
) {
128 if (optind
!= argc
) errflag
= TRUE
; // -l or -v and non-option arg
130 if (optind
> argc
- 1) { // no config file argument
131 errflag
= (only_runnable
== 0);
133 else config_file
= argv
[optind
];
137 if (argc
== 1) fputs("TTCN-3 Test Executor (single mode), version "
138 PRODUCT_NUMBER
"\n", stderr
);
144 // create buffer for error messages
145 TTCN_Logger::initialize_logger();
146 Module_List::pre_init_modules();
147 Module_List::list_testcases();
149 ret_val
= EXIT_FAILURE
;
151 TTCN_Logger::terminate_logger();
155 fputs("TTCN-3 Test Executor (single mode)\n"
156 "Product number: " PRODUCT_NUMBER
"\n"
157 "Build date (Base Library): " __DATE__
" " __TIME__
"\n"
158 "Base Library was compiled with: " C_COMPILER_VERSION
"\n\n"
159 COPYRIGHT_STRING
"\n\n", stderr
);
161 print_license_info();
164 fputs("Module information:\n", stderr
);
165 Module_List::print_version();
170 fputs("TTCN-3 Test Executor (single mode), version " PRODUCT_NUMBER
"\n",
177 if (!verify_license(&lstr
)) {
182 if (!check_feature(&lstr
, FEATURE_SINGLE
)) {
183 fputs("The license key does not allow test execution in single mode.\n",
193 TTCN_Runtime::set_state(TTCN_Runtime::SINGLE_CONTROLPART
);
194 TTCN_Runtime::install_signal_handlers();
195 TTCN_Snapshot::initialize();
196 TTCN_Logger::initialize_logger();
197 TTCN_Logger::set_executable_name(argv
[0]);
198 TTCN_Logger::set_start_time();
201 TTCN_Logger::log_executor_runtime(
202 TitanLoggerApi::ExecutorRuntime_reason::executor__start__single__mode
);
203 Module_List::pre_init_modules();
205 if (config_file
!= 0) {
206 fprintf(stderr
, "Using configuration file: `%s'\n", config_file
);
207 TTCN_Logger::log_configdata(
208 TitanLoggerApi::ExecutorConfigdata_reason::using__config__file
, config_file
);
211 TTCN_Snapshot::check_fd_setsize();
213 boolean config_file_failure
=
214 config_file
&& !process_config_file(config_file
);
215 TTCN_Runtime::load_logger_plugins();
216 // Quick return if no config file.
217 TTCN_Runtime::set_logger_parameters();
218 TTCN_Logger::open_file();
219 TTCN_Logger::write_logger_settings();
220 if (config_file_failure
) goto fail
;
221 // Config file parsed or no config file: we may be able to run.
223 if (++optind
!= argc
) {
224 // There are further commandline arguments after config file.
225 // Override testcase list.
226 // First, throw away the old list parsed from the config file.
227 for (i
= 0; i
< execute_list_len
; i
++) {
228 Free(execute_list
[i
].module_name
);
229 Free(execute_list
[i
].testcase_name
);
232 // The new execute list length is known in advance.
233 execute_list_len
= argc
- optind
;
234 execute_list
= (execute_list_item
*)Realloc(
235 execute_list
, execute_list_len
* sizeof(*execute_list
));
237 expstring_t testcase_names
= memptystr(); // collects names for printout
239 for (i
= optind
; i
< argc
; ++i
) {
240 testcase_names
= mputstr(testcase_names
, argv
[i
]);
241 testcase_names
= mputc(testcase_names
, '\t');
243 char *dot
= strchr(argv
[i
], '.');
245 *dot
++ = '\0'; // cut the string into two
246 if (!strcmp(dot
, "control"))
249 execute_list
[i
-optind
].module_name
= mcopystr(argv
[i
]);
250 execute_list
[i
-optind
].testcase_name
= dot
? mcopystr(dot
) : dot
;
251 // do not copy NULL pointer, it results in non-0 empty string
253 fprintf(stderr
, "Overriding testcase list: %s\n", testcase_names
);
254 TTCN_Logger::log_configdata(
255 TitanLoggerApi::ExecutorConfigdata_reason::overriding__testcase__list
,
257 Free(testcase_names
);
261 if (execute_list_len
== 0 && only_runnable
) {
262 // No config file or correct config file without EXECUTE section,
263 // AND precisely one control part: run that one.
264 execute_list_len
= 1;
265 execute_list
= (execute_list_item
*)Malloc(sizeof(*execute_list
));
266 execute_list
[0].module_name
= mcopystr(only_runnable
->get_name());
267 execute_list
[0].testcase_name
= 0; // control part
270 if (execute_list_len
> 0) { // we have something to run
271 Module_List::log_param();
272 Module_List::post_init_modules();
274 for (i
= 0; i
< execute_list_len
; i
++) {
275 if (execute_list
[i
].testcase_name
== NULL
)
276 Module_List::execute_control(execute_list
[i
].module_name
);
277 else if (!strcmp(execute_list
[i
].testcase_name
, "*"))
278 Module_List::execute_all_testcases(
279 execute_list
[i
].module_name
);
281 Module_List::execute_testcase(execute_list
[i
].module_name
,
282 execute_list
[i
].testcase_name
);
285 TTCN_warning("Nothing to run!");
287 ret_val
= EXIT_FAILURE
;
290 TTCN_Logger::log_str(TTCN_Logger::ERROR_UNQUALIFIED
,
291 "Fatal error. Aborting execution.");
292 ret_val
= EXIT_FAILURE
;
294 TTCN_Runtime::restore_signal_handlers();
295 TTCN_Runtime::log_verdict_statistics();
296 TTCN_Logger::log_executor_runtime(
297 TitanLoggerApi::ExecutorRuntime_reason::executor__finish__single__mode
);
298 TTCN_Logger::close_file();
300 // close_file() must be called before the information is lost
301 // close_file() WRITES to log
303 TTCN_Logger::clear_parameters();
304 PORT::clear_parameters();
305 COMPONENT::clear_component_names();
306 TTCN_EncDec::clear_error();
308 for (i
= 0; i
< execute_list_len
; i
++) {
309 Free(execute_list
[i
].module_name
);
310 Free(execute_list
[i
].testcase_name
);
314 TTCN_Logger::terminate_logger();
315 TTCN_Snapshot::terminate();