HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
unittest.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenImageIO project.
2 // SPDX-License-Identifier: Apache-2.0
3 // https://github.com/AcademySoftwareFoundation/OpenImageIO
4 
5 #pragma once
6 
7 #include <algorithm>
8 #include <cmath>
9 #include <cstdlib>
10 #include <iostream>
11 
12 #include <OpenImageIO/simd.h>
13 #include <OpenImageIO/strutil.h>
14 #include <OpenImageIO/sysutil.h>
15 
16 
18 
19 namespace simd {
20 // Force a float-based abs and max to appear in namespace simd
21 inline float
22 abs(float x)
23 {
24  return std::abs(x);
25 }
26 inline float
27 max(float x, float y)
28 {
29  return std::max(x, y);
30 }
31 } // namespace simd
32 
33 namespace pvt {
34 
36 public:
38  : m_failures(0)
39  {
40  }
42  {
43  if (m_failures) {
44  std::cout << Sysutil::Term(std::cout).ansi("red", "ERRORS!\n");
45  std::exit(m_failures != 0);
46  } else {
47 #ifndef OIIO_UNIT_TEST_QUIET_SUCCESS
48  std::cout << Sysutil::Term(std::cout).ansi("green", "OK\n");
49 #endif
50  }
51  }
52  const UnitTestFailureCounter& operator++() noexcept // prefix
53  {
54  ++m_failures;
55  return *this;
56  }
57  int operator++(int) noexcept { return m_failures++; } // postfix
59  {
60  m_failures += i;
61  return *this;
62  }
63  operator int() const noexcept { return m_failures; }
64 
65 private:
66  int m_failures = 0;
67 };
68 
69 
70 template<typename X, typename Y>
71 inline bool
72 equal_approx(const X& x, const Y& y)
73 {
74  using namespace simd;
75  return all(abs((x) - (y)) <= 0.001f * max(abs(x), abs(y)));
76 }
77 
78 
79 } // end namespace pvt
80 
82 
83 // Helper: print entire vectors. This makes the OIIO_CHECK_EQUAL macro
84 // work for std::vector!
85 template<typename T>
86 inline std::ostream&
87 operator<<(std::ostream& out, const std::vector<T>& v)
88 {
89  out << '{' << OIIO::Strutil::join(v, ",") << '}';
90  return out;
91 }
92 
93 static OIIO::pvt::UnitTestFailureCounter unit_test_failures;
94 
95 
96 
97 /// OIIO_CHECK_* macros checks if the conditions is met, and if not,
98 /// prints an error message indicating the module and line where the
99 /// error occurred, but does NOT abort. This is helpful for unit tests
100 /// where we do not want one failure.
101 #define OIIO_CHECK_ASSERT(x) \
102  ((x) ? ((void)0) \
103  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
104  << __FILE__ << ":" << __LINE__ << ":\n" \
105  << "FAILED: " \
106  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
107  << "\n"), \
108  (void)++unit_test_failures))
109 
110 #define OIIO_CHECK_EQUAL(x, y) \
111  (((x) == (y)) \
112  ? ((void)0) \
113  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
114  << __FILE__ << ":" << __LINE__ << ":\n" \
115  << "FAILED: " \
116  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
117  << " == " << #y << "\n" \
118  << "\tvalues were '" << (x) << "' and '" << (y) \
119  << "'\n"), \
120  (void)++unit_test_failures))
121 
122 #define OIIO_CHECK_FALSE(x) OIIO_CHECK_EQUAL(x, false)
123 
124 #define OIIO_CHECK_EQUAL_THRESH(x, y, eps) \
125  ((std::abs((x) - (y)) <= eps) \
126  ? ((void)0) \
127  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
128  << __FILE__ << ":" << __LINE__ << ":\n" \
129  << "FAILED: " \
130  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
131  << " == " << #y << "\n" \
132  << "\tvalues were '" << (x) << "' and '" << (y) << "'" \
133  << ", diff was " << std::abs((x) - (y)) << "\n"), \
134  (void)++unit_test_failures))
135 
136 #define OIIO_CHECK_EQUAL_THRESH_REL(x, y, epsabs, epsrel) \
137  ((std::abs((x) - (y)) <= (epsabs + epsrel * std::max(abs(x), abs(y)))) \
138  ? ((void)0) \
139  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
140  << __FILE__ << ":" << __LINE__ << ":\n" \
141  << "FAILED: " \
142  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
143  << " == " << #y << "\n" \
144  << "\tvalues were '" << (x) << "' and '" << (y) << "'" \
145  << ", diff was " << std::abs((x) - (y)) << "\n"), \
146  (void)++unit_test_failures))
147 
148 #define OIIO_CHECK_EQUAL_APPROX(x, y) \
149  (OIIO::pvt::equal_approx(x, y) \
150  ? ((void)0) \
151  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
152  << __FILE__ << ":" << __LINE__ << ":\n" \
153  << "FAILED: " \
154  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
155  << " == " << #y << "\n" \
156  << "\tvalues were '" << (x) << "' and '" << (y) << "'" \
157  << ", diff was " << ((x) - (y)) << "\n"), \
158  (void)++unit_test_failures))
159 
160 #define OIIO_CHECK_NE(x, y) \
161  (((x) != (y)) \
162  ? ((void)0) \
163  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
164  << __FILE__ << ":" << __LINE__ << ":\n" \
165  << "FAILED: " \
166  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
167  << " != " << #y << "\n" \
168  << "\tvalues were '" << (x) << "' and '" << (y) \
169  << "'\n"), \
170  (void)++unit_test_failures))
171 
172 #define OIIO_CHECK_LT(x, y) \
173  (((x) < (y)) \
174  ? ((void)0) \
175  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
176  << __FILE__ << ":" << __LINE__ << ":\n" \
177  << "FAILED: " \
178  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
179  << " < " << #y << "\n" \
180  << "\tvalues were '" << (x) << "' and '" << (y) \
181  << "'\n"), \
182  (void)++unit_test_failures))
183 
184 #define OIIO_CHECK_GT(x, y) \
185  (((x) > (y)) \
186  ? ((void)0) \
187  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
188  << __FILE__ << ":" << __LINE__ << ":\n" \
189  << "FAILED: " \
190  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
191  << " > " << #y << "\n" \
192  << "\tvalues were '" << (x) << "' and '" << (y) \
193  << "'\n"), \
194  (void)++unit_test_failures))
195 
196 #define OIIO_CHECK_LE(x, y) \
197  (((x) <= (y)) \
198  ? ((void)0) \
199  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
200  << __FILE__ << ":" << __LINE__ << ":\n" \
201  << "FAILED: " \
202  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
203  << " <= " << #y << "\n" \
204  << "\tvalues were '" << (x) << "' and '" << (y) \
205  << "'\n"), \
206  (void)++unit_test_failures))
207 
208 #define OIIO_CHECK_GE(x, y) \
209  (((x) >= (y)) \
210  ? ((void)0) \
211  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
212  << __FILE__ << ":" << __LINE__ << ":\n" \
213  << "FAILED: " \
214  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
215  << " >= " << #y << "\n" \
216  << "\tvalues were '" << (x) << "' and '" << (y) \
217  << "'\n"), \
218  (void)++unit_test_failures))
219 
220 
221 // Special SIMD related equality checks that use all()
222 #define OIIO_CHECK_SIMD_EQUAL(x, y) \
223  (all((x) == (y)) \
224  ? ((void)0) \
225  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
226  << __FILE__ << ":" << __LINE__ << ":\n" \
227  << "FAILED: " \
228  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
229  << " == " << #y << "\n" \
230  << "\tvalues were '" << (x) << "' and '" << (y) \
231  << "'\n"), \
232  (void)++unit_test_failures))
233 
234 #define OIIO_CHECK_SIMD_EQUAL_THRESH(x, y, eps) \
235  (all(abs((x) - (y)) <= (eps)) \
236  ? ((void)0) \
237  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
238  << __FILE__ << ":" << __LINE__ << ":\n" \
239  << "FAILED: " \
240  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
241  << " == " << #y << "\n" \
242  << "\tvalues were '" << (x) << "' and '" << (y) \
243  << "'\n"), \
244  (void)++unit_test_failures))
245 
246 
247 // Test if ImageBuf operation got an error. It's a lot like simply testing
248 // OIIO_CHECK_ASSERT(x), but if x is false, it will get an error message
249 // from the buffer and incorporate it into the failure message.
250 // Call like this, for example:
251 // ImageBuf buf;
252 // OIIO_CHECK_IMAGEBUF_STATUS(buf,
253 // ImageBufAlgo::Func (buf, ...)
254 // );
255 #define OIIO_CHECK_IMAGEBUF_STATUS(buf, x) \
256  ((x && !buf.has_error()) \
257  ? ((void)0) \
258  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
259  << __FILE__ << ":" << __LINE__ << ":\n" \
260  << "FAILED: " \
261  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
262  << ": " << buf.geterror() << "\n"), \
263  (void)++unit_test_failures))
vint4 max(const vint4 &a, const vint4 &b)
Definition: simd.h:5012
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
const GLdouble * v
Definition: glcorearb.h:837
GLint y
Definition: glcorearb.h:103
String-related utilities, all in namespace Strutil.
SIM_API const UT_StringHolder all
vint4 abs(const vint4 &a)
Definition: simd.h:4989
GLfloat f
Definition: glcorearb.h:1926
std::string ansi(string_view command) const
Platform-independent utilities for various OS, hardware, and system resource functionality, all in namespace Sysutil.
int operator++(int) noexcept
Definition: unittest.h:57
GLint GLenum GLint x
Definition: glcorearb.h:409
const UnitTestFailureCounter & operator++() noexcept
Definition: unittest.h:52
UnitTestFailureCounter() noexcept
Definition: unittest.h:37
float max(float x, float y)
Definition: unittest.h:27
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER IMATH_HOSTDEVICE constexpr T abs(T a) IMATH_NOEXCEPT
Definition: ImathFun.h:26
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:127
Classes for SIMD processing.
UnitTestFailureCounter operator+=(int i) noexcept
Definition: unittest.h:58
auto join(It begin, Sentinel end, string_view sep) -> join_view< It, Sentinel >
Definition: format.h:4489
#define OIIO_NAMESPACE_BEGIN
Definition: oiioversion.h:126
bool equal_approx(const X &x, const Y &y)
Definition: unittest.h:72