Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/UnitTest/TUTSuite.cpp
4 : : \copyright 2012-2015 J. Bakosi,
5 : : 2016-2018 Los Alamos National Security, LLC.,
6 : : 2019-2021 Triad National Security, LLC.,
7 : : 2022-2024 J. Bakosi
8 : : All rights reserved. See the LICENSE file for details.
9 : : \brief Template Unit Test suite class definition
10 : : \details Template Unit Test suite class definition. In principle there can
11 : : be unit test suites other than this one which uses the Template Unit Test
12 : : library.
13 : : */
14 : : // *****************************************************************************
15 : :
16 : : #include <iostream>
17 : : #include <utility>
18 : : #include <map>
19 : :
20 : : #include "NoWarning/tut_runner.hpp"
21 : :
22 : : #include "TUTSuite.hpp"
23 : : #include "TUTTest.hpp"
24 : : #include "Print.hpp"
25 : :
26 : : #include "NoWarning/unittest.decl.h"
27 : :
28 : : extern CProxy_Main mainProxy;
29 : :
30 : : namespace unittest {
31 : :
32 : : extern tut::test_runner_singleton g_runner;
33 : : extern int g_maxTestsInGroup;
34 : :
35 : : } // unittest::
36 : :
37 : : using unittest::TUTSuite;
38 : :
39 : 2 : TUTSuite::TUTSuite( const std::string& grp ) :
40 : 2 : m_group2run( grp ),
41 : 2 : m_nrun( 0 ),
42 : 2 : m_ngroup( 0 ),
43 : 2 : m_ncomplete( 0 ),
44 : 2 : m_nfail( 0 ),
45 : 2 : m_nskip( 0 ),
46 : 2 : m_nwarn( 0 ),
47 : 2 : m_nexcp( 0 ),
48 [ + - ][ + - ]: 16 : m_nspaw( 0 )
[ - + ][ + + ]
[ + + ][ + + ]
[ + - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
49 : : // *****************************************************************************
50 : : // Constructor
51 : : //! \param[in] grp Test group to run
52 : : // *****************************************************************************
53 : : {
54 [ + - ]: 2 : const auto& groups = g_runner.get().list_groups();
55 : :
56 : : // If only select groups to be run, see if there is any that will run
57 : : bool work = false;
58 [ + + ][ - + ]: 3 : if (grp.empty() ||
59 : : std::any_of( groups.cbegin(), groups.cend(), [&]( const std::string& g ) {
60 : : return g.find(grp) != std::string::npos; } ))
61 : : {
62 : : work = true;
63 : : }
64 : :
65 : : if (!work) { // Quit if there is no work to be done
66 [ - - ][ - - ]: 0 : tk::Print() << "\nNo test groups match '" + grp + "'.\n";
67 [ - - ]: 0 : mainProxy.finalize( false );
68 : : }
69 [ + - ][ - - ]: 6 : }
[ - - ]
70 : :
71 : : void
72 : 2 : TUTSuite::run()
73 : : // *****************************************************************************
74 : : // Run all tests
75 : : // *****************************************************************************
76 : : {
77 [ + - ]: 2 : tk::Print().unithead( "Running unit tests", m_group2run );
78 : :
79 : 2 : const auto& groups = g_runner.get().list_groups();
80 : :
81 : : // Fire up all tests in all groups using the Charm++ runtime system
82 [ + + ]: 50 : for (const auto& g : groups) {
83 [ + + ]: 48 : if (m_group2run.empty()) { // consider all test groups
84 [ + - ]: 24 : spawngrp( g );
85 [ + + ]: 24 : } else if (g.find(m_group2run) != std::string::npos) {
86 [ + - ]: 1 : spawngrp( g ); // spawn groups configured
87 : : }
88 : : }
89 : 2 : }
90 : :
91 : : void
92 : 25 : TUTSuite::spawngrp( const std::string& g )
93 : : // *****************************************************************************
94 : : // Fire up all tests in a test group
95 : : //! \param[in] g Name of the test group
96 : : // *****************************************************************************
97 : : {
98 [ + + ]: 25 : ++m_ngroup; // increase number of test groups to run
99 : :
100 : : // Add up number of additionally-spawned tests (this is so we know how many
101 : : // to expect results from)
102 : : const auto it = m_nspawned.find( g );
103 [ + + ]: 25 : if (it != m_nspawned.end()) m_nspaw += it->second;
104 : :
105 : : // Asynchronously fire up all tests in test group
106 [ + + ]: 2525 : for (int t=1; t<=g_maxTestsInGroup; ++t) {
107 : : if (m_fromPE0.count(g)) {
108 : 100 : CProxy_TUTTest< CProxy_TUTSuite >::ckNew( thisProxy, g, t, 0 );
109 : : } else {
110 : 2400 : CProxy_TUTTest< CProxy_TUTSuite >::ckNew( thisProxy, g, t );
111 : : }
112 : : }
113 : 25 : }
114 : :
115 : : void
116 : 2527 : TUTSuite::evaluateTest( std::vector< std::string >&& status )
117 : : // *****************************************************************************
118 : : // Evaluate a unit test
119 : : //! \param[in] status Vector strings containing the test results. See
120 : : //! unittest::TUTTest constructor for the expected structure of status.
121 : : // *****************************************************************************
122 : : {
123 : : // Increase number tests run (including dummies)
124 : 2527 : ++m_nrun;
125 : :
126 : : // Evaluate test
127 [ + + ]: 2527 : if (status[2] != "8") { // only care about non-dummy tests
128 : 365 : ++m_ncomplete; // count number of tests completed
129 [ - + ]: 365 : if (status[2] == "3") // count number of tests with a warning
130 : 0 : ++m_nwarn;
131 [ + + ]: 365 : else if (status[2] == "7") // count number of skipped tests
132 : 103 : ++m_nskip;
133 [ - + ]: 262 : else if (status[2] == "2") // count number of tests throwing
134 : 0 : ++m_nexcp;
135 [ - + ]: 262 : else if (status[2] != "0") // count number of failed tests
136 : 0 : ++m_nfail;
137 : : }
138 : :
139 : : // Echo one-liner info on result of test
140 : 2527 : tk::Print().test( m_ncomplete, m_nfail, status );
141 : :
142 : : // Wait for all tests to finish, then quit
143 [ + + ]: 2527 : if (m_nrun == m_ngroup*static_cast<std::size_t>(g_maxTestsInGroup) + m_nspaw)
144 : : {
145 : 2 : auto pass = assess();
146 : 2 : mainProxy.finalize( pass );
147 : : }
148 : 2527 : }
149 : :
150 : : bool
151 [ + - ]: 2 : TUTSuite::assess()
152 : : // *****************************************************************************
153 : : // Echo final assessment after the full unit test suite has finished
154 : : //! \return True of all tests passed, false if there was at least a failure or
155 : : //! an exception
156 : : // *****************************************************************************
157 : : {
158 : : tk::Print print;
159 : :
160 [ + - ][ + - ]: 2 : if (!m_nfail && !m_nwarn && !m_nskip && !m_nexcp) {
[ - + ][ - - ]
161 : :
162 [ - - ]: 0 : print << "\nAll " + std::to_string(m_ncomplete) + " tests passed\n";
163 : :
164 : : } else {
165 : :
166 : : std::string skip, warn, fail, excp;
167 : :
168 [ - + ]: 2 : if (m_nwarn) {
169 [ - - ]: 0 : warn = "finished with a warning: " + std::to_string(m_nwarn);
170 : : }
171 : :
172 [ + - ]: 2 : if (m_nskip) {
173 [ + - ][ + - ]: 6 : skip = std::string(m_nwarn ? ", " : "") +
[ - + ][ - - ]
174 [ + - ][ + - ]: 6 : "(fully or partially) skipped: " + std::to_string(m_nskip);
175 : : }
176 : :
177 [ - + ]: 2 : if (m_nexcp) {
178 [ - - ][ - - ]: 0 : excp = std::string(m_nskip || m_nwarn ? ", " : "") +
[ - - ][ - - ]
[ - - ]
179 [ - - ][ - - ]: 0 : "threw exception: " + std::to_string(m_nexcp);
180 : : }
181 : :
182 [ - + ]: 2 : if (m_nfail) {
183 [ - - ][ - - ]: 0 : fail = std::string(m_nexcp || m_nskip || m_nwarn ? ", " : "")
[ - - ][ - - ]
184 [ - - ][ - - ]: 0 : + "failed: " + std::to_string(m_nfail);
[ - - ][ - - ]
185 : : }
186 : :
187 [ + - ][ - + ]: 4 : print << "\nOf " + std::to_string(m_ncomplete) + " tests total: "
[ - - ]
188 [ + - ][ + - ]: 2 : << warn << skip << excp << fail << '\n';
[ + - ][ + - ]
[ + - ]
189 : :
190 : : }
191 : :
192 [ + - ][ - + ]: 2 : return (m_nfail || m_nexcp) ? false : true;
193 : : }
194 : :
195 : : #include "NoWarning/tutsuite.def.h"
|