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