timemory 3.3.0
Modular C++ Toolkit for Performance Analysis and Logging. Profiling API and Tools for C, C++, CUDA, Fortran, and Python. The C++ template API is essentially a framework to creating tools: it is designed to provide a unifying interface for recording various performance measurements alongside data logging and interfaces to other tools.
testing.hpp
Go to the documentation of this file.
1// MIT License
2//
3// Copyright (c) 2020, The Regents of the University of California,
4// through Lawrence Berkeley National Laboratory (subject to receipt of any
5// required approvals from the U.S. Dept. of Energy). All rights reserved.
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to
9// deal in the Software without restriction, including without limitation the
10// rights to use, copy, modify, merge, publish, distribute, sublicense, and
11// copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in
15// all copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23// IN THE SOFTWARE.
24
25/** \file utility/testing.hpp
26 * \headerfile utility/testing.hpp "timemory/utility/testing.hpp"
27 * This is used for C++ testing of the timemory package
28 *
29 */
30
31#pragma once
32
33// C headers
34#include <cassert>
35#include <cstdint>
36#include <cstdio>
37
38// C++ headers
39#include <iomanip>
40#include <iostream>
41#include <sstream>
42#include <stdexcept>
43
44// timemory headers
45#include "timemory/backends/dmp.hpp"
47
48//--------------------------------------------------------------------------------------//
49
50// ASSERT_NEAR
51// EXPECT_EQ
52// EXPECT_FLOAT_EQ
53// EXPECT_DOUBLE_EQ
54
55#if !defined(EXPECT_EQ)
56# define EXPECT_EQ(lhs, rhs) \
57 if(lhs != rhs) \
58 { \
59 std::stringstream ss; \
60 ss << #lhs << " != " << #rhs << " @ line " << __LINE__ << " of " \
61 << __FILE__; \
62 std::cerr << ss.str() << std::endl; \
63 throw std::runtime_error(ss.str()); \
64 }
65#endif
66
67#if !defined(ASSERT_FALSE)
68# define ASSERT_FALSE(expr) \
69 if(expr) \
70 { \
71 std::stringstream ss; \
72 ss << "Expression: ( " << #expr << " ) " \
73 << "failed @ line " << __LINE__ << " of " << __FILE__; \
74 std::cerr << ss.str() << std::endl; \
75 throw std::runtime_error(ss.str()); \
76 }
77#endif
78
79#if !defined(ASSERT_TRUE)
80# define ASSERT_TRUE(expr) \
81 if(!(expr)) \
82 { \
83 std::stringstream ss; \
84 ss << "Expression: !( " << #expr << " ) " \
85 << "failed @ line " << __LINE__ << " of " << __FILE__; \
86 std::cerr << ss.str() << std::endl; \
87 throw std::runtime_error(ss.str()); \
88 }
89#endif
90
91inline std::string
93{
94 std::stringstream ss;
95 if(tim::dmp::is_initialized())
96 ss << "[" << tim::dmp::rank() << "] ";
97 return ss.str();
98}
99
100#define rank_cout std::cout << rank_prefix()
101
102//--------------------------------------------------------------------------------------//
103#define TEST_SUMMARY(argv_0, ntest_counter, nfail_counter) \
104 { \
105 std::stringstream rank_sout; \
106 std::stringstream filler; \
107 filler.fill('='); \
108 filler << "#" << std::setw(78) << "" \
109 << "#"; \
110 rank_sout << "\n... [\e[1;33mTESTING COMPLETED\e[0m] ... \n" << std::endl; \
111 rank_sout << filler.str() << "\n#\n"; \
112 rank_sout << "#\t" \
113 << "[" << argv_0 << "] "; \
114 if(num_fail > 0) \
115 rank_sout << "\e[1;31mTESTS FAILED\e[0m: " << nfail_counter << '/' \
116 << ntest_counter << std::endl; \
117 else \
118 rank_sout << "\e[1;36mTESTS PASSED\e[0m: " \
119 << (ntest_counter - nfail_counter) << '/' << ntest_counter \
120 << std::endl; \
121 rank_sout << "#\n" << filler.str() << "\n" << std::endl; \
122 rank_cout << rank_sout.str(); \
123 }
124
125//--------------------------------------------------------------------------------------//
126// Usage:
127// CONFIGURE_TEST_SELECTOR(8)
128//
129// Required for RUN_TEST
130//
131#define CONFIGURE_TEST_SELECTOR(total_tests) \
132 int total_num_tests = total_tests; \
133 std::set<int> tests; \
134 if(argc == 1) \
135 for(int i = 0; i < total_tests; ++i) \
136 tests.insert(i + 1); \
137 for(int i = 1; i < argc; ++i) \
138 tests.insert(atoi(argv[i]));
139
140//--------------------------------------------------------------------------------------//
141// Usage:
142//
143// int num_fail = 0; // tracks the number of failed tests
144// int num_test = 0; // tracks the number of tests executed
145//
146// try
147// {
148// RUN_TEST(test_serialize, num_test, num_fail);
149// }
150// catch(std::exception& e)
151// {
152// std::cerr << e.what() << std::endl;
153// }
154//
155#define RUN_TEST(test_num, func, ntest_counter, nfail_counter) \
156 { \
157 if(test_num > total_num_tests || tests.count(test_num) != 0) \
158 { \
159 if(test_num > total_num_tests) \
160 printf("Warning! Test %i is greater than the specified number of " \
161 "tests: " \
162 "%i\n", \
163 test_num, total_num_tests); \
164 try \
165 { \
166 ntest_counter += 1; \
167 func(); \
168 } catch(std::exception & e) \
169 { \
170 std::cerr << e.what() << std::endl; \
171 nfail_counter += 1; \
172 } \
173 } \
174 else \
175 { \
176 printf("\n... Skipping test #%i ...\n\n", test_num); \
177 } \
178 }
179
180//--------------------------------------------------------------------------------------//
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
std::string rank_prefix()
Definition: testing.hpp:92