1// (C) Copyright Gennadiy Rozental 2001. 2// Distributed under the Boost Software License, Version 1.0. 3// (See accompanying file LICENSE_1_0.txt or copy at 4// http://www.boost.org/LICENSE_1_0.txt) 5 6// See http://www.boost.org/libs/test for the library home page. 7// 8// File : $RCSfile$ 9// 10// Version : $Revision$ 11// 12// Description : simple implementation for Unit Test Framework parameter 13// handling routines. May be rewritten in future to use some kind of 14// command-line arguments parsing facility and environment variable handling 15// facility 16// *************************************************************************** 17 18#ifndef BOOST_TEST_UNIT_TEST_PARAMETERS_IPP_012205GER 19#define BOOST_TEST_UNIT_TEST_PARAMETERS_IPP_012205GER 20 21// Boost.Test 22#include <boost/test/unit_test_parameters.hpp> 23 24#include <boost/test/utils/basic_cstring/basic_cstring.hpp> 25#include <boost/test/utils/basic_cstring/compare.hpp> 26#include <boost/test/utils/basic_cstring/io.hpp> 27#include <boost/test/utils/iterator/token_iterator.hpp> 28 29#include <boost/test/debug.hpp> 30#include <boost/test/framework.hpp> 31 32#include <boost/test/detail/log_level.hpp> 33#include <boost/test/detail/throw_exception.hpp> 34 35// Boost.Runtime.Param 36#include <boost/test/utils/runtime/parameter.hpp> 37#include <boost/test/utils/runtime/argument.hpp> 38#include <boost/test/utils/runtime/finalize.hpp> 39#include <boost/test/utils/runtime/cla/parser.hpp> 40#include <boost/test/utils/runtime/env/fetch.hpp> 41 42// Boost 43#include <boost/config.hpp> 44#include <boost/test/detail/suppress_warnings.hpp> 45#include <boost/test/detail/enable_warnings.hpp> 46#include <boost/cstdlib.hpp> 47 48// STL 49#include <cstdlib> 50#include <iostream> 51#include <fstream> 52 53#include <boost/test/detail/suppress_warnings.hpp> 54 55//____________________________________________________________________________// 56 57# ifdef BOOST_NO_STDC_NAMESPACE 58namespace std { using ::getenv; using ::strncmp; using ::strcmp; } 59# endif 60 61namespace boost { 62namespace unit_test { 63 64namespace rt = boost::runtime; 65 66// ************************************************************************** // 67// ************** runtime_config ************** // 68// ************************************************************************** // 69 70namespace runtime_config { 71 72// UTF parameters 73std::string btrt_auto_start_dbg = "auto_start_dbg"; 74std::string btrt_break_exec_path = "break_exec_path"; 75std::string btrt_build_info = "build_info"; 76std::string btrt_catch_sys_errors = "catch_system_errors"; 77std::string btrt_color_output = "color_output"; 78std::string btrt_detect_fp_except = "detect_fp_exceptions"; 79std::string btrt_detect_mem_leaks = "detect_memory_leaks"; 80std::string btrt_list_content = "list_content"; 81std::string btrt_list_labels = "list_labels"; 82std::string btrt_log_format = "log_format"; 83std::string btrt_log_level = "log_level"; 84std::string btrt_log_sink = "log_sink"; 85std::string btrt_combined_logger = "logger"; 86std::string btrt_output_format = "output_format"; 87std::string btrt_random_seed = "random"; 88std::string btrt_report_format = "report_format"; 89std::string btrt_report_level = "report_level"; 90std::string btrt_report_mem_leaks = "report_memory_leaks_to"; 91std::string btrt_report_sink = "report_sink"; 92std::string btrt_result_code = "result_code"; 93std::string btrt_run_filters = "run_test"; 94std::string btrt_save_test_pattern = "save_pattern"; 95std::string btrt_show_progress = "show_progress"; 96std::string btrt_use_alt_stack = "use_alt_stack"; 97std::string btrt_wait_for_debugger = "wait_for_debugger"; 98 99std::string btrt_help = "help"; 100std::string btrt_usage = "usage"; 101std::string btrt_version = "version"; 102 103//____________________________________________________________________________// 104 105namespace { 106 107void 108register_parameters( rt::parameters_store& store ) 109{ 110 rt::option auto_start_dbg( btrt_auto_start_dbg, ( 111 rt::description = "Automatically attaches debugger in case of system level failure (signal).", 112 rt::env_var = "BOOST_TEST_AUTO_START_DBG", 113 114 rt::help = "Specifies whether Boost.Test should attempt " 115 "to attach a debugger when fatal system error occurs. At the moment this feature " 116 "is only available on a few selected platforms: Win32 and *nix. There is a " 117 "default debugger configured for these platforms. You can manually configure " 118 "different debugger. For more details on how to configure the debugger see the " 119 "Boost.Test debug API, specifically the function boost::debug::set_debugger." 120 )); 121 122 auto_start_dbg.add_cla_id( "--", btrt_auto_start_dbg, "=" ); 123 auto_start_dbg.add_cla_id( "-", "d", " " ); 124 store.add( auto_start_dbg ); 125 126 /////////////////////////////////////////////// 127 128 rt::parameter<std::string> break_exec_path( btrt_break_exec_path, ( 129 rt::description = "For the exception safety testing allows to break at specific execution path.", 130 rt::env_var = "BOOST_TEST_BREAK_EXEC_PATH" 131#ifndef BOOST_NO_CXX11_LAMBDAS 132 , 133 rt::callback = [](rt::cstring) { 134 BOOST_TEST_SETUP_ASSERT( false, "parameter break_exec_path is disabled in this release" ); 135 } 136#endif 137 )); 138 139 break_exec_path.add_cla_id( "--", btrt_break_exec_path, "=" ); 140 store.add( break_exec_path ); 141 142 /////////////////////////////////////////////// 143 144 rt::option build_info( btrt_build_info, ( 145 rt::description = "Displays library build information.", 146 rt::env_var = "BOOST_TEST_BUILD_INFO", 147 rt::help = "Displays library build information, including: platform, " 148 "compiler, STL version and Boost version." 149 )); 150 151 build_info.add_cla_id( "--", btrt_build_info, "=" ); 152 build_info.add_cla_id( "-", "i", " " ); 153 store.add( build_info ); 154 155 /////////////////////////////////////////////// 156 157 rt::option catch_sys_errors( btrt_catch_sys_errors, ( 158 rt::description = "Allows to switch between catching and ignoring system errors (signals).", 159 rt::env_var = "BOOST_TEST_CATCH_SYSTEM_ERRORS", 160 rt::default_value = 161#ifdef BOOST_TEST_DEFAULTS_TO_CORE_DUMP 162 false, 163#else 164 true, 165#endif 166 rt::help = "If option " + btrt_catch_sys_errors + " has value 'no' the frameworks does not attempt to catch " 167 "asynchronous system failure events (signals on *NIX platforms or structured exceptions on Windows). " 168 " Default value is " 169#ifdef BOOST_TEST_DEFAULTS_TO_CORE_DUMP 170 "no." 171#else 172 "true." 173#endif 174 )); 175 176 catch_sys_errors.add_cla_id( "--", btrt_catch_sys_errors, "=", true ); 177 catch_sys_errors.add_cla_id( "-", "s", " " ); 178 store.add( catch_sys_errors ); 179 180 /////////////////////////////////////////////// 181 182 rt::option color_output( btrt_color_output, ( 183 rt::description = "Enables color output of the framework log and report messages.", 184 rt::env_var = "BOOST_TEST_COLOR_OUTPUT", 185 rt::default_value = true, 186 rt::help = "Produces color output for logs, reports and help. " 187 "Defaults to true. " 188 )); 189 190 color_output.add_cla_id( "--", btrt_color_output, "=", true ); 191 color_output.add_cla_id( "-", "x", " " ); 192 store.add( color_output ); 193 194 /////////////////////////////////////////////// 195 196 rt::option detect_fp_except( btrt_detect_fp_except, ( 197 rt::description = "Enables/disables floating point exceptions traps.", 198 rt::env_var = "BOOST_TEST_DETECT_FP_EXCEPTIONS", 199 rt::help = "Enables/disables hardware traps for the floating " 200 "point exceptions (if supported on your platfrom)." 201 )); 202 203 detect_fp_except.add_cla_id( "--", btrt_detect_fp_except, "=", true ); 204 store.add( detect_fp_except ); 205 206 /////////////////////////////////////////////// 207 208 rt::parameter<unsigned long> detect_mem_leaks( btrt_detect_mem_leaks, ( 209 rt::description = "Turns on/off memory leaks detection (optionally breaking on specified alloc order number).", 210 rt::env_var = "BOOST_TEST_DETECT_MEMORY_LEAK", 211 rt::default_value = 1L, 212 rt::optional_value = 1L, 213 rt::value_hint = "<alloc order number>", 214 rt::help = "Enables/disables memory leaks detection. " 215 "This parameter has optional long integer value. The default value is 1, which " 216 "enables the memory leak detection. The value 0 disables memory leak detection. " 217 "Any value N greater than 1 is treated as leak allocation number and tells the " 218 "framework to setup runtime breakpoint at Nth heap allocation. If value is " 219 "omitted the default value is assumed." 220 )); 221 222 detect_mem_leaks.add_cla_id( "--", btrt_detect_mem_leaks, "=" ); 223 store.add( detect_mem_leaks ); 224 225 /////////////////////////////////////////////// 226 227 rt::enum_parameter<unit_test::output_format> list_content( btrt_list_content, ( 228 rt::description = "Lists the content of test tree - names of all test suites and test cases.", 229 rt::env_var = "BOOST_TEST_LIST_CONTENT", 230 rt::default_value = OF_INVALID, 231 rt::optional_value = OF_CLF, 232 rt::enum_values<unit_test::output_format>::value = 233#if defined(BOOST_TEST_CLA_NEW_API) 234 { 235 { "HRF", OF_CLF }, 236 { "DOT", OF_DOT } 237 }, 238#else 239 rt::enum_values_list<unit_test::output_format>() 240 ( "HRF", OF_CLF ) 241 ( "DOT", OF_DOT ) 242 , 243#endif 244 rt::help = "Lists the test suites and cases " 245 "of the test module instead of executing the test cases. The format of the " 246 "desired output can be passed to the command. Currently the " 247 "framework supports two formats: human readable format (HRF) and dot graph " 248 "format (DOT). If value is omitted HRF value is assumed." 249 )); 250 list_content.add_cla_id( "--", btrt_list_content, "=" ); 251 store.add( list_content ); 252 253 /////////////////////////////////////////////// 254 255 rt::option list_labels( btrt_list_labels, ( 256 rt::description = "Lists all available labels.", 257 rt::env_var = "BOOST_TEST_LIST_LABELS", 258 rt::help = "Option " + btrt_list_labels + " instructs the framework to list all the the labels " 259 "defined in the test module instead of executing the test cases." 260 )); 261 262 list_labels.add_cla_id( "--", btrt_list_labels, "=" ); 263 store.add( list_labels ); 264 265 /////////////////////////////////////////////// 266 267 rt::enum_parameter<unit_test::output_format> log_format( btrt_log_format, ( 268 rt::description = "Specifies log format.", 269 rt::env_var = "BOOST_TEST_LOG_FORMAT", 270 rt::default_value = OF_CLF, 271 rt::enum_values<unit_test::output_format>::value = 272#if defined(BOOST_TEST_CLA_NEW_API) 273 { 274 { "HRF", OF_CLF }, 275 { "CLF", OF_CLF }, 276 { "XML", OF_XML }, 277 { "JUNIT", OF_JUNIT }, 278 }, 279#else 280 rt::enum_values_list<unit_test::output_format>() 281 ( "HRF", OF_CLF ) 282 ( "CLF", OF_CLF ) 283 ( "XML", OF_XML ) 284 ( "JUNIT", OF_JUNIT ) 285 , 286#endif 287 rt::help = "Set the frameowrk's log format to one " 288 "of the formats supplied by the framework. The only acceptable values for this " 289 "parameter are the names of the output formats supplied by the framework. By " 290 "default the framework uses human readable format (HRF) for testing log. This " 291 "format is similar to compiler error format. Alternatively you can specify XML " 292 "or JUNIT as log format, which are easier to process by testing automation tools." 293 )); 294 295 log_format.add_cla_id( "--", btrt_log_format, "=" ); 296 log_format.add_cla_id( "-", "f", " " ); 297 store.add( log_format ); 298 299 /////////////////////////////////////////////// 300 301 rt::enum_parameter<unit_test::log_level> log_level( btrt_log_level, ( 302 rt::description = "Specifies the logging level of the test execution.", 303 rt::env_var = "BOOST_TEST_LOG_LEVEL", 304 rt::default_value = log_all_errors, 305 rt::enum_values<unit_test::log_level>::value = 306#if defined(BOOST_TEST_CLA_NEW_API) 307 { 308 { "all" , log_successful_tests }, 309 { "success" , log_successful_tests }, 310 { "test_suite" , log_test_units }, 311 { "unit_scope" , log_test_units }, 312 { "message" , log_messages }, 313 { "warning" , log_warnings }, 314 { "error" , log_all_errors }, 315 { "cpp_exception" , log_cpp_exception_errors }, 316 { "system_error" , log_system_errors }, 317 { "fatal_error" , log_fatal_errors }, 318 { "nothing" , log_nothing } 319 }, 320#else 321 rt::enum_values_list<unit_test::log_level>() 322 ( "all" , log_successful_tests ) 323 ( "success" , log_successful_tests ) 324 ( "test_suite" , log_test_units ) 325 ( "unit_scope" , log_test_units ) 326 ( "message" , log_messages ) 327 ( "warning" , log_warnings ) 328 ( "error" , log_all_errors ) 329 ( "cpp_exception" , log_cpp_exception_errors ) 330 ( "system_error" , log_system_errors ) 331 ( "fatal_error" , log_fatal_errors ) 332 ( "nothing" , log_nothing ) 333 , 334#endif 335 rt::help = "Set the framework's log level. " 336 "The log level defines the verbosity of the testing logs produced by a test " 337 "module. The verbosity ranges from a complete log, when all assertions " 338 "(both successful and failing) are reported, all notifications about " 339 "test units start and finish are included, to an empty log when nothing " 340 "is reported to a testing log stream." 341 )); 342 343 log_level.add_cla_id( "--", btrt_log_level, "=" ); 344 log_level.add_cla_id( "-", "l", " " ); 345 store.add( log_level ); 346 347 /////////////////////////////////////////////// 348 349 rt::parameter<std::string> log_sink( btrt_log_sink, ( 350 rt::description = "Specifies log sink: stdout (default), stderr or file name.", 351 rt::env_var = "BOOST_TEST_LOG_SINK", 352 rt::value_hint = "<stderr|stdout|file name>", 353 rt::help = "Sets the log sink - the location " 354 "where Boost.Test writes the logs of the test execution. It allows to easily redirect the " 355 "test logs to file or standard streams. By default testing log is " 356 "directed to standard output." 357 )); 358 359 log_sink.add_cla_id( "--", btrt_log_sink, "=" ); 360 log_sink.add_cla_id( "-", "k", " " ); 361 store.add( log_sink ); 362 363 /////////////////////////////////////////////// 364 365 rt::enum_parameter<unit_test::output_format> output_format( btrt_output_format, ( 366 rt::description = "Specifies output format (both log and report).", 367 rt::env_var = "BOOST_TEST_OUTPUT_FORMAT", 368 rt::enum_values<unit_test::output_format>::value = 369#if defined(BOOST_TEST_CLA_NEW_API) 370 { 371 { "HRF", OF_CLF }, 372 { "CLF", OF_CLF }, 373 { "XML", OF_XML } 374 }, 375#else 376 rt::enum_values_list<unit_test::output_format>() 377 ( "HRF", OF_CLF ) 378 ( "CLF", OF_CLF ) 379 ( "XML", OF_XML ) 380 , 381#endif 382 rt::help = "Combines an effect of " + btrt_report_format + 383 " and " + btrt_log_format + " parameters. If this parameter is specified, " 384 "it overrides the value of other two parameters. This parameter does not " 385 "have a default value. The only acceptable values are string names of " 386 "output formats: HRF - human readable format and XML - XML formats for " 387 "automation tools processing." 388 )); 389 390 output_format.add_cla_id( "--", btrt_output_format, "=" ); 391 output_format.add_cla_id( "-", "o", " " ); 392 store.add( output_format ); 393 394 /////////////////////////////////////////////// combined logger option 395 396 rt::parameter<std::string,rt::REPEATABLE_PARAM> combined_logger( btrt_combined_logger, ( 397 rt::description = "Specifies log level and sink for one or several log format", 398 rt::env_var = "BOOST_TEST_LOGGER", 399 rt::value_hint = "log_format,log_level,log_sink[:log_format,log_level,log_sink]", 400 rt::help = "Specify one or more logging definition, which include the logger type, level and sink. " 401 "The log format, level and sink follow the same format as for the argument '--" + btrt_log_format + 402 "', '--" + btrt_log_level + "' and '--" + btrt_log_sink + "' respetively. " 403 "This command can take several logging definition separated by a ':', or be repeated " 404 "on the command line." 405 )); 406 407 combined_logger.add_cla_id( "--", btrt_combined_logger, "=" ); 408 store.add( combined_logger ); 409 410 /////////////////////////////////////////////// 411 412 rt::parameter<unsigned> random_seed( btrt_random_seed, ( 413 rt::description = "Allows to switch between sequential and random order of test units execution." 414 " Optionally allows to specify concrete seed for random number generator.", 415 rt::env_var = "BOOST_TEST_RANDOM", 416 rt::default_value = 0U, 417 rt::optional_value = 1U, 418 rt::value_hint = "<seed>", 419 rt::help = "Instructs the framework to execute the " 420 "test cases in random order. This parameter accepts an optional unsigned " 421 "integer argument. If parameter is specified without the argument value testing " 422 "order is randomized based on current time. Alternatively you can specify " 423 "any positive value greater than 1 and it will be used as random seed for " 424 "the run. " 425 "By default, the test cases are executed in an " 426 "order defined by their declaration and the optional dependencies among the test units." 427 )); 428 429 random_seed.add_cla_id( "--", btrt_random_seed, "=" ); 430 store.add( random_seed ); 431 432 /////////////////////////////////////////////// 433 434 rt::enum_parameter<unit_test::output_format> report_format( btrt_report_format, ( 435 rt::description = "Specifies the test report format.", 436 rt::env_var = "BOOST_TEST_REPORT_FORMAT", 437 rt::default_value = OF_CLF, 438 rt::enum_values<unit_test::output_format>::value = 439#if defined(BOOST_TEST_CLA_NEW_API) 440 { 441 { "HRF", OF_CLF }, 442 { "CLF", OF_CLF }, 443 { "XML", OF_XML } 444 }, 445#else 446 rt::enum_values_list<unit_test::output_format>() 447 ( "HRF", OF_CLF ) 448 ( "CLF", OF_CLF ) 449 ( "XML", OF_XML ) 450 , 451#endif 452 rt::help = "Set the framework's report format " 453 "to one of the formats supplied by the framework. The only acceptable values " 454 "for this parameter are the names of the output formats. By default the framework " 455 "uses human readable format (HRF) for results reporting. Alternatively you can " 456 "specify XML as report format. This format is easier to process by testing " 457 "automation tools." 458 )); 459 460 report_format.add_cla_id( "--", btrt_report_format, "=" ); 461 report_format.add_cla_id( "-", "m", " " ); 462 store.add( report_format ); 463 464 /////////////////////////////////////////////// 465 466 rt::enum_parameter<unit_test::report_level> report_level( btrt_report_level, ( 467 rt::description = "Specifies test report level.", 468 rt::env_var = "BOOST_TEST_REPORT_LEVEL", 469 rt::default_value = CONFIRMATION_REPORT, 470 rt::enum_values<unit_test::report_level>::value = 471#if defined(BOOST_TEST_CLA_NEW_API) 472 { 473 { "confirm", CONFIRMATION_REPORT }, 474 { "short", SHORT_REPORT }, 475 { "detailed", DETAILED_REPORT }, 476 { "no", NO_REPORT } 477 }, 478#else 479 rt::enum_values_list<unit_test::report_level>() 480 ( "confirm", CONFIRMATION_REPORT ) 481 ( "short", SHORT_REPORT ) 482 ( "detailed", DETAILED_REPORT ) 483 ( "no", NO_REPORT ) 484 , 485#endif 486 rt::help = "Set the verbosity level of the " 487 "result report generated by the testing framework. Use value 'no' to " 488 "disable the results report completely." 489 )); 490 491 report_level.add_cla_id( "--", btrt_report_level, "=" ); 492 report_level.add_cla_id( "-", "r", " " ); 493 store.add( report_level ); 494 495 /////////////////////////////////////////////// 496 497 rt::parameter<std::string> report_mem_leaks( btrt_report_mem_leaks, ( 498 rt::description = "File where to report memory leaks to.", 499 rt::env_var = "BOOST_TEST_REPORT_MEMORY_LEAKS_TO", 500 rt::default_value = std::string(), 501 rt::value_hint = "<file name>", 502 rt::help = "Parameter " + btrt_report_mem_leaks + " allows to specify a file where to report " 503 "memory leaks to. The parameter does not have default value. If it is not specified, " 504 "memory leaks (if any) are reported to the standard error stream." 505 )); 506 507 report_mem_leaks.add_cla_id( "--", btrt_report_mem_leaks, "=" ); 508 store.add( report_mem_leaks ); 509 510 /////////////////////////////////////////////// 511 512 rt::parameter<std::string> report_sink( btrt_report_sink, ( 513 rt::description = "Specifies report sink: stderr(default), stdout or file name.", 514 rt::env_var = "BOOST_TEST_REPORT_SINK", 515 rt::value_hint = "<stderr|stdout|file name>", 516 rt::help = "Sets the result report sink - " 517 "the location where the framework writes the result report to. " 518 "The sink may be a a file or a standard " 519 "stream. The default is 'stderr': the " 520 "standard error stream." 521 )); 522 523 report_sink.add_cla_id( "--", btrt_report_sink, "=" ); 524 report_sink.add_cla_id( "-", "e", " " ); 525 store.add( report_sink ); 526 527 /////////////////////////////////////////////// 528 529 rt::option result_code( btrt_result_code, ( 530 rt::description = "Disables test modules's result code generation.", 531 rt::env_var = "BOOST_TEST_RESULT_CODE", 532 rt::default_value = true, 533 rt::help = "The 'no' argument value for the parameter " + btrt_result_code + " instructs the " 534 "framework to always return zero result code. This can be used for test programs " 535 "executed within IDE. By default this parameter has value 'yes'." 536 )); 537 538 result_code.add_cla_id( "--", btrt_result_code, "=", true ); 539 result_code.add_cla_id( "-", "c", " " ); 540 store.add( result_code ); 541 542 /////////////////////////////////////////////// 543 544 rt::parameter<std::string,rt::REPEATABLE_PARAM> tests_to_run( btrt_run_filters, ( 545 rt::description = "Filters which tests to execute.", 546 rt::env_var = "BOOST_TEST_RUN_FILTERS", 547 rt::value_hint = "<test unit filter>", 548 rt::help = "Filters which test units to execute. " 549 "The framework supports both 'selection filters', which allow to select " 550 "which test units to enable from the set of available test units, and 'disabler " 551 "filters', which allow to disable some test units. Boost.test also supports " 552 "enabling/disabling test units at compile time. These settings identify the default " 553 "set of test units to run. Parameter " + btrt_run_filters + " is used to change this default. " 554 "This parameter is repeatable, so you can specify more than one filter if necessary." 555 )); 556 557 tests_to_run.add_cla_id( "--", btrt_run_filters, "=" ); 558 tests_to_run.add_cla_id( "-", "t", " " ); 559 store.add( tests_to_run ); 560 561 /////////////////////////////////////////////// 562 563 rt::option save_test_pattern( btrt_save_test_pattern, ( 564 rt::description = "Allows to switch between saving or matching test pattern file.", 565 rt::env_var = "BOOST_TEST_SAVE_PATTERN", 566 rt::help = "Parameter " + btrt_save_test_pattern + " facilitates switching mode of operation for " 567 "testing output streams.\n\nThis parameter serves no particular purpose within the " 568 "framework itself. It can be used by test modules relying on output_test_stream to " 569 "implement testing logic. Default mode is 'match' (false)." 570 )); 571 572 save_test_pattern.add_cla_id( "--", btrt_save_test_pattern, "=" ); 573 store.add( save_test_pattern ); 574 575 /////////////////////////////////////////////// 576 577 rt::option show_progress( btrt_show_progress, ( 578 rt::description = "Turns on progress display.", 579 rt::env_var = "BOOST_TEST_SHOW_PROGRESS", 580 rt::help = "Instructs the framework to display the progress of the tests. " 581 "This feature is turned off by default." 582 )); 583 584 show_progress.add_cla_id( "--", btrt_show_progress, "=" ); 585 show_progress.add_cla_id( "-", "p", " " ); 586 store.add( show_progress ); 587 588 /////////////////////////////////////////////// 589 590 rt::option use_alt_stack( btrt_use_alt_stack, ( 591 rt::description = "Turns on/off usage of an alternative stack for signal handling.", 592 rt::env_var = "BOOST_TEST_USE_ALT_STACK", 593 rt::default_value = true, 594 rt::help = "Instructs the framework to use an alternative " 595 "stack for operating system's signals handling (on platforms where this is supported). " 596 "The feature is enabled by default, but can be disabled using this command line switch." 597 )); 598 599 use_alt_stack.add_cla_id( "--", btrt_use_alt_stack, "=", true ); 600 store.add( use_alt_stack ); 601 602 /////////////////////////////////////////////// 603 604 rt::option wait_for_debugger( btrt_wait_for_debugger, ( 605 rt::description = "Forces test module to wait for button to be pressed before starting test run.", 606 rt::env_var = "BOOST_TEST_WAIT_FOR_DEBUGGER", 607 rt::help = "Instructs the framework to pause before starting " 608 "test units execution, so that you can attach a debugger to the test module process. " 609 "This feature is turned off by default." 610 )); 611 612 wait_for_debugger.add_cla_id( "--", btrt_wait_for_debugger, "=" ); 613 wait_for_debugger.add_cla_id( "-", "w", " " ); 614 store.add( wait_for_debugger ); 615 616 /////////////////////////////////////////////// 617 618 rt::parameter<std::string> help( btrt_help, ( 619 rt::description = "Help for framework parameters.", 620 rt::optional_value = std::string(), 621 rt::value_hint = "<parameter name>", 622 rt::help = "Displays help on the framework's parameters. " 623 "The parameter accepts an optional argument value. If present, an argument value is " 624 "interpreted as a parameter name (name guessing works as well, so for example " 625 "'--help=rand' displays help on the parameter 'random'). If the parameter name is unknown " 626 "or ambiguous error is reported. If argument value is absent, a summary of all " 627 "framework's parameter is displayed." 628 )); 629 help.add_cla_id( "--", btrt_help, "=" ); 630 store.add( help ); 631 632 /////////////////////////////////////////////// 633 634 rt::option usage( btrt_usage, ( 635 rt::description = "Short message explaining usage of Boost.Test parameters." 636 )); 637 usage.add_cla_id( "-", "?", " " ); 638 store.add( usage ); 639 640 /////////////////////////////////////////////// 641 642 rt::option version( btrt_version, ( 643 rt::description = "Prints Boost.Test version and exits." 644 )); 645 version.add_cla_id( "--", btrt_version, " " ); 646 store.add( version ); 647} 648 649static rt::arguments_store s_arguments_store; 650static rt::parameters_store s_parameters_store; 651 652//____________________________________________________________________________// 653 654} // local namespace 655 656void 657init( int& argc, char** argv ) 658{ 659 shared_ptr<rt::cla::parser> parser; 660 661 BOOST_TEST_I_TRY { 662 // Initialize parameters list 663 if( s_parameters_store.is_empty() ) 664 register_parameters( s_parameters_store ); 665 666 // Clear up arguments store just in case (of multiple init invocations) 667 s_arguments_store.clear(); 668 669 // Parse CLA they take precedence over environment 670 parser.reset( new rt::cla::parser( s_parameters_store, (rt::end_of_params = "--", rt::negation_prefix = "no_") ) ); 671 argc = parser->parse( argc, argv, s_arguments_store ); 672 673 // Try to fetch missing arguments from environment 674 rt::env::fetch_absent( s_parameters_store, s_arguments_store ); 675 676 // Set arguments to default values if defined and perform all the validations 677 rt::finalize_arguments( s_parameters_store, s_arguments_store ); 678 679 // check if colorized output is enabled 680 bool use_color = true; 681 if( s_arguments_store.has(btrt_color_output ) ) { 682 use_color = runtime_config::get<bool>(runtime_config::btrt_color_output); 683 } 684 685 // Report help if requested 686 if( runtime_config::get<bool>( btrt_version ) ) { 687 parser->version( std::cerr ); 688 BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_success ) ); 689 } 690 else if( runtime_config::get<bool>( btrt_usage ) ) { 691 parser->usage( std::cerr, runtime::cstring(), use_color ); 692 BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_success ) ); 693 } 694 else if( s_arguments_store.has( btrt_help ) ) { 695 parser->help(std::cerr, 696 s_parameters_store, 697 runtime_config::get<std::string>( btrt_help ), 698 use_color ); 699 BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_success ) ); 700 } 701 702 // A bit of business logic: output_format takes precedence over log/report formats 703 if( s_arguments_store.has( btrt_output_format ) ) { 704 unit_test::output_format of = s_arguments_store.get<unit_test::output_format>( btrt_output_format ); 705 s_arguments_store.set( btrt_report_format, of ); 706 s_arguments_store.set( btrt_log_format, of ); 707 } 708 709 } 710 BOOST_TEST_I_CATCH( rt::init_error, ex ) { 711 BOOST_TEST_SETUP_ASSERT( false, ex.msg ); 712 } 713 BOOST_TEST_I_CATCH( rt::ambiguous_param, ex ) { 714 std::cerr << ex.msg << "\n Did you mean one of these?\n"; 715 716 BOOST_TEST_FOREACH( rt::cstring, name, ex.m_amb_candidates ) 717 std::cerr << " " << name << "\n"; 718 719 BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_exception_failure ) ); 720 } 721 BOOST_TEST_I_CATCH( rt::unrecognized_param, ex ) { 722 std::cerr << ex.msg << "\n"; 723 724 if( !ex.m_typo_candidates.empty() ) { 725 std::cerr << " Did you mean one of these?\n"; 726 727 BOOST_TEST_FOREACH( rt::cstring, name, ex.m_typo_candidates ) 728 std::cerr << " " << name << "\n"; 729 } 730 else if( parser ) { 731 std::cerr << "\n"; 732 parser->usage( std::cerr ); 733 } 734 735 BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_exception_failure ) ); 736 } 737 BOOST_TEST_I_CATCH( rt::input_error, ex ) { 738 std::cerr << ex.msg << "\n\n"; 739 740 if( parser ) 741 parser->usage( std::cerr, ex.param_name ); 742 743 BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_exception_failure ) ); 744 } 745} 746 747//____________________________________________________________________________// 748 749rt::arguments_store const& 750argument_store() 751{ 752 return s_arguments_store; 753} 754 755//____________________________________________________________________________// 756 757bool 758save_pattern() 759{ 760 return runtime_config::get<bool>( btrt_save_test_pattern ); 761} 762 763//____________________________________________________________________________// 764 765} // namespace runtime_config 766} // namespace unit_test 767} // namespace boost 768 769#include <boost/test/detail/enable_warnings.hpp> 770 771#endif // BOOST_TEST_UNIT_TEST_PARAMETERS_IPP_012205GER 772