NCBI C++ ToolKit
test_boost.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: test_boost.cpp 100049 2023-06-07 19:59:38Z ucko $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author: Pavel Ivanov
27  *
28  * File Description:
29  * Implementation of special reporter for Boost.Test framework and utility
30  * functions for embedding it into the Boost.
31  *
32  */
33 
34 #include <ncbi_pch.hpp>
35 #include <corelib/ncbicfg.h>
36 #include <corelib/error_codes.hpp>
37 #include <corelib/ncbienv.hpp>
38 #include <corelib/ncbimisc.hpp>
39 #include <corelib/ncbiapp.hpp>
40 #include <corelib/ncbi_system.hpp>
42 
43 #ifndef BOOST_TEST_NO_LIB
44 # define BOOST_TEST_NO_LIB
45 #endif
46 #define BOOST_TEST_NO_MAIN
47 #if defined(__FreeBSD_cc_version) && !defined(__FreeBSD_version)
48 # define __FreeBSD_version __FreeBSD_cc_version
49 #endif
50 #include <corelib/test_boost.hpp>
51 
52 #include <boost/preprocessor/cat.hpp>
53 #include <boost/preprocessor/tuple/elem.hpp>
54 #include <boost/preprocessor/tuple/eat.hpp>
55 
56 // On Mac OS X, some corelib headers end up pulling in system headers
57 // that #define nil as a macro that ultimately expands to __null,
58 // breaking Boost's internal use of a struct nil.
59 #ifdef nil
60 # undef nil
61 #endif
62 #ifdef NCBI_COMPILER_MSVC
63 # pragma warning(push)
64 // 'class' : class has virtual functions, but destructor is not virtual
65 # pragma warning(disable: 4265)
66 // 'operator/operation' : unsafe conversion from 'type of expression' to 'type required'
67 # pragma warning(disable: 4191)
68 #endif
69 
70 #include <boost/test/included/unit_test.hpp>
71 #include <boost/test/results_collector.hpp>
72 #include <boost/test/results_reporter.hpp>
73 #include <boost/test/unit_test_log.hpp>
74 #include <boost/test/unit_test_log_formatter.hpp>
75 #include <boost/test/output/plain_report_formatter.hpp>
76 #include <boost/test/output/xml_report_formatter.hpp>
77 #include <boost/test/output/compiler_log_formatter.hpp>
78 #include <boost/test/output/xml_log_formatter.hpp>
79 #include <boost/test/utils/xml_printer.hpp>
80 #include <boost/test/detail/global_typedef.hpp>
81 #include <boost/test/debug.hpp>
82 
83 #if BOOST_VERSION >= 105900
84 # include <boost/test/tree/observer.hpp>
85 # include <boost/test/unit_test_parameters.hpp>
86 # define IGNORE_STATUS , true
87 #else
88 # include <boost/test/test_observer.hpp>
89 # include <boost/test/detail/unit_test_parameters.hpp>
90 # define OF_XML XML
91 # define TUT_CASE tut_case
92 # define TUT_SUITE tut_suite
93 # define IGNORE_STATUS
94 #endif
95 
96 #if BOOST_VERSION >= 106000
97 # define attr_value utils::attr_value
98 # if BOOST_VERSION >= 106400
99  // Everything old is new again, apparently...
100 # define RTCFG(type, new_name, old_name) \
101  but::runtime_config::get<type >(but::runtime_config::btrt_##old_name)
102 # define CONFIGURED_FILTERS RTCFG(std::vector<std::string>, _, run_filters)
103 # else
104 # define RTCFG(type, new_name, old_name) \
105  but::runtime_config::get<type >(but::runtime_config::new_name)
106 # endif
107 #else
108 # define RTCFG(type, new_name, old_name) but::runtime_config::old_name()
109 # if BOOST_VERSION >= 105900
110 # define BOOST_TEST_I_TRY BOOST_TEST_IMPL_TRY
111 # define BOOST_TEST_I_CATCH BOOST_TEST_IMPL_CATCH
112 # define BOOST_TEST_I_CATCH0 BOOST_TEST_IMPL_CATCH0
113 # define BOOST_TEST_I_CATCHALL BOOST_TEST_IMPL_CATCHALL
114 # else
115 # define BOOST_TEST_I_TRY try
116 # define BOOST_TEST_I_CATCH(type, ex) catch (type const& ex)
117 # define BOOST_TEST_I_CATCH0(type) catch (type const&)
118 # define BOOST_TEST_I_CATCHALL() catch (...)
119 # endif
120 #endif
121 
122 #ifndef CONFIGURED_FILTERS
123  #define CONFIGURED_FILTERS \
124  RTCFG(std::vector<std::string>, RUN_FILTERS, test_to_run)
125 #endif
126 
127 #ifdef NCBI_COMPILER_MSVC
128 # pragma warning(pop)
129 #endif
130 
131 #include <list>
132 #include <vector>
133 #include <set>
134 #include <map>
135 #include <string>
136 
137 
138 #define NCBI_USE_ERRCODE_X Corelib_TestBoost
139 
140 
141 namespace but = boost::unit_test;
142 
143 
145 
146 #ifdef SYSTEM_MUTEX_INITIALIZER
148 #else
149 CAutoInitializeStaticFastMutex g_NcbiTestMutex;
150 #endif
151 
152 #if BOOST_VERSION >= 105900
153 inline
154 static bool s_IsEnabled(const but::test_unit& tu) {
155  return tu.is_enabled();
156 }
157 
158 inline
159 static void s_SetEnabled(but::test_unit& tu, bool enabled) {
160  but::test_unit::run_status rs
161  = enabled ? but::test_unit::RS_ENABLED : but::test_unit::RS_DISABLED;
162  tu.p_default_status.set(rs);
163  tu.p_run_status.set(rs);
164 }
165 #else
166 inline
167 static bool s_IsEnabled(const but::test_unit& tu) {
168  return tu.p_enabled;
169 }
170 
171 inline
172 static void s_SetEnabled(but::test_unit& tu, bool enabled) {
173  tu.p_enabled.set(enabled);
174 }
175 #endif
176 
177 const char* kTestsDisableSectionName = "UNITTESTS_DISABLE";
178 const char* kTestsToFixSectionName = "UNITTESTS_TOFIX";
179 const char* kTestsTimeoutSectionName = "UNITTESTS_TIMEOUT_MULT";
180 const char* kTestConfigGlobalValue = "GLOBAL";
181 
182 #define DUMMY_TEST_FUNCTION_NAME DummyTestFunction
183 const char* kDummyTestCaseName = BOOST_STRINGIZE(DUMMY_TEST_FUNCTION_NAME);
184 
185 const char* kTestResultPassed = "passed";
186 const char* kTestResultFailed = "failed";
187 const char* kTestResultTimeout = "timeout";
188 const char* kTestResultAborted = "aborted";
189 const char* kTestResultSkipped = "skipped";
190 const char* kTestResultDisabled = "disabled";
191 const char* kTestResultToFix = "tofix";
192 
193 
195 typedef but::unit_test_log_formatter TBoostLogFormatter;
199 
200 
201 /// Reporter for embedding in Boost framework and adding non-standard
202 /// information to detailed report given by Boost.
204 {
205 public:
206  CNcbiBoostReporter(void);
207  virtual ~CNcbiBoostReporter(void) {}
208 
209  /// Setup reporter tuned for printing report of specific format
210  ///
211  /// @param format
212  /// Format of the report
213  void SetOutputFormat(but::output_format format);
214 
215  // TBoostRepFormatter interface
216  virtual void results_report_start (ostream& ostr);
217  virtual void results_report_finish (ostream& ostr);
218  virtual void test_unit_report_start (but::test_unit const& tu, ostream& ostr);
219  virtual void test_unit_report_finish (but::test_unit const& tu, ostream& ostr);
220  virtual void do_confirmation_report (but::test_unit const& tu, ostream& ostr);
221 
222 private:
223  /// Standard reporter from Boost for particular report format
225  /// If report is XML or not
226  bool m_IsXML;
227  /// Current indentation level in plain text report
228  int m_Indent;
229 };
230 
231 
232 /// Logger for embedding in Boost framework and adding non-standard
233 /// information to logging given by Boost.
235 {
236 public:
237  CNcbiBoostLogger(void);
238  virtual ~CNcbiBoostLogger(void) {}
239 
240  /// Setup logger tuned for printing log of specific format
241  ///
242  /// @param format
243  /// Format of the report
244  void SetOutputFormat(but::output_format format);
245 
246  // TBoostLogFormatter interface
247  virtual void log_start(ostream& ostr, but::counter_t test_cases_amount);
248  virtual void log_finish(ostream& ostr);
249 #if BOOST_VERSION >= 107000
250  virtual void log_build_info(ostream& ostr, bool log_build_info = true);
251 #else
252  virtual void log_build_info(ostream& ostr);
253 #endif
254  virtual void test_unit_start(ostream& ostr, but::test_unit const& tu);
255  virtual void test_unit_finish(ostream& ostr, but::test_unit const& tu, unsigned long elapsed);
256  virtual void test_unit_skipped(ostream& ostr, but::test_unit const& tu);
257 #if BOOST_VERSION >= 105900
258  virtual void log_exception_start(ostream& ostr, but::log_checkpoint_data const& lcd, boost::execution_exception const& ex);
259  virtual void log_exception_finish(ostream& ostr);
260 #elif BOOST_VERSION >= 104200
261  virtual void log_exception(ostream& ostr, but::log_checkpoint_data const& lcd, boost::execution_exception const& ex);
262  // Next line is necessary for compiling with ICC and Boost 1.41.0 and up
263  using TBoostLogFormatter::log_exception;
264 #else
265  virtual void log_exception(ostream& ostr, but::log_checkpoint_data const& lcd, but::const_string explanation);
266 #endif
267  virtual void log_entry_start(ostream& ostr, but::log_entry_data const& led, log_entry_types let);
268  virtual void log_entry_value (ostream& ostr, but::const_string value);
269  // Next line is necessary for compiling with ICC and Boost 1.41.0 and up
270  using TBoostLogFormatter::log_entry_value;
271  virtual void log_entry_finish (ostream& ostr);
272 
273 #if BOOST_VERSION >= 105900
274  virtual void entry_context_start(ostream& ostr, but::log_level l);
275 # if BOOST_VERSION >= 106500
276  virtual void log_entry_context(ostream& os, but::log_level l, but::const_string v);
277  virtual void entry_context_finish(ostream& os, but::log_level l);
278 # else
279  virtual void log_entry_context(ostream& ostr, but::const_string value);
280  virtual void entry_context_finish (ostream& ostr);
281 # endif
282 #endif
283 
284 private:
285  /// Standard logger from Boost for particular report format
287  /// If report is XML or not
288  bool m_IsXML;
289 };
290 
291 
292 /// Special observer to embed in Boost.Test framework to initialize test
293 /// dependencies before they started execution.
294 class CNcbiTestsObserver : public but::test_observer
295 {
296 public:
297  virtual ~CNcbiTestsObserver(void) {}
298 
299  /// Method called before execution of all tests
300  // virtual void test_start(but::counter_t /* test_cases_amount */);
301 
302  /// Method called after execution of all tests
303  virtual void test_finish(void);
304 
305  /// Method called before execution of each unit
306  virtual void test_unit_start(but::test_unit const& tu);
307 
308  /// Method called after execution of each unit
309  virtual void test_unit_finish(but::test_unit const& tu, unsigned long elapsed);
310 
311  /// Method called when some exception was caught during execution of unit
312  virtual void exception_caught(boost::execution_exception const& ex);
313 
314  /// Method called when some check fails during execution of unit
315  virtual void test_unit_aborted(but::test_unit const& tu);
316 
317 #if BOOST_VERSION >= 105900
318  virtual void assertion_result(but::assertion_result ar);
319 #endif
320  virtual void assertion_result(bool passed);
321 };
322 
323 
324 /// Class that can walk through all tree of tests and register them inside
325 /// CNcbiTestApplication.
326 class CNcbiTestsCollector : public but::test_tree_visitor
327 {
328 public:
329  virtual ~CNcbiTestsCollector(void) {}
330 
331  virtual void visit (but::test_case const& test );
332  virtual bool test_suite_start(but::test_suite const& suite);
333 };
334 
335 
336 /// Element of tests tree. Used to make proper order between units to ensure
337 /// that dependencies are executed earlier than dependents.
339 {
340 public:
341  /// Element represents one test unit
342  CNcbiTestTreeElement(but::test_unit* tu);
343  /// In destructor class destroys all its children
344  ~CNcbiTestTreeElement(void);
345 
346  /// Get unit represented by the element
347  but::test_unit* GetTestUnit(void);
348 
349  /// Add child element. Class acquires ownership on the child element and
350  /// destroys it at the end of work.
351  void AddChild(CNcbiTestTreeElement* element);
352 
353  /// Get parent element in tests tree. If this element represents master
354  /// test suite then return NULL.
356 
357  /// Ensure good dependency of this element on "from" element. If
358  /// dependency is not fulfilled well then ensure that "from" element will
359  /// stand earlier in tests tree. Correct order is made in internal
360  /// structures only. To make it in Boost tests tree you need to call
361  /// FixUnitsOrder().
362  ///
363  /// @sa FixUnitsOrder()
364  void EnsureDep(CNcbiTestTreeElement* from);
365 
366  /// Fix order of unit tests in the subtree rooted in this element. Any
367  /// action is taken only if during calls to EnsureDep() some wrong order
368  /// was found.
369  ///
370  /// @sa EnsureDep()
371  void FixUnitsOrder(void);
372 
373 private:
374  /// Prohibit
377 
378  typedef vector<CNcbiTestTreeElement*> TElemsList;
380 
381  /// Ensure that leftElem and rightElem (or element pointed by it_right
382  /// inside m_Children) are in that very order: leftElem first, rightElem
383  /// after that. leftElem and rightElem should be children of this element.
385  void x_EnsureChildOrder(CNcbiTestTreeElement* leftElem, size_t idx_right);
386 
387  /// Add leftElem (rightElem) in the list of elements that should be
388  /// "lefter" ("righter") in the tests tree.
391 
392 private:
393  /// Parent element in tests tree
395  /// Unit represented by the element
396  but::test_unit* m_TestUnit;
397  /// If order of children was changed during checking dependencies
399  /// Children of the element in tests tree
401  /// Elements that should be "on the left" from this element in tests tree
402  /// (should have less index in the parent's list of children).
404  /// Elements that should be "on the right" from this element in tests tree
405  /// (should have greater index in the parent's list of children).
407 };
408 
409 
410 /// Class for traversing all Boost tests tree and building tree structure in
411 /// our own accessible manner.
412 class CNcbiTestsTreeBuilder : public but::test_tree_visitor
413 {
414 public:
415  CNcbiTestsTreeBuilder(void);
416  virtual ~CNcbiTestsTreeBuilder(void);
417 
418  virtual void visit (but::test_case const& test );
419  virtual bool test_suite_start (but::test_suite const& suite);
420  virtual void test_suite_finish(but::test_suite const& suite);
421 
422  /// Ensure good dependency of the tu test unit on tu_from test unit. If
423  /// dependency is not fulfilled well then ensure that tu_from element will
424  /// stand earlier in tests tree. Correct order is made in internal
425  /// structures only. To make it in Boost tests tree you need to call
426  /// FixUnitsOrder().
427  ///
428  /// @sa FixUnitsOrder()
429  void EnsureDep(but::test_unit* tu, but::test_unit* tu_from);
430 
431  /// Fix order of unit tests in the whole tree of tests. Any action is
432  /// taken only if during calls to EnsureDep() some wrong order was found.
433  ///
434  /// @sa EnsureDep()
435  void FixUnitsOrder(void);
436 
437 private:
439 
440  /// Root element of the tests tree
442  /// Element in tests tree representing started but not yet finished test
443  /// suite, i.e. all test cases that will be visited now will for sure be
444  /// from this test suite.
446  /// Overall map of relations between test units and their representatives
447  /// in elements tree.
449 };
450 
451 
452 /// Application for all unit tests
454 {
455 public:
456  CNcbiTestApplication(void);
457  ~CNcbiTestApplication(void);
458 
459  virtual void Init (void);
460  virtual int Run (void);
461  virtual int DryRun(void);
462 
463  /// Add user function
465  ETestUserFuncType func_type);
466  /// Add dependency for test unit
467  void AddTestDependsOn(but::test_unit* tu, but::test_unit* dep_tu);
468  /// Set test as disabled by user
469  void SetTestDisabled(but::test_unit* tu);
470  /// Set flag that all tests globally disabled
471  void SetGloballyDisabled(void);
472  /// Set flag that all tests globally skipped
473  void SetGloballySkipped(void);
474 
475  /// Initialize this application, main test suite and all test framework
476  but::test_suite* InitTestFramework(int argc, char* argv[]);
477  /// Get object with argument descriptions.
478  /// Return NULL if it is not right time to fill in descriptions.
480  /// Get parser evaluating configuration conditions.
481  /// Return NULL if it is not right time to deal with the parser.
482  CExprParser* GetIniParser(void);
483 
484  /// Save test unit in the collection of all tests.
485  void CollectTestUnit(but::test_unit* tu);
486  /// Get pointer to test case or test suite by its name.
487  but::test_unit* GetTestUnit(CTempString test_name);
488  /// Initialize already prepared test suite before running tests
489  void InitTestsBeforeRun(void);
490  /// Finalize test suite after running tests
491  void FiniTestsAfterRun(void);
492  /// Enable all necessary tests after execution but before printing report
493  void ReEnableAllTests(void);
494  /// Check the correct setting for unit timeout and check overall
495  /// test timeout.
496  void AdjustTestTimeout(but::test_unit* tu);
497  /// Mark test case as failed due to hit of the timeout
498  void SetTestTimedOut(but::test_case* tc);
499  /// Register the fact of test failure
500  void SetTestErrored(but::test_case* tc);
501  /// Check if given test is marked as requiring fixing in the future
502  bool IsTestToFix(const but::test_unit* tu);
503 
504  /// Get number of actually executed tests
505  int GetRanTestsCount(void);
506  /// Get number of tests that were failed but are marked to be fixed
507  int GetToFixTestsCount(void);
508  /// Get string representation of result of test execution
509  string GetTestResultString(but::test_unit* tu);
510  /// Get pointer to empty test case added to Boost for internal purposes
511  but::test_case* GetDummyTest(void);
512  /// Check if user initialization functions failed
513  bool IsInitFailed(void);
514 
515  /// Check if there were any test errors
516  bool HasTestErrors(void);
517  /// Check if there were any timeouted tests
518  bool HasTestTimeouts(void);
519 
520  /// Get the application's cached configuration parameters, accessible to read-write.
521  /// @sa GetConfig, GetRWConfig
523 
524  ostream& GetFreeformReportStream(void) const;
525 
526 private:
527  typedef list<TNcbiTestUserFunction> TUserFuncsList;
528 
529  /// Setup our own reporter for Boost.Test
530  void x_SetupBoostReporters(void);
531  /// Call all user functions. Return TRUE if functions execution is
532  /// successful and FALSE if come function thrown exception.
533  bool x_CallUserFuncs(ETestUserFuncType func_type);
534  /// Ensure that all dependencies stand earlier in tests tree than their
535  /// dependents.
536  void x_EnsureAllDeps(void);
537  /// Set up real Boost.Test dependencies based on ones made by
538  /// AddTestDependsOn().
539  ///
540  /// @sa AddTestDependsOn()
541  void x_ActualizeDeps(void);
542  /// Enable / disable tests based on application configuration file
543  bool x_ReadConfiguration(void);
544  /// Get number of tests which Boost will execute
545  int x_GetEnabledTestsCount(void);
546  /// Add empty test necesary for internal purposes
547  void x_AddDummyTest(void);
548  /// Initialize common for all tests parser variables
549  /// (OS*, COMPILER* and DLL_BUILD)
550  void x_InitCommonParserVars(void);
551  /// Apply standard trimmings to test name and return resultant test name
552  /// which will identify test inside the framework.
553  string x_GetTrimmedTestName(const string& test_name);
554  /// Enable / disable all tests known to application
555  void x_EnableAllTests(bool enable);
556  /// Collect names and pointers to all tests existing in master test suite
557  void x_CollectAllTests();
558  /// Calculate the value from configuration file
559  bool x_CalcConfigValue(const string& value);
560 
561 
562 private:
563  /// Mode of running testing application
564  enum ERunMode {
565  fTestList = 0x1, ///< Only tests list is requested
566  fDisabled = 0x2, ///< All tests are disabled in configuration file
567  fInitFailed = 0x4 ///< Initialization user functions failed
568  };
569  typedef unsigned int TRunMode;
570 
571  /// If Run() was called or not
572  ///
573  /// @sa Run()
575  /// Mode of running the application
577  /// Lists of all user-defined functions
579  - eTestUserFuncFirst + 1];
580  /// Argument descriptions to be passed to SetArgDescriptions().
581  /// Value is not null only during NCBITEST_INIT_CMDLINE() function
583  /// Parser to evaluate expressions in configuration file.
584  /// Value is not null only during NCBITEST_INIT_VARIABLES() function
586  /// List of all test units mapped to their names.
588  /// List of all disabled tests
590  /// List of all tests which result is a timeout
592  /// List of all tests marked as in need of fixing in the future
594  /// List of all dependencies for each test having dependencies
596  /// Observer to make test dependencies and look for unit's timeouts
598  /// Boost reporter - must be pointer because Boost.Test calls free() on it
600  /// Boost logger - must be pointer because Boost.Test calls free() on it
602  /// Output stream for Boost.Test report
603  ofstream m_ReportOut;
604  /// Builder of internal accessible from library tests tree
606  /// Empty test case added to Boost for internal perposes
607  but::test_case* m_DummyTest;
608  /// Timeout for the whole test
609  double m_Timeout;
610  /// String representation for whole test timeout (real value taken from
611  /// CHECK_TIMEOUT in Makefile).
612  string m_TimeoutStr;
613  /// Multiplicator for timeouts
614  double m_TimeMult;
615  /// Timer measuring elapsed time for the whole test
617  /// Timeout that was set in currently executing unit before adjustment
618  ///
619  /// @sa AdjustTestTimeout()
620  unsigned int m_CurUnitTimeout;
621  /// Flag showing if there were some test errors
623  /// Flag showing if there were some timeouted tests
625 };
626 
627 
628 inline
630  : m_IsXML(false)
631 {}
632 
633 inline void
634 CNcbiBoostReporter::SetOutputFormat(but::output_format fmt)
635 {
636  if (fmt == but::OF_XML) {
637  m_IsXML = true;
638  m_Upper = new but::output::xml_report_formatter();
639  }
640  else {
641  m_IsXML = false;
642  m_Upper = new but::output::plain_report_formatter();
643  }
644 }
645 
646 inline
648  : m_IsXML(false)
649 {}
650 
651 inline void
653 {
654  if (format == but::OF_XML) {
655  m_IsXML = true;
656  m_Upper = new but::output::xml_log_formatter();
657  }
658  else {
659  m_IsXML = false;
660  m_Upper = new but::output::compiler_log_formatter();
661  }
662 }
663 
664 inline
666  : m_Parent (NULL),
667  m_TestUnit (tu),
668  m_OrderChanged(false)
669 {}
670 
672 {
674  delete *it;
675  }
676 }
677 
678 inline void
680 {
681  m_Children.push_back(element);
682  element->m_Parent = this;
683 }
684 
685 void
687  size_t idx_right)
688 {
689  size_t idx_left = 0;
690  for (; idx_left < m_Children.size(); ++ idx_left) {
691  if (m_Children[idx_left] == leftElem)
692  break;
693  }
694  _ASSERT(idx_left < m_Children.size());
695 
696  if (idx_left < idx_right)
697  return;
698 
699  m_OrderChanged = true;
700  m_Children.erase(m_Children.begin() + idx_left);
701  m_Children.insert(m_Children.begin() + idx_right, leftElem);
702 
703  ITERATE(TElemsSet, it, leftElem->m_MustLeft) {
704  x_EnsureChildOrder(*it, idx_right);
705  // If order is changed in the above call then leftElem will move to
706  // the right and we need to change our index.
707  while (m_Children[idx_right] != leftElem)
708  ++idx_right;
709  }
710 }
711 
712 void
714  CNcbiTestTreeElement* leftElem)
715 {
716  if (elem == leftElem) {
717  NCBI_THROW(CCoreException, eCore,
718  FORMAT("Circular dependency found: '"
719  << elem->m_TestUnit->p_name.get()
720  << "' must depend on itself."));
721  }
722  elem->m_MustLeft.insert(leftElem);
723 
724  ITERATE(TElemsSet, it, elem->m_MustRight) {
725  x_AddToMustLeft(*it, leftElem);
726  }
727 }
728 
729 void
731  CNcbiTestTreeElement* rightElem)
732 {
733  if (elem == rightElem) {
734  NCBI_THROW(CCoreException, eCore,
735  FORMAT("Circular dependency found: '"
736  << elem->m_TestUnit->p_name.get()
737  << "' must depend on itself."));
738  }
739  elem->m_MustRight.insert(rightElem);
740 
741  ITERATE(TElemsSet, it, elem->m_MustLeft) {
742  x_AddToMustRight(*it, rightElem);
743  }
744 }
745 
746 inline void
748  CNcbiTestTreeElement* rightElem)
749 {
750  x_AddToMustLeft(rightElem, leftElem);
751  x_AddToMustRight(leftElem, rightElem);
752 
753  size_t idx_right = 0;
754  for (; idx_right < m_Children.size(); ++idx_right) {
755  if (m_Children[idx_right] == rightElem)
756  break;
757  }
758  _ASSERT(idx_right < m_Children.size());
759 
760  x_EnsureChildOrder(leftElem, idx_right);
761 }
762 
763 void
765 {
766  TElemsList parents;
767 
768  CNcbiTestTreeElement* parElem = this;
769  if (m_TestUnit->p_type != but::TUT_SUITE) {
770  parElem = m_Parent;
771  }
772  do {
773  parents.push_back(parElem);
774  parElem = parElem->m_Parent;
775  }
776  while (parElem != NULL);
777 
778  parElem = from;
779  CNcbiTestTreeElement* fromElem = from;
780  do {
781  TElemsList::iterator it = find(parents.begin(), parents.end(), parElem);
782  if (it != parents.end()) {
783  break;
784  }
785  fromElem = parElem;
786  parElem = parElem->m_Parent;
787  }
788  while (parElem != NULL);
789  _ASSERT(parElem);
790 
791  if (parElem == this) {
792  NCBI_THROW(CCoreException, eCore,
793  FORMAT("Error in unit tests setup: dependency of '"
794  << m_TestUnit->p_name.get() << "' from '"
795  << from->m_TestUnit->p_name.get()
796  << "' can never be implemented."));
797  }
798 
799  CNcbiTestTreeElement* toElem = this;
800  while (toElem->m_Parent != parElem) {
801  toElem = toElem->m_Parent;
802  }
803 
804  parElem->x_EnsureChildOrder(fromElem, toElem);
805 }
806 
807 void
809 {
810  if (m_OrderChanged) {
811  but::test_suite* suite = static_cast<but::test_suite*>(m_TestUnit);
813  suite->remove((*it)->m_TestUnit->p_id);
814  }
816  suite->add((*it)->m_TestUnit);
817  }
818  }
819 
821  (*it)->FixUnitsOrder();
822  }
823 }
824 
825 inline but::test_unit*
827 {
828  return m_TestUnit;
829 }
830 
831 inline CNcbiTestTreeElement*
833 {
834  return m_Parent;
835 }
836 
838  : m_RootElem(NULL),
839  m_CurElem (NULL)
840 {}
841 
843 {
844  delete m_RootElem;
845 }
846 
847 bool
848 CNcbiTestsTreeBuilder::test_suite_start(but::test_suite const& suite)
849 {
850  but::test_suite* nc_suite = const_cast<but::test_suite*>(&suite);
851  if (m_RootElem) {
852  CNcbiTestTreeElement* next_elem = new CNcbiTestTreeElement(nc_suite);
853  m_CurElem->AddChild(next_elem);
854  m_CurElem = next_elem;
855  }
856  else {
857  m_RootElem = new CNcbiTestTreeElement(nc_suite);
859  }
860  m_AllUnits[nc_suite] = m_CurElem;
861  return true;
862 }
863 
864 void
865 CNcbiTestsTreeBuilder::test_suite_finish(but::test_suite const& suite)
866 {
867  _ASSERT(m_CurElem->GetTestUnit() == &static_cast<const but::test_unit&>(suite));
869 }
870 
871 void
872 CNcbiTestsTreeBuilder::visit(but::test_case const& test)
873 {
874  but::test_case* nc_test = const_cast<but::test_case*>(&test);
875  CNcbiTestTreeElement* elem = new CNcbiTestTreeElement(nc_test);
876  m_CurElem->AddChild(elem);
877  m_AllUnits[nc_test] = elem;
878 }
879 
880 inline void
881 CNcbiTestsTreeBuilder::EnsureDep(but::test_unit* tu, but::test_unit* tu_from)
882 {
883  CNcbiTestTreeElement* elem = m_AllUnits[tu];
884  CNcbiTestTreeElement* elem_from = m_AllUnits[tu_from];
885  _ASSERT(elem && elem_from);
886  elem->EnsureDep(elem_from);
887 }
888 
889 inline void
891 {
892  if (m_RootElem) {
894  }
895 }
896 
897 // List of memory chunks to delete at exit
899 
901 {
904  }
906 }
907 
909 {
910  for (auto& x : s_TestMemoryCleanupList->m_List) {
911  free(x);
912  }
913  m_List.clear();
914 }
915 
917  m_List.push_back(ptr);
918 }
919 
920 
921 
923 
924 inline
926  : m_RunCalled(false),
927  m_RunMode (0),
928  m_DummyTest(NULL),
929  m_Timeout (0),
930  m_TimeMult (1),
931  m_Timer (CStopWatch::eStart),
932  m_HasTestErrors(false),
933  m_HasTestTimeouts(false)
934 {
936  m_Logger = new CNcbiBoostLogger();
937 }
938 
940 {
941  if (m_ReportOut.good())
942  but::results_reporter::set_stream(cerr);
943 }
944 
945 /// Application for unit tests
946 static CNcbiTestApplication&
948 {
949  if (!s_TestApp) {
951  }
952  return *s_TestApp;
953 }
954 
955 void
957 {
959  m_ArgDescrs->AddFlag("-help",
960  "Print test framework related command line arguments");
961 #ifndef NCBI_COMPILER_WORKSHOP
962  m_ArgDescrs->AddOptionalKey("-run_test", "Filter",
963  "Allows to filter which test units to run",
965 #endif
966  m_ArgDescrs->AddFlag("dryrun",
967  "Do not actually run tests, just print list of all available tests.");
968  m_ArgDescrs->SetUsageContext(GetArguments().GetProgramBasename(), "NCBI unit test");
972 }
973 
974 int
976 {
977  m_RunCalled = true;
978  return 0;
979 }
980 
981 int
983 {
984  m_RunCalled = true;
985  m_RunMode |= fTestList;
986  but::results_reporter::set_level(but::DETAILED_REPORT);
987  return 0;
988 }
989 
990 inline void
992 {
993  m_UserFuncs[func_type].push_back(func);
994 }
995 
996 inline void
997 CNcbiTestApplication::AddTestDependsOn(but::test_unit* tu, but::test_unit* dep_tu)
998 {
999  m_TestDeps[tu].insert(dep_tu);
1000 }
1001 
1002 inline void
1004 {
1005  if (CONFIGURED_FILTERS.empty()) {
1006  s_SetEnabled(*tu, false);
1007  m_DisabledTests.insert(tu);
1008  }
1009 }
1010 
1011 inline CArgDescriptions*
1013 {
1014  return m_ArgDescrs.get();
1015 }
1016 
1017 inline CExprParser*
1019 {
1020  return m_IniParser.get();
1021 }
1022 
1023 inline but::test_case*
1025 {
1026  return m_DummyTest;
1027 }
1028 
1029 inline bool
1031 {
1032  return (m_RunMode & fInitFailed) != 0;
1033 }
1034 
1035 string
1037 {
1038  string new_name = test_name;
1039  SIZE_TYPE pos = NStr::Find(new_name, "::", NStr::eCase, NStr::eReverseSearch);
1040  if (pos != NPOS) {
1041  new_name = new_name.substr(pos + 2);
1042  }
1043  if(NStr::StartsWith(new_name, "test_", NStr::eNocase)) {
1044  new_name = new_name.substr(5);
1045  }
1046  else if(NStr::StartsWith(new_name, "test", NStr::eNocase)) {
1047  new_name = new_name.substr(4);
1048  }
1049  return new_name;
1050 }
1051 
1052 inline void
1054 {
1055  const string unit_name = x_GetTrimmedTestName(tu->p_name.get());
1056  if (unit_name == kDummyTestCaseName) {
1057  return;
1058  }
1059  string test_name(unit_name);
1060  int index = 0;
1061  for (;;) {
1062  but::test_unit*& tu_val = m_AllTests[test_name];
1063  if (!tu_val) {
1064  tu_val = tu;
1065  if (test_name != unit_name) {
1066  ERR_POST_X(3, Info << "Duplicate name found: '" << unit_name
1067  << "' - renamed to '" << test_name << "'");
1068  tu->p_name.set(test_name);
1069  }
1070  break;
1071  }
1072  test_name = unit_name;
1073  test_name += "_";
1074  test_name += NStr::IntToString(++index);
1075  }
1076 }
1077 
1078 inline void
1080 {
1082  but::test_unit* test = it->first;
1083  ITERATE(TUnitsSet, dep_it, it->second) {
1084  but::test_unit* dep_test = *dep_it;
1085  m_TreeBuilder.EnsureDep(test, dep_test);
1086  }
1087  }
1089 }
1090 
1091 inline void
1093 {
1094 #if BOOST_VERSION >= 105900
1095  // Expedite run status initialization so s_IsEnabled will work.
1096  auto master_id = but::framework::master_test_suite().p_id;
1097  auto& state = but::framework::impl::s_frk_state();
1098  state.finalize_default_run_status(master_id, but::test_unit::RS_INVALID);
1099  state.deduce_run_status(master_id);
1100 #endif
1102  but::test_unit* test = it->first;
1103  if (!m_DisabledTests.count(test) && !s_IsEnabled(*test)) {
1104  continue;
1105  }
1106  ITERATE(TUnitsSet, dep_it, it->second) {
1107  but::test_unit* dep_test = *dep_it;
1108  if (!m_DisabledTests.count(dep_test) && !s_IsEnabled(*dep_test)) {
1109  continue;
1110  }
1111  test->depends_on(dep_test);
1112  }
1113  }
1114 }
1115 
1116 /// Helper macro to check if NCBI preprocessor flag was defined empty or
1117 /// equal to 1.
1118 /// Macro expands to true if flag was defined empty or equal to 1 and to false
1119 /// if it was defined to something else or wasn't defined at all.
1120 #define IS_FLAG_DEFINED(flag) \
1121  BOOST_PP_TUPLE_ELEM(2, 1, IS_FLAG_DEFINED_I(BOOST_PP_CAT(NCBI_, flag)))
1122 #define IS_VAR_DEFINED(var) \
1123  BOOST_PP_TUPLE_ELEM(2, 1, IS_FLAG_DEFINED_I(var))
1124 #define IS_FLAG_DEFINED_I(flag) \
1125  (BOOST_PP_CAT(IS_FLAG_DEFINED_II_, flag) (), false)
1126 #define IS_FLAG_DEFINED_II_() \
1127  BOOST_PP_NIL, true) BOOST_PP_TUPLE_EAT(2) (BOOST_PP_NIL
1128 #define IS_FLAG_DEFINED_II_1() \
1129  BOOST_PP_NIL, true) BOOST_PP_TUPLE_EAT(2) (BOOST_PP_NIL
1130 
1131 /// List of features that will be converted to unittest variables
1132 /// (checking testsuite environment variable $FEATURES).
1133 /// If you would like to add some new veriables here, please
1134 /// see Unix configure utility and Project Tree Builder for full
1135 /// list of supported values.
1136 /// @note
1137 /// All non alphanumeric charecters in the names replaced with "_" symbol.
1138 static const char* s_NcbiFeatures[] = {
1139  // Features
1140  "AIX",
1141  "BSD",
1142  "CompaqCompiler",
1143  "Cygwin",
1144  "CygwinMT",
1145  "DLL",
1146  "DLL_BUILD",
1147  "Darwin",
1148  "GCC",
1149  "ICC",
1150  "IRIX",
1151  "KCC",
1152  "Linux",
1153  "MIPSpro",
1154  "MSVC",
1155  "MSWin",
1156  "MT",
1157  "MacOS",
1158  "Ncbi_JNI", // Ncbi-JNI
1159  "OSF",
1160  "PubSeqOS",
1161  "SRAT_internal", // SRAT-internal
1162  "Solaris",
1163  "VisualAge",
1164  "WinMain",
1165  "WorkShop",
1166  "XCODE",
1167  "in_house_resources", // in-house-resources
1168  "full_blastdb", // full-blastdb
1169  "full_test_data", // full-test-data
1170  "unix",
1171 
1172  // Packages
1173  "BZ2",
1174  "BerkeleyDB",
1175  "BerkeleyDB__", // BerkeleyDB++
1176  "Boost_Regex", // Boost.Regex
1177  "Boost_Spirit", // Boost.Spirit
1178  "Boost_Test", // Boost.Test
1179  "Boost_Test_Included", // Boost.Test.Included
1180  "Boost_Threads", // Boost.Threads
1181  "C_Toolkit", // C-Toolkit
1182  "CPPUNIT",
1183  "C_ncbi",
1184  "DBLib",
1185  "EXPAT",
1186  "FLTK",
1187  "FUSE",
1188  "Fast_CGI", // Fast-CGI
1189  "FreeTDS",
1190  "FreeType",
1191  "GIF",
1192  "GLUT",
1193  "GNUTLS",
1194  "HDF5",
1195  "ICU",
1196  "JPEG",
1197  "LIBXML",
1198  "LIBXSLT",
1199  "LZO",
1200  "LocalBZ2",
1201  "LocalMSGMAIL2",
1202  "LocalNCBILS",
1203  "LocalPCRE",
1204  "LocalSSS",
1205  "LocalZ",
1206  "MAGIC",
1207  "MESA",
1208  "MUPARSER",
1209  "MySQL",
1210  "NCBILS2",
1211  "ODBC",
1212  "OECHEM",
1213  "OPENSSL",
1214  "ORBacus",
1215  "OpenGL",
1216  "PCRE",
1217  "PNG",
1218  "PYTHON",
1219  "PYTHON23",
1220  "PYTHON24",
1221  "PYTHON25",
1222  "SABLOT",
1223  "SGE",
1224  "SP",
1225  "SQLITE",
1226  "SQLITE3",
1227  "SQLITE3ASYNC",
1228  "SSSDB",
1229  "SSSUTILS",
1230  "Sybase",
1231  "SybaseCTLIB",
1232  "SybaseDBLIB",
1233  "TIFF",
1234  "UNGIF",
1235  "UUID",
1236  "XPM",
1237  "Xalan",
1238  "Xerces",
1239  "Z",
1240  "wx2_8", // wx2.8
1241  "wxWidgets",
1242  "wxWindows",
1243 
1244  // Projects
1245  "algo",
1246  "app",
1247  "bdb",
1248  "cgi",
1249  "connext",
1250  "ctools",
1251  "dbapi",
1252  "gbench",
1253  "gui",
1254  "objects",
1255  "serial"
1256 };
1257 
1258 
1259 inline void
1261 {
1262  m_IniParser->AddSymbol("COMPILER_Clang", IS_FLAG_DEFINED(COMPILER_ANY_CLANG));
1263  m_IniParser->AddSymbol("COMPILER_Compaq", IS_FLAG_DEFINED(COMPILER_COMPAQ));
1264  m_IniParser->AddSymbol("COMPILER_Cray", IS_FLAG_DEFINED(COMPILER_CRAY));
1265  m_IniParser->AddSymbol("COMPILER_GCC", IS_FLAG_DEFINED(COMPILER_GCC));
1266  m_IniParser->AddSymbol("COMPILER_ICC", IS_FLAG_DEFINED(COMPILER_ICC));
1267  m_IniParser->AddSymbol("COMPILER_KCC", IS_FLAG_DEFINED(COMPILER_KCC));
1268  m_IniParser->AddSymbol("COMPILER_LLVM", IS_VAR_DEFINED(__llvm__));
1269  m_IniParser->AddSymbol("COMPILER_MipsPro", IS_FLAG_DEFINED(COMPILER_MIPSPRO));
1270  m_IniParser->AddSymbol("COMPILER_MSVC", IS_FLAG_DEFINED(COMPILER_MSVC));
1271  m_IniParser->AddSymbol("COMPILER_VisualAge", IS_FLAG_DEFINED(COMPILER_VISUALAGE));
1272  m_IniParser->AddSymbol("COMPILER_WorkShop", IS_FLAG_DEFINED(COMPILER_WORKSHOP));
1273 
1274  m_IniParser->AddSymbol("OS_AIX", IS_FLAG_DEFINED(OS_AIX));
1275  m_IniParser->AddSymbol("OS_BSD", IS_FLAG_DEFINED(OS_BSD));
1276  m_IniParser->AddSymbol("OS_Cygwin", IS_FLAG_DEFINED(OS_CYGWIN));
1277  m_IniParser->AddSymbol("OS_MacOSX", IS_FLAG_DEFINED(OS_DARWIN));
1278  m_IniParser->AddSymbol("OS_Irix", IS_FLAG_DEFINED(OS_IRIX));
1279  m_IniParser->AddSymbol("OS_Linux", IS_FLAG_DEFINED(OS_LINUX));
1280  m_IniParser->AddSymbol("OS_MacOS", IS_FLAG_DEFINED(OS_MAC));
1281  m_IniParser->AddSymbol("OS_Windows", IS_FLAG_DEFINED(OS_MSWIN));
1282  m_IniParser->AddSymbol("OS_Tru64", IS_FLAG_DEFINED(OS_OSF1));
1283  m_IniParser->AddSymbol("OS_Solaris", IS_FLAG_DEFINED(OS_SOLARIS));
1285 
1286  m_IniParser->AddSymbol("PLATFORM_Bits32", NCBI_PLATFORM_BITS == 32);
1287  m_IniParser->AddSymbol("PLATFORM_Bits64", NCBI_PLATFORM_BITS == 64);
1288 
1289  m_IniParser->AddSymbol("PLATFORM_BigEndian", IS_VAR_DEFINED(WORDS_BIGENDIAN));
1290  m_IniParser->AddSymbol("PLATFORM_LittleEndian", !IS_VAR_DEFINED(WORDS_BIGENDIAN));
1291 
1292  m_IniParser->AddSymbol("BUILD_Dll", IS_FLAG_DEFINED(DLL_BUILD));
1293  m_IniParser->AddSymbol("BUILD_Static", !IS_FLAG_DEFINED(DLL_BUILD));
1294 
1295  m_IniParser->AddSymbol("BUILD_Debug", IS_VAR_DEFINED(_DEBUG));
1296  m_IniParser->AddSymbol("BUILD_Release", !IS_VAR_DEFINED(_DEBUG));
1297 
1298 
1299  // Add variables based on features available in the build
1300 
1301  string features_str = NCBI_GetBuildFeatures();
1302  if (features_str.empty()) {
1303  return;
1304  }
1305  // Split $FEATURES to tokens
1306  list<string> features_list;
1307  NStr::Split(features_str, " ", features_list, NStr::fSplit_Tokenize);
1308  // Convert list<> to set<> to speed up a search
1309  typedef set<string> TFeatures;
1310  TFeatures features;
1311  // For all features
1312  ITERATE(list<string>, it, features_list) {
1313  // Replace all non alphanumeric characters in the names with "_".
1314  // Ignore negative features (with first "-" characters)
1315  string f = *it;
1316  if (f[0] != '-') {
1317  NON_CONST_ITERATE (string, fit, f) {
1318  if (!isalnum((unsigned char)(*fit))) {
1319  *fit = '_';
1320  }
1321  }
1322  // Add feature name
1323  features.insert(f);
1324  }
1325  }
1326  // Add FEATURE_* variables
1327  for (size_t i = 0; i < sizeof(s_NcbiFeatures) / sizeof(s_NcbiFeatures[0]); i++) {
1328  string name("FEATURE_");
1329  name += s_NcbiFeatures[i];
1330  TFeatures::const_iterator it = features.find(s_NcbiFeatures[i]);
1331  bool found = (it != features.end());
1332  m_IniParser->AddSymbol(name.c_str(), found);
1333  }
1334 
1335  // Is it running from TeamCity?
1337  ("TeamCity",
1338  !CNcbiEnvironment().Get("TEAMCITY_PROJECT_NAME").empty());
1339 }
1340 
1341 
1342 inline bool
1344 {
1345  m_IniParser->Parse(value.c_str());
1346  const CExprValue& expr_res = m_IniParser->GetResult();
1347  if (expr_res.GetType() == CExprValue::eBOOL && !expr_res.GetBool()) {
1348  return false;
1349  }
1350  return true;
1351 }
1352 
1353 
1354 void
1356 {
1357  if (s_GetTestApp().IsInitFailed()) {
1358  but::results_collector.test_unit_aborted(*s_GetTestApp().GetDummyTest());
1359  }
1360 }
1361 
1362 
1363 void
1365 {
1366  m_RunMode |= fDisabled;
1367 
1368  // This should certainly go to the output. So we can use only printf,
1369  // nothing else.
1370  printf("All tests are disabled in current configuration.\n"
1371  " (for autobuild scripts: NCBI_UNITTEST_DISABLED)\n");
1372  x_AddDummyTest();
1373 }
1374 
1375 void
1377 {
1378  m_RunMode |= fDisabled;
1379 
1380  // This should certainly go to the output. So we can use only printf,
1381  // nothing else.
1382  printf("Tests cannot be executed in current configuration and will be skipped.\n"
1383  " (for autobuild scripts: NCBI_UNITTEST_SKIPPED)\n");
1384 }
1385 
1386 inline void
1388 {
1389  if (!m_DummyTest) {
1390  m_DummyTest = BOOST_TEST_CASE(&DUMMY_TEST_FUNCTION_NAME);
1391  but::framework::master_test_suite().add(m_DummyTest);
1392  }
1393 }
1394 
1395 inline bool
1397 {
1401  return false;
1402  }
1404  list<string> reg_entries;
1406 
1407  // Disable tests ...
1408  ITERATE(list<string>, it, reg_entries) {
1409  const string& test_name = *it;
1410  string reg_value = registry.Get(kTestsDisableSectionName, test_name);
1411 
1413  if (x_CalcConfigValue(reg_value)) {
1415  }
1416  continue;
1417  }
1418  but::test_unit* tu = GetTestUnit(test_name);
1419  if (tu) {
1420  if (x_CalcConfigValue(reg_value)) {
1421  SetTestDisabled(tu);
1422  }
1423  }
1424  else {
1425  ERR_POST_X(2, Warning << "Invalid test case name: '" << test_name << "'");
1426  }
1427  }
1428 
1429  reg_entries.clear();
1431  // Put tests into "to-fix" list
1432  ITERATE(list<string>, it, reg_entries) {
1433  const string& test_name = *it;
1434  string reg_value = registry.Get(kTestsToFixSectionName, test_name);
1435 
1436  but::test_unit* tu = GetTestUnit(test_name);
1437  if (tu) {
1438  if (x_CalcConfigValue(reg_value)) {
1439  m_ToFixTests.insert(tu);
1440  }
1441  }
1442  else {
1443  ERR_POST_X(4, Warning << "Invalid test case name: '" << test_name << "'");
1444  }
1445  }
1446 
1447  reg_entries.clear();
1449  // Adjust timeouts of test units
1450  ITERATE(list<string>, it, reg_entries) {
1451  const string& test_name = *it;
1452  string reg_value = registry.Get(kTestsTimeoutSectionName, test_name);
1453 
1454  but::test_unit* tu = GetTestUnit(test_name);
1455  if (tu) {
1456  list<CTempString> koef_lst;
1457  NStr::Split(reg_value, ";", koef_lst);
1458  ITERATE(list<CTempString>, it_koef, koef_lst) {
1459  CTempString koef_str, koef_cond;
1460  if (NStr::SplitInTwo(*it_koef, ":", koef_str, koef_cond)) {
1461  if (x_CalcConfigValue(koef_cond)) {
1463  tu->p_timeout.set(Uint4(tu->p_timeout.get() * koef));
1464  break;
1465  }
1466  }
1467  else {
1468  ERR_POST_X(6, "Bad format of TIMEOUT_MULT string: '" << reg_value << "'");
1469  break;
1470  }
1471  }
1472  }
1473  else {
1474  ERR_POST_X(5, Warning << "Invalid test case name: '" << test_name << "'");
1475  }
1476  }
1477  return true;
1478 }
1479 
1480 void
1482 {
1484  but::test_unit* tu = it->second;
1485  if (tu->p_type == but::TUT_CASE) {
1486  s_SetEnabled(*tu, enable);
1487  /*
1488  For full correctness this functionality should exist but it
1489  can't be made now. So if test suite will be disabled by user
1490  then it will not be possible to get list of tests inside this
1491  suite to be included in the report.
1492 
1493  if (enable && tu->p_type == but::TUT_SUITE) {
1494  but::results_collector.results(tu->p_id).p_skipped = false;
1495  }
1496  */
1497  }
1498  }
1499 }
1500 
1501 inline void
1503 {
1504  bool need_run = !(m_RunMode & (fTestList + fDisabled));
1505  if (need_run && !x_CallUserFuncs(eTestUserFuncInit)) {
1507  need_run = false;
1508  }
1509  // fDisabled property can be changed in initialization functions
1510  if (m_RunMode & fDisabled)
1511  need_run = false;
1512 
1513  if (need_run) {
1514  x_EnsureAllDeps();
1515  x_ActualizeDeps();
1516  }
1517  else {
1518  x_EnableAllTests(false);
1519  if (m_RunMode & fInitFailed) {
1520  x_AddDummyTest();
1521  }
1522  }
1523 }
1524 
1525 inline void
1527 {
1530 }
1531 
1532 inline void
1534 {
1535  x_EnableAllTests(true);
1536 
1537  // Disabled tests can accidentally become not included in full list if
1538  // they were disabled in initialization
1540  s_SetEnabled(**it, true);
1541  }
1542 }
1543 
1544 inline void
1546 {
1547  // If equal then it's real timeout, if not then it's just this unit hit
1548  // the whole test timeout.
1549  if (tc->p_timeout.get() == m_CurUnitTimeout) {
1550  m_TimedOutTests.insert(tc);
1551  }
1552  m_HasTestTimeouts = true;
1553 }
1554 
1555 inline void
1557 {
1558  if (m_TimedOutTests.find(tc) == m_TimedOutTests.end())
1559  m_HasTestErrors = true;
1560 }
1561 
1562 void
1564 {
1565  m_CurUnitTimeout = tu->p_timeout.get();
1566  unsigned int new_timeout = (unsigned int)(m_CurUnitTimeout * m_TimeMult);
1567 
1568  if (m_Timeout != 0) {
1569  double elapsed = m_Timer.Elapsed();
1570  if (m_Timeout <= elapsed) {
1572  printf("Maximum execution time of %s seconds is exceeded", m_TimeoutStr.c_str());
1573 #if BOOST_VERSION < 105900
1574  throw but::test_being_aborted();
1575 #elif defined(SIGALRM)
1576  raise(SIGALRM);
1577 #else
1578  throw runtime_error("Maximum execution time of " + m_TimeoutStr + " seconds is exceeded");
1579 #endif
1580  }
1581  new_timeout = (unsigned int)(m_Timeout - elapsed);
1582  }
1583  if (m_CurUnitTimeout == 0 || m_CurUnitTimeout > new_timeout) {
1584  tu->p_timeout.set(new_timeout);
1585  }
1586 }
1587 
1588 string
1590 {
1591  string result;
1592  const but::test_results& tr = but::results_collector.results(tu->p_id);
1593 
1594  if (m_DisabledTests.count(tu) != 0 || (m_RunMode & fDisabled))
1596  else if (m_TimedOutTests.count(tu) != 0)
1598  else if (!tr.passed() && m_ToFixTests.find(tu) != m_ToFixTests.end())
1600  else if (tr.p_aborted)
1602  else if (tr.p_assertions_failed.get() > tr.p_expected_failures.get() ||
1603  tr.p_test_cases_failed.get() + tr.p_test_cases_aborted.get() > 0) {
1605  }
1606  else if ((m_RunMode & fTestList) || tr.p_skipped)
1608  else if( tr.passed() )
1610  else
1612 
1613  return result;
1614 }
1615 
1616 int
1618 {
1619  int result = 0;
1621  but::test_unit* tu = it->second;
1622  if (tu->p_type != but::TUT_CASE) {
1623  continue;
1624  }
1625  string str = GetTestResultString(tu);
1627  ++result;
1628  }
1629  }
1630  return result;
1631 }
1632 
1633 int
1635 {
1636  int result = 0;
1638  if (!but::results_collector.results((*it)->p_id).passed())
1639  ++result;
1640  }
1641  return result;
1642 }
1643 
1644 inline bool
1645 CNcbiTestApplication::IsTestToFix(const but::test_unit* tu)
1646 {
1647  return m_ToFixTests.find(const_cast<but::test_unit*>(tu)) != m_ToFixTests.end();
1648 }
1649 
1650 inline void
1652 {
1653  but::output_format format = RTCFG(but::output_format, REPORT_FORMAT,
1654  report_format);
1655 
1657  string is_autobuild = env.Get("NCBI_AUTOMATED_BUILD");
1658  if (! is_autobuild.empty()) {
1659  // There shouldn't be any message box in the automated build mode
1661 
1662  format = but::OF_XML;
1663  but::results_reporter::set_level(but::DETAILED_REPORT);
1664 
1665  string boost_rep = env.Get("NCBI_BOOST_REPORT_FILE");
1666  if (! boost_rep.empty()) {
1667  m_ReportOut.open(boost_rep.c_str());
1668  if (m_ReportOut.good()) {
1669  but::results_reporter::set_stream(m_ReportOut);
1670  }
1671  else {
1672  ERR_POST("Error opening Boost.Test report file '" << boost_rep << "'");
1673  }
1674  }
1675  }
1676 
1678  but::results_reporter::set_format(m_Reporter);
1679 
1680  m_Logger->SetOutputFormat(RTCFG(but::output_format, LOG_FORMAT, log_format));
1681  but::unit_test_log.set_formatter(m_Logger);
1682 }
1683 
1684 static const char*
1686 {
1687  switch (func_type) {
1688  case eTestUserFuncInit:
1689  return "NCBITEST_AUTO_INIT()";
1690  case eTestUserFuncFini:
1691  return "NCBITEST_AUTO_FINI()";
1692  case eTestUserFuncCmdLine:
1693  return "NCBITEST_INIT_CMDLINE()";
1694  case eTestUserFuncVars:
1695  return "NCBITEST_INIT_VARIABLES()";
1696  case eTestUserFuncDeps:
1697  return "NCBITEST_INIT_TREE()";
1698  default:
1699  return NULL;
1700  }
1701 }
1702 
1703 bool
1705 {
1706  ITERATE(TUserFuncsList, it, m_UserFuncs[func_type]) {
1707  try {
1708  (*it)();
1709  }
1710  catch (CException& e) {
1711  ERR_POST_X(1, "Exception in " << s_GetUserFuncName(func_type) << ": " << e);
1712  throw;
1713  //return false;
1714  }
1715  catch (exception& e) {
1716  ERR_POST_X(1, "Exception in " << s_GetUserFuncName(func_type) << ": " << e.what());
1717  throw;
1718  //return false;
1719  }
1720  }
1721  return true;
1722 }
1723 
1724 inline but::test_unit*
1726 {
1728  if (it == m_AllTests.end()) {
1729  NCBI_THROW(CCoreException, eInvalidArg,
1730  "Test unit '" + (string)test_name + "' not found.");
1731  }
1732  return it->second;
1733 }
1734 
1735 inline void
1737 {
1738  m_AllTests.clear();
1739  CNcbiTestsCollector collector;
1740  but::traverse_test_tree(but::framework::master_test_suite(), collector IGNORE_STATUS);
1741 }
1742 
1743 inline int
1745 {
1746  but::test_case_counter tcc;
1747  but::traverse_test_tree(but::framework::master_test_suite(), tcc IGNORE_STATUS);
1748  return (int)tcc.p_count;
1749 }
1750 
1751 but::test_suite*
1753 {
1754  // Do not detect memory leaks using msvcrt - this information is useless
1755  boost::debug::detect_memory_leaks(false);
1756  boost::debug::break_memory_alloc(0);
1757 
1759  but::framework::register_observer(m_Observer);
1760 
1761  // TODO: change this functionality to use only -dryrun parameter
1762  for (int i = 1; i < argc; ++i) {
1763  if (NStr::CompareCase(argv[i], "--do_not_run") == 0) {
1764  m_RunMode |= fTestList;
1765  but::results_reporter::set_level(but::DETAILED_REPORT);
1766 
1767  for (int j = i + 1; j < argc; ++j) {
1768  argv[j - 1] = argv[j];
1769  }
1770  --argc;
1771  }
1772  }
1773 
1775  m_TimeoutStr = env.Get("NCBI_CHECK_TIMEOUT");
1776  if (!m_TimeoutStr.empty()) {
1778  }
1779  if (m_Timeout == 0) {
1780  m_Timer.Stop();
1781  }
1782  else {
1783  m_Timeout = min(max(0.0, m_Timeout - 3), 0.9 * m_Timeout);
1784  }
1786 
1788  if (AppMain(argc, argv) == 0 && m_RunCalled) {
1790 
1791  but::traverse_test_tree(but::framework::master_test_suite(), m_TreeBuilder IGNORE_STATUS);
1792 
1793  // We do not read configuration if particular tests were given in
1794  // command line
1796  && (!CONFIGURED_FILTERS.empty() || x_ReadConfiguration()))
1797  {
1798  // Call should be doubled to support manual adding of
1799  // test cases inside NCBITEST_INIT_TREE().
1801 #if BOOST_VERSION <= 105900
1802  // As of Boost.Test 3.0 (Boost 1.59.0), this check is prone
1803  // to false positives.
1804  if (x_GetEnabledTestsCount() == 0) {
1806  }
1807 #endif
1808 #ifdef NCBI_COMPILER_WORKSHOP
1809  else if (!CONFIGURED_FILTERS.empty()) {
1810  printf("Parameter --run_test is not supported in current configuration\n");
1811  x_EnableAllTests(false);
1812  x_AddDummyTest();
1813  }
1814 #endif
1815  return NULL;
1816  }
1817  }
1818 
1819  // This path we'll be if something have gone wrong
1821  x_EnableAllTests(false);
1822 
1823  return NULL;
1824 }
1825 
1826 inline bool
1828 {
1829  return m_HasTestErrors;
1830 }
1831 
1832 inline bool
1834 {
1835  return m_HasTestTimeouts;
1836 }
1837 
1838 inline CNcbiRegistry&
1840 {
1841  return GetRWConfig();
1842 }
1843 
1844 inline ostream&
1846 {
1847  if (m_ReportOut.good()) {
1848  return NcbiCerr;
1849  } else {
1850  return but::results_reporter::get_stream();
1851  }
1852 }
1853 
1854 void
1855 CNcbiTestsCollector::visit(but::test_case const& test)
1856 {
1857  s_GetTestApp().CollectTestUnit(const_cast<but::test_case*>(&test));
1858 }
1859 
1860 bool
1861 CNcbiTestsCollector::test_suite_start(but::test_suite const& suite)
1862 {
1863  s_GetTestApp().CollectTestUnit(const_cast<but::test_suite*>(&suite));
1864  return true;
1865 }
1866 
1867 void
1869 {
1871 }
1872 
1873 void
1874 CNcbiTestsObserver::test_unit_start(but::test_unit const& tu)
1875 {
1876  s_GetTestApp().AdjustTestTimeout(const_cast<but::test_unit*>(&tu));
1877 }
1878 
1879 void
1880 CNcbiTestsObserver::test_unit_finish(but::test_unit const& tu, unsigned long elapsed)
1881 {
1882  unsigned long timeout = tu.p_timeout.get();
1883  // elapsed comes in microseconds
1884  if (timeout != 0 && timeout < elapsed / 1000000) {
1885  boost::execution_exception ex(
1886  boost::execution_exception::timeout_error, "Timeout exceeded"
1888  but::framework::exception_caught(ex);
1889  }
1890 
1891  but::test_results& tr = but::s_rc_impl().m_results_store[tu.p_id];
1892  if (!tr.passed() && s_GetTestApp().IsTestToFix(&tu)) {
1893  static_cast<but::readwrite_property<bool>& >(
1894  static_cast<but::class_property<bool>& >(tr.p_skipped)).set(true);
1895  static_cast<but::readwrite_property<but::counter_t>& >(
1896  static_cast<but::class_property<but::counter_t>& >(tr.p_assertions_failed)).set(0);
1897  }
1898 }
1899 
1900 void
1901 CNcbiTestsObserver::exception_caught(boost::execution_exception const& ex)
1902 {
1903  if (ex.code() == boost::execution_exception::timeout_error) {
1904  s_GetTestApp().SetTestTimedOut(const_cast<but::test_case*>(
1905  &but::framework::current_test_case()));
1906  }
1907  else {
1908  s_GetTestApp().SetTestErrored(const_cast<but::test_case*>(
1909  &but::framework::current_test_case()));
1910  }
1911 }
1912 
1913 void
1914 CNcbiTestsObserver::test_unit_aborted(but::test_unit const& tu)
1915 {
1916  s_GetTestApp().SetTestErrored((but::test_case*)&tu);
1917 }
1918 
1919 #if BOOST_VERSION >= 105900
1920 void CNcbiTestsObserver::assertion_result(but::assertion_result ar)
1921 {
1922  if (ar == but::AR_FAILED) {
1923  assertion_result(false);
1924  }
1925 }
1926 #endif
1927 
1928 void
1930 {
1931  if (!passed) {
1932  s_GetTestApp().SetTestErrored(const_cast<but::test_case*>(&but::framework::current_test_case()));
1933  // On any failed assetion set request context status to 500
1934  // We have the same for exceptions, see test_boost.hpp : BOOST_AUTO_TC_INVOKER()
1936  }
1937 }
1938 
1939 void
1941 {
1942  m_Indent = 0;
1944  m_Upper->results_report_start(ostr);
1945 }
1946 
1947 void
1949 {
1950  m_Upper->results_report_finish(ostr);
1951  if (m_IsXML) {
1952  ostr << endl;
1953  }
1954 }
1955 
1956 void
1958  ostream& ostr)
1959 {
1960  if (tu.p_name.get() == kDummyTestCaseName) {
1961  return;
1962  }
1963  string descr = s_GetTestApp().GetTestResultString(const_cast<but::test_unit*>(&tu));
1964 
1965  if (m_IsXML) {
1966  ostr << '<' << (tu.p_type == but::TUT_CASE ? "TestCase" : "TestSuite")
1967  << " name" << but::attr_value() << tu.p_name.get()
1968  << " result" << but::attr_value() << descr;
1969  ostr << '>';
1970  }
1971  else {
1972  ostr << std::setw( m_Indent ) << ""
1973  << "Test " << (tu.p_type == but::TUT_CASE ? "case " : "suite " )
1974  << "\"" << tu.p_name << "\" " << descr;
1975  ostr << '\n';
1976  m_Indent += 2;
1977  }
1978 }
1979 
1980 void
1981 CNcbiBoostReporter::test_unit_report_finish(but::test_unit const& tu, std::ostream& ostr)
1982 {
1983  if (tu.p_name.get() == kDummyTestCaseName) {
1984  return;
1985  }
1986  m_Indent -= 2;
1987  m_Upper->test_unit_report_finish(tu, ostr);
1988 }
1989 
1990 void
1991 CNcbiBoostReporter::do_confirmation_report(but::test_unit const& tu, std::ostream& ostr)
1992 {
1993 #if BOOST_VERSION >= 105900
1994  if (tu.p_type == but::TUT_SUITE && tu.p_line_num == 0) {
1995  but::test_results const& tr = but::results_collector.results(tu.p_id);
1996 
1997  if ( !m_IsXML ) {
1998  if (tr.p_test_cases_skipped > 0) {
1999  ostr << "*** Skipped " << tr.p_test_cases_skipped << " test(s)\n";
2000  } else if (tr.p_skipped) {
2001  ostr << "*** Skipped some tests\n";
2002  }
2003  }
2004  // Boost.Test 3.x (from Boost 1.59+) treats skipped tests as errors.
2005  // Override that treatment both here (to avoid a claim that errors
2006  // occurred) and in main (to yield a sane exit code regardless of
2007  // report level).
2008  const_cast<bool&>(tr.p_skipped.get()) = false;
2009  const_cast<but::counter_t&>(tr.p_test_cases_skipped.get()) = 0;
2010  }
2011 #endif
2012  m_Upper->do_confirmation_report(tu, ostr);
2013 }
2014 
2015 
2016 void
2017 CNcbiBoostLogger::log_start(ostream& ostr, but::counter_t test_cases_amount)
2018 {
2019  m_Upper->log_start(ostr, test_cases_amount);
2020 }
2021 
2022 void
2023 CNcbiBoostLogger::log_finish(ostream& ostr)
2024 {
2025  m_Upper->log_finish(ostr);
2026  if (!m_IsXML) {
2027  ostr << "Executed " << s_GetTestApp().GetRanTestsCount() << " test cases";
2028  int to_fix = s_GetTestApp().GetToFixTestsCount();
2029  if (to_fix != 0) {
2030  ostr << " (" << to_fix << " to fix)";
2031  }
2032  ostr << "." << endl;
2033  }
2034 }
2035 
2036 #if BOOST_VERSION >= 107000
2037 void
2038 CNcbiBoostLogger::log_build_info(ostream& ostr, bool log_build_info)
2039 {
2040  m_Upper->log_build_info(ostr, log_build_info);
2041 }
2042 #else
2043 void
2044 CNcbiBoostLogger::log_build_info(ostream& ostr)
2045 {
2046  m_Upper->log_build_info(ostr);
2047 }
2048 #endif
2049 
2050 void
2051 CNcbiBoostLogger::test_unit_start(ostream& ostr, but::test_unit const& tu)
2052 {
2053  m_Upper->test_unit_start(ostr, tu);
2054 }
2055 
2056 void
2057 CNcbiBoostLogger::test_unit_finish(ostream& ostr, but::test_unit const& tu,
2058  unsigned long elapsed)
2059 {
2060  m_Upper->test_unit_finish(ostr, tu, elapsed);
2061 }
2062 
2063 void
2064 CNcbiBoostLogger::test_unit_skipped(ostream& ostr, but::test_unit const& tu)
2065 {
2066  m_Upper->test_unit_skipped(ostr, tu);
2067 }
2068 
2069 #if BOOST_VERSION >= 105900
2070 void
2071 CNcbiBoostLogger::log_exception_start(ostream& ostr,
2072  but::log_checkpoint_data const& lcd,
2073  boost::execution_exception const& ex)
2074 {
2075  m_Upper->log_exception_start(ostr, lcd, ex);
2076 }
2077 
2078 void
2079 CNcbiBoostLogger::log_exception_finish(ostream& ostr)
2080 {
2081  m_Upper->log_exception_finish(ostr);
2082 }
2083 #elif BOOST_VERSION >= 104200
2084 void
2085 CNcbiBoostLogger::log_exception(ostream& ostr, but::log_checkpoint_data const& lcd,
2086  boost::execution_exception const& ex)
2087 {
2088  m_Upper->log_exception(ostr, lcd, ex);
2089 }
2090 #else
2091 void
2092 CNcbiBoostLogger::log_exception(ostream& ostr, but::log_checkpoint_data const& lcd,
2093  but::const_string explanation)
2094 {
2095  m_Upper->log_exception(ostr, lcd, explanation);
2096 }
2097 #endif
2098 
2099 void
2100 CNcbiBoostLogger::log_entry_start(ostream& ostr, but::log_entry_data const& led, log_entry_types let)
2101 {
2102  m_Upper->log_entry_start(ostr, led, let);
2103 }
2104 
2105 void
2106 CNcbiBoostLogger::log_entry_value(ostream& ostr, but::const_string value)
2107 {
2108  m_Upper->log_entry_value(ostr, value);
2109 }
2110 
2111 void
2112 CNcbiBoostLogger::log_entry_finish(ostream& ostr)
2113 {
2114  m_Upper->log_entry_finish(ostr);
2115 }
2116 
2117 #if BOOST_VERSION >= 105900
2118 void CNcbiBoostLogger::entry_context_start(ostream& ostr, but::log_level l)
2119 {
2120  m_Upper->entry_context_start(ostr, l);
2121 }
2122 
2123 # if BOOST_VERSION >= 106500
2124 void CNcbiBoostLogger::log_entry_context(ostream& ostr,
2125  but::log_level l,
2126  but::const_string value)
2127 {
2128  m_Upper->log_entry_context(ostr, l, value);
2129 }
2130 
2131 void CNcbiBoostLogger::entry_context_finish(ostream& ostr, but::log_level l)
2132 {
2133  m_Upper->entry_context_finish(ostr, l);
2134 }
2135 # else
2136 void CNcbiBoostLogger::log_entry_context(ostream& ostr, but::const_string value)
2137 {
2138  m_Upper->log_entry_context(ostr, value);
2139 }
2140 
2141 void CNcbiBoostLogger::entry_context_finish (ostream& ostr)
2142 {
2143  m_Upper->entry_context_finish(ostr);
2144 }
2145 # endif
2146 #endif
2147 
2148 void
2149 RegisterNcbiTestUserFunc(TNcbiTestUserFunction func,
2150  ETestUserFuncType func_type)
2151 {
2152  s_GetTestApp().AddUserFunction(func, func_type);
2153 }
2154 
2155 void
2156 NcbiTestDependsOn(but::test_unit* tu, but::test_unit* dep_tu)
2157 {
2158  s_GetTestApp().AddTestDependsOn(tu, dep_tu);
2159 }
2160 
2161 void
2162 NcbiTestDisable(but::test_unit* tu)
2163 {
2164  s_GetTestApp().SetTestDisabled(tu);
2165 }
2166 
2167 void
2168 NcbiTestSetGlobalDisabled(void)
2169 {
2170  s_GetTestApp().SetGloballyDisabled();
2171 }
2172 
2173 void
2174 NcbiTestSetGlobalSkipped(void)
2175 {
2176  s_GetTestApp().SetGloballySkipped();
2177 }
2178 
2179 CNcbiApplication* NcbiTestGetAppInstance(void)
2180 {
2181  return &s_GetTestApp();
2182 }
2183 
2184 CNcbiRegistry& NcbiTestGetRWConfig(void)
2185 {
2186  return s_GetTestApp().GetTestRWConfig();
2187 }
2188 
2189 CExprParser*
2190 NcbiTestGetIniParser(void)
2191 {
2192  return s_GetTestApp().GetIniParser();
2193 }
2194 
2195 CArgDescriptions*
2196 NcbiTestGetArgDescrs(void)
2197 {
2198  return s_GetTestApp().GetArgDescrs();
2199 }
2200 
2201 but::test_unit*
2202 NcbiTestGetUnit(CTempString test_name)
2203 {
2204  return s_GetTestApp().GetTestUnit(test_name);
2205 }
2206 
2207 
2208 END_NCBI_SCOPE
2209 
2210 
2211 using namespace but;
2212 
2213 static int s_NcbiArgc;
2214 static char** s_NcbiArgv;
2215 
2216 /// Global initialization function called from Boost framework
2217 test_suite*
2218 init_unit_test_suite(int argc, char** argv)
2219 {
2220  if (s_NcbiArgc > 0) {
2221  argc = s_NcbiArgc;
2222  argv = s_NcbiArgv;
2223  }
2224  return NCBI_NS_NCBI::s_GetTestApp().InitTestFramework(argc, argv);
2225 }
2226 
2227 
2228 // Note: including of a cpp file is unfortunate however there is no
2229 // possibility to add it into the Makefile. Both files, test_boost.cpp
2230 // and teamcity_boost.cpp include some boost header files which in turn
2231 // have some implemented functions. Having them in two compilation units
2232 // result in broken linkage.
2233 //
2234 // Note 2: teamcity_boost.cpp uses BOOST_GLOBAL_FIXTURE() which installs
2235 // teamcity formatters if the tests are executed under teamcity.
2236 #include "teamcity_boost.cpp"
2237 
2238 
2239 // This main() is based on a unification of code from various Boost versions'
2240 // unit_test_main.ipp, matching 1.60.0's where reasonably possible.
2241 int
2242 main(int argc, char* argv[])
2243 {
2244  int result_code = boost::exit_success;
2245  bool made_report = false;
2246 
2247  std::ostream* ostr = &NcbiCerr;
2248 
2250 #if BOOST_VERSION >= 106000
2251  std::vector<char*> boost_args(1, argv[0]), ncbi_args;
2252  for (int i = 0; i < argc; ++i) {
2253  NCBI_NS_NCBI::CTempString s(argv[i]);
2254  if (NCBI_NS_NCBI::NStr::StartsWith(s, "--")) {
2255  boost_args.push_back(argv[i]);
2256  } else if (s.size() == 2 && s[0] == '-'
2257  && s[1] >= 'a' && s[1] <= 'z') {
2258  boost_args.push_back(argv[i]);
2259  if (i + 1 < argc && argv[i+1][0] != '-') {
2260  boost_args.push_back(argv[++i]);
2261  }
2262  } else {
2263  ncbi_args.push_back(argv[i]);
2264  }
2265  }
2266  s_NcbiArgc = (int)ncbi_args.size();
2267  s_NcbiArgv = ncbi_args.data();
2268  framework::init(&init_unit_test_suite, (int)boost_args.size(), boost_args.data());
2269 #else
2270  framework::init(&init_unit_test_suite, argc, argv);
2271 #endif
2272 
2274 
2276 #if BOOST_VERSION >= 105900
2277  if( RTCFG(bool, WAIT_FOR_DEBUGGER, wait_for_debugger) ) {
2278  *ostr << "Press any key to continue..." << std::endl;
2279 
2280  std::getchar();
2281  *ostr << "Continuing..." << std::endl;
2282  }
2283  framework::finalize_setup_phase();
2284  output_format list_cont = RTCFG(output_format, LIST_CONTENT, list_content);
2285  if( list_cont != but::OF_INVALID ) {
2286  if( list_cont == but::OF_DOT ) {
2287  ut_detail::dot_content_reporter reporter( results_reporter::get_stream() );
2288  traverse_test_tree( framework::master_test_suite().p_id, reporter, true );
2289  }
2290  else {
2291  ut_detail::hrf_content_reporter reporter( results_reporter::get_stream() );
2292  traverse_test_tree( framework::master_test_suite().p_id, reporter, true );
2293  }
2294  return boost::exit_success;
2295  }
2296 
2297  if( RTCFG(bool, LIST_LABELS, list_labels) ) {
2298  ut_detail::labels_collector collector;
2299  traverse_test_tree( framework::master_test_suite().p_id, collector, true );
2300  *ostr << "Available labels:\n ";
2301  std::copy( collector.labels().begin(), collector.labels().end(),
2302  std::ostream_iterator<std::string>( *ostr, "\n " ) );
2303  *ostr << "\n";
2304  return boost::exit_success;
2305  }
2306 #else
2307  if( !runtime_config::test_to_run().is_empty() ) {
2308  test_case_filter filter( runtime_config::test_to_run() );
2309  traverse_test_tree( framework::master_test_suite().p_id, filter );
2310  }
2311 #endif
2312  framework::run();
2313 #if BOOST_VERSION < 106700
2314  results_reporter::make_report();
2315 #endif
2316  made_report = true;
2317 
2318  if (
2319 #if BOOST_VERSION >= 106000
2320  RTCFG(bool, RESULT_CODE, result_code)
2321 #else
2322  !runtime_config::no_result_code()
2323 #endif
2324  ) {
2325 #if BOOST_VERSION >= 105900
2326  // Boost.Test 3.x (from Boost 1.59+) treats skipped tests
2327  // as errors. Override that treatment both here (to yield
2328  // a sane exit code regardless of report level) and in
2329  // CNcbiBoostReporter::do_confirmation_report (to avoid a
2330  // claim that errors occurred).
2331  but::test_results const& tr
2332  = but::results_collector.results(
2333  framework::master_test_suite().p_id);
2334  const_cast<bool&>(tr.p_skipped.get()) = false;
2335  const_cast<but::counter_t&>(tr.p_test_cases_skipped.get()) = 0;
2336 #endif
2337  result_code = results_collector.results( framework::master_test_suite().p_id ).result_code();
2340  {
2341  // This should certainly go to the output. So we can use only
2342  // printf, nothing else.
2343  printf("There were no test failures, only timeouts.\n"
2344  " (for autobuild scripts: NCBI_UNITTEST_TIMEOUTS_BUT_NO_ERRORS)\n");
2345  }
2346  }
2347 
2348  }
2349 #if BOOST_VERSION >= 106000
2350  BOOST_TEST_I_CATCH( framework::nothing_to_test, ex ) {
2351  result_code = ex.m_result_code;
2352  }
2353 #elif BOOST_VERSION >= 104200
2354  BOOST_TEST_I_CATCH0( framework::nothing_to_test ) {
2355  result_code = boost::exit_success;
2356  }
2357 #endif
2358  BOOST_TEST_I_CATCH( framework::internal_error, ex ) {
2359  *ostr << "Boost.Test framework internal error: " << ex.what()
2360  << std::endl;
2361  result_code = boost::exit_exception_failure;
2362  }
2363  BOOST_TEST_I_CATCH( framework::setup_error, ex ) {
2364  *ostr << "Test setup error: " << ex.what() << std::endl;
2365  result_code = boost::exit_exception_failure;
2366  }
2367  BOOST_TEST_I_CATCH( std::exception, ex ) {
2368  *ostr << "Test framework error: " << ex.what() << std::endl;
2369  result_code = boost::exit_exception_failure;
2370  }
2372  *ostr << "Boost.Test framework internal error: unknown reason"
2373  << std::endl;
2374  result_code = boost::exit_exception_failure;
2375  }
2376  // Report results now if an exception precluded doing so earlier.
2377  if ( !made_report ) {
2378  results_reporter::make_report();
2379  }
2380 
2381 #if BOOST_VERSION >= 105900
2382  framework::shutdown();
2383 #endif
2384 
2385  delete NCBI_NS_NCBI::s_TestApp;
2387 
2389  return result_code;
2390 }
2391 
2392 // Provide 'wmain()' too, and convert cmdline args from UNICODE to UTF-8.
2393 #if defined(NCBI_OS_MSWIN) && defined(_UNICODE)
2394 int NcbiSys_main(int argc, ncbi::TXChar* argv[])
2395 {
2396  std::vector<std::string> args_storage(argc);
2397  std::vector<char*> args(argc);
2398  for (int i = 0; i < argc; ++i) {
2399  args_storage[i] = ncbi::CUtf8::AsUTF8(argv[i]);
2400  args[i] = const_cast<char*>(args_storage[i].c_str());
2401  }
2402  return main(argc, args.data());
2403 }
2404 #endif
#define false
Definition: bool.h:36
CArgDescriptions –.
Definition: ncbiargs.hpp:541
CCoreException –.
Definition: ncbiexpt.hpp:1476
void Parse(const char *str)
Definition: expr.cpp:738
CExprSymbol * AddSymbol(const char *name, VT value)
Definition: expr.hpp:382
const CExprValue & GetResult(void) const
Definition: expr.hpp:289
@ eDenyAutoVar
Definition: expr.hpp:278
bool GetBool(void) const
Definition: expr.hpp:135
EValue GetType(void) const
Definition: expr.hpp:75
@ eBOOL
Definition: expr.hpp:70
Logger for embedding in Boost framework and adding non-standard information to logging given by Boost...
Definition: test_boost.cpp:235
virtual void test_unit_skipped(ostream &ostr, but::test_unit const &tu)
virtual ~CNcbiBoostLogger(void)
Definition: test_boost.cpp:238
bool m_IsXML
If report is XML or not.
Definition: test_boost.cpp:288
virtual void log_entry_value(ostream &ostr, but::const_string value)
virtual void log_exception(ostream &ostr, but::log_checkpoint_data const &lcd, but::const_string explanation)
virtual void log_start(ostream &ostr, but::counter_t test_cases_amount)
virtual void log_build_info(ostream &ostr)
virtual void log_entry_start(ostream &ostr, but::log_entry_data const &led, log_entry_types let)
virtual void test_unit_finish(ostream &ostr, but::test_unit const &tu, unsigned long elapsed)
void SetOutputFormat(but::output_format format)
Setup logger tuned for printing log of specific format.
Definition: test_boost.cpp:652
virtual void test_unit_start(ostream &ostr, but::test_unit const &tu)
AutoPtr< TBoostLogFormatter > m_Upper
Standard logger from Boost for particular report format.
Definition: test_boost.cpp:286
virtual void log_entry_finish(ostream &ostr)
virtual void log_finish(ostream &ostr)
Reporter for embedding in Boost framework and adding non-standard information to detailed report give...
Definition: test_boost.cpp:204
virtual void results_report_finish(ostream &ostr)
void SetOutputFormat(but::output_format format)
Setup reporter tuned for printing report of specific format.
Definition: test_boost.cpp:634
int m_Indent
Current indentation level in plain text report.
Definition: test_boost.cpp:228
virtual ~CNcbiBoostReporter(void)
Definition: test_boost.cpp:207
virtual void test_unit_report_start(but::test_unit const &tu, ostream &ostr)
bool m_IsXML
If report is XML or not.
Definition: test_boost.cpp:226
virtual void do_confirmation_report(but::test_unit const &tu, ostream &ostr)
AutoPtr< TBoostRepFormatter > m_Upper
Standard reporter from Boost for particular report format.
Definition: test_boost.cpp:224
virtual void results_report_start(ostream &ostr)
virtual void test_unit_report_finish(but::test_unit const &tu, ostream &ostr)
CNcbiEnvironment –.
Definition: ncbienv.hpp:104
CNcbiRegistry –.
Definition: ncbireg.hpp:913
Application for all unit tests.
Definition: test_boost.cpp:454
int GetToFixTestsCount(void)
Get number of tests that were failed but are marked to be fixed.
bool m_RunCalled
If Run() was called or not.
Definition: test_boost.cpp:574
void x_EnableAllTests(bool enable)
Enable / disable all tests known to application.
bool HasTestErrors(void)
Check if there were any test errors.
string m_TimeoutStr
String representation for whole test timeout (real value taken from CHECK_TIMEOUT in Makefile).
Definition: test_boost.cpp:612
CExprParser * GetIniParser(void)
Get parser evaluating configuration conditions.
virtual int DryRun(void)
Test run the application.
Definition: test_boost.cpp:982
TStringToUnitMap m_AllTests
List of all test units mapped to their names.
Definition: test_boost.cpp:587
ofstream m_ReportOut
Output stream for Boost.Test report.
Definition: test_boost.cpp:603
list< TNcbiTestUserFunction > TUserFuncsList
Definition: test_boost.cpp:527
CNcbiRegistry & GetTestRWConfig(void)
Get the application's cached configuration parameters, accessible to read-write.
void AddUserFunction(TNcbiTestUserFunction func, ETestUserFuncType func_type)
Add user function.
Definition: test_boost.cpp:991
virtual void Init(void)
Initialize the application.
Definition: test_boost.cpp:956
AutoPtr< CArgDescriptions > m_ArgDescrs
Argument descriptions to be passed to SetArgDescriptions().
Definition: test_boost.cpp:582
AutoPtr< CExprParser > m_IniParser
Parser to evaluate expressions in configuration file.
Definition: test_boost.cpp:585
void x_AddDummyTest(void)
Add empty test necesary for internal purposes.
bool m_HasTestErrors
Flag showing if there were some test errors.
Definition: test_boost.cpp:622
ostream & GetFreeformReportStream(void) const
CNcbiTestsTreeBuilder m_TreeBuilder
Builder of internal accessible from library tests tree.
Definition: test_boost.cpp:605
TUnitsSet m_ToFixTests
List of all tests marked as in need of fixing in the future.
Definition: test_boost.cpp:593
TUnitToManyMap m_TestDeps
List of all dependencies for each test having dependencies.
Definition: test_boost.cpp:595
but::test_suite * InitTestFramework(int argc, char *argv[])
Initialize this application, main test suite and all test framework.
string GetTestResultString(but::test_unit *tu)
Get string representation of result of test execution.
void FiniTestsAfterRun(void)
Finalize test suite after running tests.
ERunMode
Mode of running testing application.
Definition: test_boost.cpp:564
@ fTestList
Only tests list is requested.
Definition: test_boost.cpp:565
@ fInitFailed
Initialization user functions failed.
Definition: test_boost.cpp:567
@ fDisabled
All tests are disabled in configuration file.
Definition: test_boost.cpp:566
void x_InitCommonParserVars(void)
Initialize common for all tests parser variables (OS*, COMPILER* and DLL_BUILD)
void x_SetupBoostReporters(void)
Setup our own reporter for Boost.Test.
void x_CollectAllTests()
Collect names and pointers to all tests existing in master test suite.
bool IsInitFailed(void)
Check if user initialization functions failed.
void InitTestsBeforeRun(void)
Initialize already prepared test suite before running tests.
unsigned int m_CurUnitTimeout
Timeout that was set in currently executing unit before adjustment.
Definition: test_boost.cpp:620
void x_EnsureAllDeps(void)
Ensure that all dependencies stand earlier in tests tree than their dependents.
void x_ActualizeDeps(void)
Set up real Boost.Test dependencies based on ones made by AddTestDependsOn().
unsigned int TRunMode
Definition: test_boost.cpp:569
void SetTestDisabled(but::test_unit *tu)
Set test as disabled by user.
void CollectTestUnit(but::test_unit *tu)
Save test unit in the collection of all tests.
double m_Timeout
Timeout for the whole test.
Definition: test_boost.cpp:609
int GetRanTestsCount(void)
Get number of actually executed tests.
void AddTestDependsOn(but::test_unit *tu, but::test_unit *dep_tu)
Add dependency for test unit.
Definition: test_boost.cpp:997
void SetTestErrored(but::test_case *tc)
Register the fact of test failure.
double m_TimeMult
Multiplicator for timeouts.
Definition: test_boost.cpp:614
void ReEnableAllTests(void)
Enable all necessary tests after execution but before printing report.
bool HasTestTimeouts(void)
Check if there were any timeouted tests.
bool x_CalcConfigValue(const string &value)
Calculate the value from configuration file.
but::test_case * m_DummyTest
Empty test case added to Boost for internal perposes.
Definition: test_boost.cpp:607
string x_GetTrimmedTestName(const string &test_name)
Apply standard trimmings to test name and return resultant test name which will identify test inside ...
void SetGloballyDisabled(void)
Set flag that all tests globally disabled.
bool IsTestToFix(const but::test_unit *tu)
Check if given test is marked as requiring fixing in the future.
void AdjustTestTimeout(but::test_unit *tu)
Check the correct setting for unit timeout and check overall test timeout.
int x_GetEnabledTestsCount(void)
Get number of tests which Boost will execute.
CNcbiBoostReporter * m_Reporter
Boost reporter - must be pointer because Boost.Test calls free() on it.
Definition: test_boost.cpp:599
void SetTestTimedOut(but::test_case *tc)
Mark test case as failed due to hit of the timeout.
TUnitsSet m_DisabledTests
List of all disabled tests.
Definition: test_boost.cpp:589
but::test_case * GetDummyTest(void)
Get pointer to empty test case added to Boost for internal purposes.
bool x_ReadConfiguration(void)
Enable / disable tests based on application configuration file.
bool x_CallUserFuncs(ETestUserFuncType func_type)
Call all user functions.
void SetGloballySkipped(void)
Set flag that all tests globally skipped.
CArgDescriptions * GetArgDescrs(void)
Get object with argument descriptions.
TRunMode m_RunMode
Mode of running the application.
Definition: test_boost.cpp:576
virtual int Run(void)
Run the application.
Definition: test_boost.cpp:975
CNcbiBoostLogger * m_Logger
Boost logger - must be pointer because Boost.Test calls free() on it.
Definition: test_boost.cpp:601
TUnitsSet m_TimedOutTests
List of all tests which result is a timeout.
Definition: test_boost.cpp:591
CNcbiTestsObserver m_Observer
Observer to make test dependencies and look for unit's timeouts.
Definition: test_boost.cpp:597
CStopWatch m_Timer
Timer measuring elapsed time for the whole test.
Definition: test_boost.cpp:616
but::test_unit * GetTestUnit(CTempString test_name)
Get pointer to test case or test suite by its name.
TUserFuncsList m_UserFuncs[eTestUserFuncLast - eTestUserFuncFirst+1]
Lists of all user-defined functions.
Definition: test_boost.cpp:579
bool m_HasTestTimeouts
Flag showing if there were some timeouted tests.
Definition: test_boost.cpp:624
CNcbiTestMemoryCleanupList – Define a list of pointers to free at exit.
Element of tests tree.
Definition: test_boost.cpp:339
~CNcbiTestTreeElement(void)
In destructor class destroys all its children.
Definition: test_boost.cpp:671
TElemsSet m_MustLeft
Elements that should be "on the left" from this element in tests tree (should have less index in the ...
Definition: test_boost.cpp:403
void AddChild(CNcbiTestTreeElement *element)
Add child element.
Definition: test_boost.cpp:679
TElemsSet m_MustRight
Elements that should be "on the right" from this element in tests tree (should have greater index in ...
Definition: test_boost.cpp:406
void x_AddToMustRight(CNcbiTestTreeElement *elem, CNcbiTestTreeElement *rightElem)
Definition: test_boost.cpp:730
but::test_unit * GetTestUnit(void)
Get unit represented by the element.
Definition: test_boost.cpp:826
void x_EnsureChildOrder(CNcbiTestTreeElement *leftElem, CNcbiTestTreeElement *rightElem)
Ensure that leftElem and rightElem (or element pointed by it_right inside m_Children) are in that ver...
Definition: test_boost.cpp:747
vector< CNcbiTestTreeElement * > TElemsList
Definition: test_boost.cpp:378
CNcbiTestTreeElement * m_Parent
Parent element in tests tree.
Definition: test_boost.cpp:394
void x_AddToMustLeft(CNcbiTestTreeElement *elem, CNcbiTestTreeElement *leftElem)
Add leftElem (rightElem) in the list of elements that should be "lefter" ("righter") in the tests tre...
Definition: test_boost.cpp:713
TElemsList m_Children
Children of the element in tests tree.
Definition: test_boost.cpp:400
bool m_OrderChanged
If order of children was changed during checking dependencies.
Definition: test_boost.cpp:398
CNcbiTestTreeElement & operator=(const CNcbiTestTreeElement &)
void EnsureDep(CNcbiTestTreeElement *from)
Ensure good dependency of this element on "from" element.
Definition: test_boost.cpp:764
void FixUnitsOrder(void)
Fix order of unit tests in the subtree rooted in this element.
Definition: test_boost.cpp:808
CNcbiTestTreeElement(but::test_unit *tu)
Element represents one test unit.
Definition: test_boost.cpp:665
CNcbiTestTreeElement(const CNcbiTestTreeElement &)
Prohibit.
set< CNcbiTestTreeElement * > TElemsSet
Definition: test_boost.cpp:379
CNcbiTestTreeElement * GetParent(void)
Get parent element in tests tree.
Definition: test_boost.cpp:832
but::test_unit * m_TestUnit
Unit represented by the element.
Definition: test_boost.cpp:396
Class that can walk through all tree of tests and register them inside CNcbiTestApplication.
Definition: test_boost.cpp:327
virtual bool test_suite_start(but::test_suite const &suite)
virtual void visit(but::test_case const &test)
virtual ~CNcbiTestsCollector(void)
Definition: test_boost.cpp:329
Special observer to embed in Boost.Test framework to initialize test dependencies before they started...
Definition: test_boost.cpp:295
virtual void test_unit_finish(but::test_unit const &tu, unsigned long elapsed)
Method called after execution of each unit.
virtual void exception_caught(boost::execution_exception const &ex)
Method called when some exception was caught during execution of unit.
virtual void test_finish(void)
Method called before execution of all tests.
virtual ~CNcbiTestsObserver(void)
Definition: test_boost.cpp:297
virtual void test_unit_start(but::test_unit const &tu)
Method called before execution of each unit.
virtual void test_unit_aborted(but::test_unit const &tu)
Method called when some check fails during execution of unit.
virtual void assertion_result(bool passed)
Class for traversing all Boost tests tree and building tree structure in our own accessible manner.
Definition: test_boost.cpp:413
virtual void test_suite_finish(but::test_suite const &suite)
Definition: test_boost.cpp:865
CNcbiTestTreeElement * m_CurElem
Element in tests tree representing started but not yet finished test suite, i.e.
Definition: test_boost.cpp:445
void EnsureDep(but::test_unit *tu, but::test_unit *tu_from)
Ensure good dependency of the tu test unit on tu_from test unit.
Definition: test_boost.cpp:881
CNcbiTestTreeElement * m_RootElem
Root element of the tests tree.
Definition: test_boost.cpp:441
map< but::test_unit *, CNcbiTestTreeElement * > TUnitToElemMap
Definition: test_boost.cpp:438
virtual ~CNcbiTestsTreeBuilder(void)
Definition: test_boost.cpp:842
virtual bool test_suite_start(but::test_suite const &suite)
Definition: test_boost.cpp:848
TUnitToElemMap m_AllUnits
Overall map of relations between test units and their representatives in elements tree.
Definition: test_boost.cpp:448
virtual void visit(but::test_case const &test)
Definition: test_boost.cpp:872
void FixUnitsOrder(void)
Fix order of unit tests in the whole tree of tests.
Definition: test_boost.cpp:890
static void Destroy(CSafeStaticLifeSpan::ELifeLevel level)
Explicitly destroy all on-demand variables up to a specified level.
@ eLifeLevel_AppMain
Destroyed in CNcbiApplication::AppMain, if possible.
CStopWatch –.
Definition: ncbitime.hpp:1938
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:65
IRegistry –.
Definition: ncbireg.hpp:73
const_iterator end() const
Definition: map.hpp:152
iterator_bool insert(const value_type &val)
Definition: map.hpp:165
void clear()
Definition: map.hpp:169
const_iterator find(const key_type &key) const
Definition: map.hpp:153
iterator_bool insert(const value_type &val)
Definition: set.hpp:149
const_iterator find(const key_type &key) const
Definition: set.hpp:137
const_iterator end() const
Definition: set.hpp:136
static CMemoryRegistry registry
Definition: cn3d_tools.cpp:81
char value[7]
Definition: config.c:431
static void DLIST_NAME() init(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:40
void SetAppFlags(TAppFlags flags)
const CNcbiRegistry & GetConfig(void) const
Get the application's cached configuration parameters (read-only).
int AppMain(int argc, const char *const *argv, const char *const *envp=0, EAppDiagStream diag=eDS_Default, const char *conf=NcbiEmptyCStr, const string &name=NcbiEmptyString)
Main function (entry point) for the NCBI application.
Definition: ncbiapp.cpp:799
virtual void SetupArgDescriptions(CArgDescriptions *arg_desc)
Setup the command line argument descriptions.
Definition: ncbiapp.cpp:1175
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
element_type * get(void) const
Get pointer.
Definition: ncbimisc.hpp:469
CNcbiRegistry & GetRWConfig(void)
Get the application's cached configuration parameters, accessible for read-write for an application's...
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
Definition: ncbimisc.hpp:822
const CNcbiArguments & GetArguments(void) const
Get the application's cached unprocessed command-line arguments.
element_type * release(void)
Release will release ownership of pointer to caller.
Definition: ncbimisc.hpp:472
void AddFlag(const string &name, const string &comment, CBoolEnum< EFlagValue > set_value=eFlagHasValueIfSet, TFlags flags=0)
Add description for flag argument.
Definition: ncbiargs.cpp:2459
void SetUsageContext(const string &usage_name, const string &usage_description, bool usage_sort_args=false, SIZE_TYPE usage_width=78)
Set extra info to be used by PrintUsage().
Definition: ncbiargs.cpp:3299
void AddOptionalKey(const string &name, const string &synopsis, const string &comment, EType type, TFlags flags=0)
Add description for optional key without default value.
Definition: ncbiargs.cpp:2427
@ fMandatorySeparator
Require '=' separator.
Definition: ncbiargs.hpp:659
@ eString
An arbitrary string.
Definition: ncbiargs.hpp:589
#define NULL
Definition: ncbistd.hpp:225
#define OS_UNIX
Definition: ncbilcl.hpp:59
#define OS_MSWIN
Definition: ncbilcl.hpp:63
CDiagContext & GetDiagContext(void)
Get diag context instance.
Definition: logging.cpp:818
static CRequestContext & GetRequestContext(void)
Shortcut to CDiagContextThreadData::GetThreadData().GetRequestContext()
Definition: ncbidiag.cpp:1901
void SetRequestStatus(int status)
void SetExitCode(int exit_code)
Set exit code.
Definition: ncbidiag.hpp:2176
#define ERR_POST_X(err_subcode, message)
Error posting with default error code and given error subcode.
Definition: ncbidiag.hpp:550
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
Definition: ncbidiag.hpp:186
const string & Get(const string &name, bool *found=NULL) const
Get environment value by name.
Definition: ncbienv.cpp:109
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
void Warning(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1191
virtual const char * what(void) const noexcept
Standard report (includes full backlog).
Definition: ncbiexpt.cpp:342
#define FORMAT(message)
Format message using iostreams library.
Definition: ncbiexpt.hpp:672
void Info(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1185
uint32_t Uint4
4-byte (32-bit) unsigned integer
Definition: ncbitype.h:103
virtual const string & Get(const string &section, const string &name, TFlags flags=0) const
Get the parameter value.
Definition: ncbireg.cpp:262
virtual void EnumerateEntries(const string &section, list< string > *entries, TFlags flags=fAllLayers) const
Enumerate parameter names for a specified section.
Definition: ncbireg.cpp:514
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define NcbiCerr
Definition: ncbistre.hpp:544
NCBI_NS_STD::string::size_type SIZE_TYPE
Definition: ncbistr.hpp:132
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
Definition: ncbistr.cpp:3457
char TXChar
Definition: ncbistr.hpp:172
static double StringToDouble(const CTempStringEx str, TStringToNumFlags flags=0)
Convert string to double.
Definition: ncbistr.cpp:1387
#define NPOS
Definition: ncbistr.hpp:133
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5083
static SIZE_TYPE Find(const CTempString str, const CTempString pattern, ECase use_case=eCase, EDirection direction=eForwardSearch, SIZE_TYPE occurrence=0)
Find the pattern in the string.
Definition: ncbistr.cpp:2887
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
Definition: ncbistr.hpp:5411
static bool SplitInTwo(const CTempString str, const CTempString delim, string &str1, string &str2, TSplitFlags flags=0)
Split a string into two pieces using the specified delimiters.
Definition: ncbistr.cpp:3550
static int CompareCase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-sensitive compare of a substring with another string.
Definition: ncbistr.cpp:135
@ fAllowTrailingSpaces
Ignore trailing space characters.
Definition: ncbistr.hpp:297
@ fConvErr_NoThrow
Do not throw an exception on error.
Definition: ncbistr.hpp:285
@ fAllowLeadingSpaces
Ignore leading spaces in converted string.
Definition: ncbistr.hpp:294
@ fSplit_Tokenize
All delimiters are merged and trimmed, to get non-empty tokens only.
Definition: ncbistr.hpp:2508
@ eReverseSearch
Search in a backward direction.
Definition: ncbistr.hpp:1947
@ eNocase
Case insensitive compare.
Definition: ncbistr.hpp:1206
@ eCase
Case sensitive compare.
Definition: ncbistr.hpp:1205
CAutoInitializeStaticFastMutex g_NcbiTestMutex
Definition: test_boost.cpp:149
void(* TNcbiTestUserFunction)(void)
Type of user-defined function which will be automatically registered in test framework.
ETestUserFuncType
Types of functions that user can define.
std::list< void * > m_List
static CNcbiTestMemoryCleanupList * GetInstance()
Definition: test_boost.cpp:900
@ eTestUserFuncInit
@ eTestUserFuncCmdLine
@ eTestUserFuncFirst
@ eTestUserFuncFini
@ eTestUserFuncLast
@ eTestUserFuncVars
@ eTestUserFuncDeps
#define STATIC_FAST_MUTEX_INITIALIZER
Determine type of system mutex initialization.
Definition: ncbimtx.hpp:492
double Elapsed(void) const
Return time elapsed since first Start() or last Restart() call (in seconds).
Definition: ncbitime.hpp:2776
void Stop(void)
Suspend the timer.
Definition: ncbitime.hpp:2793
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
Definition of all error codes used in corelib (xncbi.lib).
int i
yy_size_t n
constexpr bool empty(list< Ts... >) noexcept
Static variables safety - create on demand, destroy on application termination.
@ fSuppress_All
void SuppressSystemMessageBox(TSuppressSystemMessageBox mode=fSuppress_Default)
Suppress popup messages on execution errors.
Defines the CNcbiApplication and CAppException classes for creating NCBI applications.
#define NcbiSys_main
Definition: ncbiapp.hpp:48
Defines access to miscellaneous global configuration settings.
const char * NCBI_GetBuildFeatures(void)
Get list of enabled features and packages, delimited by spaces.
double NCBI_GetCheckTimeoutMult(void)
Get multiplier for timeouts which depends on speed of the machine and tools application is running un...
#define NCBI_PLATFORM_BITS
Definition: ncbiconf_msvc.h:96
int isalnum(Uchar c)
Definition: ncbictype.hpp:62
Defines unified interface to application:
Miscellaneous common-use basic types and functionality.
T max(T x_, T y_)
T min(T x_, T y_)
static Format format
Definition: njn_ioutil.cpp:53
void copy(Njn::Matrix< S > *matrix_, const Njn::Matrix< T > &matrix0_)
Definition: njn_matrix.hpp:613
double f(double x_, const double &y_)
Definition: njn_root.hpp:188
static const char * str(char *buf, int n)
Definition: stats.c:84
int test(int srctype, const void *srcdata, int srclen, int dsttype, int dstlen)
Definition: t0019.c:43
#define _DEBUG
static char test_name[128]
Definition: utf8_2.c:34
#define _ASSERT
#define BOOST_TEST_I_CATCHALL()
Definition: test_boost.cpp:118
#define TUT_SUITE
Definition: test_boost.cpp:92
const char * kDummyTestCaseName
Definition: test_boost.cpp:183
static char ** s_NcbiArgv
const char * kTestsTimeoutSectionName
Definition: test_boost.cpp:179
int main(int argc, char *argv[])
static const char * s_NcbiFeatures[]
List of features that will be converted to unittest variables (checking testsuite environment variabl...
const char * kTestConfigGlobalValue
Definition: test_boost.cpp:180
map< but::test_unit *, TUnitsSet > TUnitToManyMap
Definition: test_boost.cpp:197
static CNcbiTestApplication * s_TestApp
Definition: test_boost.cpp:922
but::results_reporter::format TBoostRepFormatter
Definition: test_boost.cpp:194
const char * kTestResultDisabled
Definition: test_boost.cpp:190
static bool s_IsEnabled(const but::test_unit &tu)
Definition: test_boost.cpp:167
const char * kTestsToFixSectionName
Definition: test_boost.cpp:178
const char * kTestResultPassed
Definition: test_boost.cpp:185
#define TUT_CASE
Definition: test_boost.cpp:91
static CNcbiTestMemoryCleanupList * s_TestMemoryCleanupList
Definition: test_boost.cpp:898
#define BOOST_TEST_I_CATCH0(type)
Definition: test_boost.cpp:117
#define CONFIGURED_FILTERS
Definition: test_boost.cpp:123
#define IS_FLAG_DEFINED(flag)
Helper macro to check if NCBI preprocessor flag was defined empty or equal to 1.
const char * kTestsDisableSectionName
Definition: test_boost.cpp:177
but::unit_test_log_formatter TBoostLogFormatter
Definition: test_boost.cpp:195
#define BOOST_TEST_I_CATCH(type, ex)
Definition: test_boost.cpp:116
const char * kTestResultAborted
Definition: test_boost.cpp:188
#define IS_VAR_DEFINED(var)
const char * kTestResultSkipped
Definition: test_boost.cpp:189
const char * kTestResultToFix
Definition: test_boost.cpp:191
const char * kTestResultFailed
Definition: test_boost.cpp:186
#define BOOST_TEST_I_TRY
Definition: test_boost.cpp:115
static const char * s_GetUserFuncName(ETestUserFuncType func_type)
#define OF_XML
Definition: test_boost.cpp:90
#define DUMMY_TEST_FUNCTION_NAME
Definition: test_boost.cpp:182
set< but::test_unit * > TUnitsSet
Definition: test_boost.cpp:196
#define RTCFG(type, new_name, old_name)
Definition: test_boost.cpp:108
test_suite * init_unit_test_suite(int argc, char **argv)
Global initialization function called from Boost framework.
const char * kTestResultTimeout
Definition: test_boost.cpp:187
#define IGNORE_STATUS
Definition: test_boost.cpp:93
static int s_NcbiArgc
static void s_SetEnabled(but::test_unit &tu, bool enabled)
Definition: test_boost.cpp:172
map< string, but::test_unit * > TStringToUnitMap
Definition: test_boost.cpp:198
static CNcbiTestApplication & s_GetTestApp(void)
Application for unit tests.
Definition: test_boost.cpp:947
Utility stuff for more convenient using of Boost.Test library.
#define NCBI_BOOST_LOCATION()
Definition: test_boost.hpp:289
else result
Definition: token2.c:20
static HENV env
Definition: transaction2.c:38
static const char *const features[]
void free(voidpf ptr)
Modified on Sat Dec 02 09:19:36 2023 by modify_doxy.py rev. 669887