1*c217d954SCole Faust /*
2*c217d954SCole Faust * Copyright (c) 2017-2022 Arm Limited.
3*c217d954SCole Faust *
4*c217d954SCole Faust * SPDX-License-Identifier: MIT
5*c217d954SCole Faust *
6*c217d954SCole Faust * Permission is hereby granted, free of charge, to any person obtaining a copy
7*c217d954SCole Faust * of this software and associated documentation files (the "Software"), to
8*c217d954SCole Faust * deal in the Software without restriction, including without limitation the
9*c217d954SCole Faust * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*c217d954SCole Faust * sell copies of the Software, and to permit persons to whom the Software is
11*c217d954SCole Faust * furnished to do so, subject to the following conditions:
12*c217d954SCole Faust *
13*c217d954SCole Faust * The above copyright notice and this permission notice shall be included in all
14*c217d954SCole Faust * copies or substantial portions of the Software.
15*c217d954SCole Faust *
16*c217d954SCole Faust * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*c217d954SCole Faust * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*c217d954SCole Faust * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*c217d954SCole Faust * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*c217d954SCole Faust * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21*c217d954SCole Faust * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22*c217d954SCole Faust * SOFTWARE.
23*c217d954SCole Faust */
24*c217d954SCole Faust #ifndef ARM_COMPUTE_TEST_FRAMEWORK_ASSERTS
25*c217d954SCole Faust #define ARM_COMPUTE_TEST_FRAMEWORK_ASSERTS
26*c217d954SCole Faust
27*c217d954SCole Faust #include "Exceptions.h"
28*c217d954SCole Faust #include "Framework.h"
29*c217d954SCole Faust
30*c217d954SCole Faust #include <sstream>
31*c217d954SCole Faust #include <type_traits>
32*c217d954SCole Faust
33*c217d954SCole Faust #include "utils/TypePrinter.h"
34*c217d954SCole Faust
35*c217d954SCole Faust namespace arm_compute
36*c217d954SCole Faust {
37*c217d954SCole Faust namespace test
38*c217d954SCole Faust {
39*c217d954SCole Faust namespace framework
40*c217d954SCole Faust {
41*c217d954SCole Faust // Cast char values to int so that their numeric value are printed.
make_printable(int8_t value)42*c217d954SCole Faust inline int make_printable(int8_t value)
43*c217d954SCole Faust {
44*c217d954SCole Faust return value;
45*c217d954SCole Faust }
46*c217d954SCole Faust
make_printable(const arm_compute::WeightFormat wf)47*c217d954SCole Faust inline std::string make_printable(const arm_compute::WeightFormat wf)
48*c217d954SCole Faust {
49*c217d954SCole Faust return arm_compute::to_string(wf);
50*c217d954SCole Faust }
51*c217d954SCole Faust
make_printable(uint8_t value)52*c217d954SCole Faust inline unsigned int make_printable(uint8_t value)
53*c217d954SCole Faust {
54*c217d954SCole Faust return value;
55*c217d954SCole Faust }
56*c217d954SCole Faust
57*c217d954SCole Faust // Everything else can be printed as its own type.
58*c217d954SCole Faust template <typename T>
make_printable(T && value)59*c217d954SCole Faust inline T make_printable(T &&value)
60*c217d954SCole Faust {
61*c217d954SCole Faust return value;
62*c217d954SCole Faust }
63*c217d954SCole Faust
ARM_COMPUTE_PRINT_INFO()64*c217d954SCole Faust inline void ARM_COMPUTE_PRINT_INFO()
65*c217d954SCole Faust {
66*c217d954SCole Faust std::stringstream msg;
67*c217d954SCole Faust arm_compute::test::framework::Framework::get().print_test_info(msg);
68*c217d954SCole Faust arm_compute::test::framework::Framework::get().log_info(msg.str());
69*c217d954SCole Faust arm_compute::test::framework::Framework::get().clear_test_info();
70*c217d954SCole Faust }
71*c217d954SCole Faust
72*c217d954SCole Faust #define ARM_COMPUTE_TEST_INFO(INFO) \
73*c217d954SCole Faust { \
74*c217d954SCole Faust std::stringstream info; \
75*c217d954SCole Faust info << INFO; \
76*c217d954SCole Faust arm_compute::test::framework::Framework::get().add_test_info(info.str()); \
77*c217d954SCole Faust }
78*c217d954SCole Faust
79*c217d954SCole Faust namespace detail
80*c217d954SCole Faust {
81*c217d954SCole Faust #define ARM_COMPUTE_TEST_COMP_FACTORY(SEVERITY, SEVERITY_NAME, COMP, COMP_NAME, ERROR_CALL) \
82*c217d954SCole Faust template <typename T, typename U> \
83*c217d954SCole Faust void ARM_COMPUTE_##SEVERITY##_##COMP_NAME##_IMPL(T &&x, U &&y, const std::string &x_str, const std::string &y_str, LogLevel level) \
84*c217d954SCole Faust { \
85*c217d954SCole Faust if(!(x COMP y)) \
86*c217d954SCole Faust { \
87*c217d954SCole Faust std::stringstream msg; \
88*c217d954SCole Faust msg << #SEVERITY_NAME " '" << x_str << " " #COMP " " << y_str << "' failed. [" \
89*c217d954SCole Faust << std::boolalpha << arm_compute::test::framework::make_printable(x) \
90*c217d954SCole Faust << " " #COMP " " \
91*c217d954SCole Faust << std::boolalpha << arm_compute::test::framework::make_printable(y) \
92*c217d954SCole Faust << "]\n"; \
93*c217d954SCole Faust arm_compute::test::framework::Framework::get().print_test_info(msg); \
94*c217d954SCole Faust ERROR_CALL \
95*c217d954SCole Faust } \
96*c217d954SCole Faust arm_compute::test::framework::Framework::get().clear_test_info(); \
97*c217d954SCole Faust }
98*c217d954SCole Faust
99*c217d954SCole Faust ARM_COMPUTE_TEST_COMP_FACTORY(EXPECT, Expectation, ==, EQUAL, arm_compute::test::framework::Framework::get().log_failed_expectation(arm_compute::test::framework::TestError(msg.str(), level));)
100*c217d954SCole Faust ARM_COMPUTE_TEST_COMP_FACTORY(EXPECT, Expectation, !=, NOT_EQUAL, arm_compute::test::framework::Framework::get().log_failed_expectation(arm_compute::test::framework::TestError(msg.str(), level));)
101*c217d954SCole Faust ARM_COMPUTE_TEST_COMP_FACTORY(ASSERT, Assertion, ==, EQUAL, throw arm_compute::test::framework::TestError(msg.str(), level);)
102*c217d954SCole Faust ARM_COMPUTE_TEST_COMP_FACTORY(ASSERT, Assertion, !=, NOT_EQUAL, throw arm_compute::test::framework::TestError(msg.str(), level);)
103*c217d954SCole Faust } // namespace detail
104*c217d954SCole Faust
105*c217d954SCole Faust #define ARM_COMPUTE_ASSERT_NOT_EQUAL(X, Y) \
106*c217d954SCole Faust arm_compute::test::framework::detail::ARM_COMPUTE_ASSERT_NOT_EQUAL_IMPL(X, Y, #X, #Y, LogLevel::ERRORS)
107*c217d954SCole Faust
108*c217d954SCole Faust #define ARM_COMPUTE_ASSERT_EQUAL(X, Y) \
109*c217d954SCole Faust arm_compute::test::framework::detail::ARM_COMPUTE_ASSERT_EQUAL_IMPL(X, Y, #X, #Y, LogLevel::ERRORS)
110*c217d954SCole Faust
111*c217d954SCole Faust #define ARM_COMPUTE_EXPECT_EQUAL(X, Y, LEVEL) \
112*c217d954SCole Faust arm_compute::test::framework::detail::ARM_COMPUTE_EXPECT_EQUAL_IMPL(X, Y, #X, #Y, LEVEL)
113*c217d954SCole Faust
114*c217d954SCole Faust #define ARM_COMPUTE_EXPECT_NOT_EQUAL(X, Y, LEVEL) \
115*c217d954SCole Faust arm_compute::test::framework::detail::ARM_COMPUTE_EXPECT_NOT_EQUAL_IMPL(X, Y, #X, #Y, LEVEL)
116*c217d954SCole Faust
117*c217d954SCole Faust #define ARM_COMPUTE_ASSERT(X) \
118*c217d954SCole Faust do \
119*c217d954SCole Faust { \
120*c217d954SCole Faust const auto &x = X; \
121*c217d954SCole Faust if(!x) \
122*c217d954SCole Faust { \
123*c217d954SCole Faust std::stringstream msg; \
124*c217d954SCole Faust msg << "Assertion '" #X "' failed.\n"; \
125*c217d954SCole Faust arm_compute::test::framework::Framework::get().print_test_info(msg); \
126*c217d954SCole Faust throw arm_compute::test::framework::TestError(msg.str(), arm_compute::test::framework::LogLevel::ERRORS); \
127*c217d954SCole Faust } \
128*c217d954SCole Faust arm_compute::test::framework::Framework::get().clear_test_info(); \
129*c217d954SCole Faust } while(false)
130*c217d954SCole Faust
131*c217d954SCole Faust #define ARM_COMPUTE_EXPECT(X, LEVEL) \
132*c217d954SCole Faust do \
133*c217d954SCole Faust { \
134*c217d954SCole Faust const auto &x = X; \
135*c217d954SCole Faust if(!x) \
136*c217d954SCole Faust { \
137*c217d954SCole Faust std::stringstream msg; \
138*c217d954SCole Faust msg << "Expectation '" #X "' failed.\n"; \
139*c217d954SCole Faust arm_compute::test::framework::Framework::get().print_test_info(msg); \
140*c217d954SCole Faust arm_compute::test::framework::Framework::get().log_failed_expectation(arm_compute::test::framework::TestError(msg.str(), LEVEL)); \
141*c217d954SCole Faust } \
142*c217d954SCole Faust arm_compute::test::framework::Framework::get().clear_test_info(); \
143*c217d954SCole Faust } while(false)
144*c217d954SCole Faust
145*c217d954SCole Faust #define ARM_COMPUTE_EXPECT_NO_THROW(X, LEVEL) \
146*c217d954SCole Faust do \
147*c217d954SCole Faust { \
148*c217d954SCole Faust try \
149*c217d954SCole Faust { \
150*c217d954SCole Faust const auto &x = X; \
151*c217d954SCole Faust (void)x; \
152*c217d954SCole Faust } \
153*c217d954SCole Faust catch(...) \
154*c217d954SCole Faust { \
155*c217d954SCole Faust std::stringstream msg; \
156*c217d954SCole Faust msg << "Expectation '" #X "' to not throw failed.\n"; \
157*c217d954SCole Faust arm_compute::test::framework::Framework::get().print_test_info(msg); \
158*c217d954SCole Faust arm_compute::test::framework::Framework::get().log_failed_expectation(arm_compute::test::framework::TestError(msg.str(), LEVEL)); \
159*c217d954SCole Faust } \
160*c217d954SCole Faust arm_compute::test::framework::Framework::get().clear_test_info(); \
161*c217d954SCole Faust } while(false)
162*c217d954SCole Faust
163*c217d954SCole Faust #if defined(ARM_COMPUTE_ASSERTS_ENABLED)
164*c217d954SCole Faust #define ARM_COMPUTE_EXPECT_THROW(X, LEVEL) \
165*c217d954SCole Faust do \
166*c217d954SCole Faust { \
167*c217d954SCole Faust bool exception_caught = false; \
168*c217d954SCole Faust try \
169*c217d954SCole Faust { \
170*c217d954SCole Faust const auto &x = X; \
171*c217d954SCole Faust (void)x; \
172*c217d954SCole Faust } \
173*c217d954SCole Faust catch(...) \
174*c217d954SCole Faust { \
175*c217d954SCole Faust exception_caught = true; \
176*c217d954SCole Faust } \
177*c217d954SCole Faust if(!exception_caught) \
178*c217d954SCole Faust { \
179*c217d954SCole Faust std::stringstream msg; \
180*c217d954SCole Faust msg << "Expectation '" #X "' to throw failed.\n"; \
181*c217d954SCole Faust arm_compute::test::framework::Framework::get().print_test_info(msg); \
182*c217d954SCole Faust arm_compute::test::framework::Framework::get().log_failed_expectation(arm_compute::test::framework::TestError(msg.str(), LEVEL)); \
183*c217d954SCole Faust } \
184*c217d954SCole Faust arm_compute::test::framework::Framework::get().clear_test_info(); \
185*c217d954SCole Faust } while(false)
186*c217d954SCole Faust #else // defined(ARM_COMPUTE_ASSERTS_ENABLED)
187*c217d954SCole Faust #define ARM_COMPUTE_EXPECT_THROW(X, LEVEL) \
188*c217d954SCole Faust do \
189*c217d954SCole Faust { \
190*c217d954SCole Faust std::stringstream msg; \
191*c217d954SCole Faust msg << "'" #X "' Skipped: asserts disabled, cannot throw\n"; \
192*c217d954SCole Faust arm_compute::test::framework::Framework::get().print_test_info(msg); \
193*c217d954SCole Faust arm_compute::test::framework::Framework::get().log_info(msg.str()); \
194*c217d954SCole Faust arm_compute::test::framework::Framework::get().clear_test_info(); \
195*c217d954SCole Faust } while(false)
196*c217d954SCole Faust #endif // defined(ARM_COMPUTE_ASSERTS_ENABLED)
197*c217d954SCole Faust
198*c217d954SCole Faust #define ARM_COMPUTE_ASSERT_FAIL(MSG) \
199*c217d954SCole Faust do \
200*c217d954SCole Faust { \
201*c217d954SCole Faust std::stringstream msg; \
202*c217d954SCole Faust msg << "Assertion '" << MSG << "' failed.\n"; \
203*c217d954SCole Faust arm_compute::test::framework::Framework::get().print_test_info(msg); \
204*c217d954SCole Faust throw arm_compute::test::framework::TestError(msg.str(), arm_compute::test::framework::LogLevel::ERRORS); \
205*c217d954SCole Faust arm_compute::test::framework::Framework::get().clear_test_info(); \
206*c217d954SCole Faust } while(false)
207*c217d954SCole Faust
208*c217d954SCole Faust #define ARM_COMPUTE_EXPECT_FAIL(MSG, LEVEL) \
209*c217d954SCole Faust do \
210*c217d954SCole Faust { \
211*c217d954SCole Faust std::stringstream msg; \
212*c217d954SCole Faust msg << "Expectation '" << MSG << "' failed.\n"; \
213*c217d954SCole Faust arm_compute::test::framework::Framework::get().print_test_info(msg); \
214*c217d954SCole Faust arm_compute::test::framework::Framework::get().log_failed_expectation(arm_compute::test::framework::TestError(msg.str(), LEVEL)); \
215*c217d954SCole Faust arm_compute::test::framework::Framework::get().clear_test_info(); \
216*c217d954SCole Faust } while(false)
217*c217d954SCole Faust } // namespace framework
218*c217d954SCole Faust } // namespace test
219*c217d954SCole Faust } // namespace arm_compute
220*c217d954SCole Faust #endif /* ARM_COMPUTE_TEST_FRAMEWORK_ASSERTS */
221