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 2008-present Contributors to the OpenImageIO project.
2 // SPDX-License-Identifier: BSD-3-Clause
3 // https://github.com/OpenImageIO/oiio
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  std::cout << Sysutil::Term(std::cout).ansi("green", "OK\n");
48  }
49  }
50  const UnitTestFailureCounter& operator++() noexcept // prefix
51  {
52  ++m_failures;
53  return *this;
54  }
55  int operator++(int) noexcept { return m_failures++; } // postfix
57  {
58  m_failures += i;
59  return *this;
60  }
61  operator int() const noexcept { return m_failures; }
62 
63 private:
64  int m_failures = 0;
65 };
66 
67 
68 template<typename X, typename Y>
69 inline bool
70 equal_approx(const X& x, const Y& y)
71 {
72  using namespace simd;
73  return all(abs((x) - (y)) <= 0.001f * max(abs(x), abs(y)));
74 }
75 
76 
77 } // end namespace pvt
78 
80 
81 // Helper: print entire vectors. This makes the OIIO_CHECK_EQUAL macro
82 // work for std::vector!
83 template<typename T>
84 inline std::ostream&
85 operator<<(std::ostream& out, const std::vector<T>& v)
86 {
87  out << '{' << OIIO::Strutil::join(v, ",") << '}';
88  return out;
89 }
90 
91 static OIIO::pvt::UnitTestFailureCounter unit_test_failures;
92 
93 
94 
95 /// OIIO_CHECK_* macros checks if the conditions is met, and if not,
96 /// prints an error message indicating the module and line where the
97 /// error occurred, but does NOT abort. This is helpful for unit tests
98 /// where we do not want one failure.
99 #define OIIO_CHECK_ASSERT(x) \
100  ((x) ? ((void)0) \
101  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
102  << __FILE__ << ":" << __LINE__ << ":\n" \
103  << "FAILED: " \
104  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
105  << "\n"), \
106  (void)++unit_test_failures))
107 
108 #define OIIO_CHECK_EQUAL(x, y) \
109  (((x) == (y)) \
110  ? ((void)0) \
111  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
112  << __FILE__ << ":" << __LINE__ << ":\n" \
113  << "FAILED: " \
114  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
115  << " == " << #y << "\n" \
116  << "\tvalues were '" << (x) << "' and '" << (y) \
117  << "'\n"), \
118  (void)++unit_test_failures))
119 
120 #define OIIO_CHECK_EQUAL_THRESH(x, y, eps) \
121  ((std::abs((x) - (y)) <= eps) \
122  ? ((void)0) \
123  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
124  << __FILE__ << ":" << __LINE__ << ":\n" \
125  << "FAILED: " \
126  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
127  << " == " << #y << "\n" \
128  << "\tvalues were '" << (x) << "' and '" << (y) << "'" \
129  << ", diff was " << std::abs((x) - (y)) << "\n"), \
130  (void)++unit_test_failures))
131 
132 #define OIIO_CHECK_EQUAL_APPROX(x, y) \
133  (OIIO::pvt::equal_approx(x, y) \
134  ? ((void)0) \
135  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
136  << __FILE__ << ":" << __LINE__ << ":\n" \
137  << "FAILED: " \
138  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
139  << " == " << #y << "\n" \
140  << "\tvalues were '" << (x) << "' and '" << (y) << "'" \
141  << ", diff was " << ((x) - (y)) << "\n"), \
142  (void)++unit_test_failures))
143 
144 #define OIIO_CHECK_NE(x, y) \
145  (((x) != (y)) \
146  ? ((void)0) \
147  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
148  << __FILE__ << ":" << __LINE__ << ":\n" \
149  << "FAILED: " \
150  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
151  << " != " << #y << "\n" \
152  << "\tvalues were '" << (x) << "' and '" << (y) \
153  << "'\n"), \
154  (void)++unit_test_failures))
155 
156 #define OIIO_CHECK_LT(x, y) \
157  (((x) < (y)) \
158  ? ((void)0) \
159  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
160  << __FILE__ << ":" << __LINE__ << ":\n" \
161  << "FAILED: " \
162  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
163  << " < " << #y << "\n" \
164  << "\tvalues were '" << (x) << "' and '" << (y) \
165  << "'\n"), \
166  (void)++unit_test_failures))
167 
168 #define OIIO_CHECK_GT(x, y) \
169  (((x) > (y)) \
170  ? ((void)0) \
171  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
172  << __FILE__ << ":" << __LINE__ << ":\n" \
173  << "FAILED: " \
174  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
175  << " > " << #y << "\n" \
176  << "\tvalues were '" << (x) << "' and '" << (y) \
177  << "'\n"), \
178  (void)++unit_test_failures))
179 
180 #define OIIO_CHECK_LE(x, y) \
181  (((x) <= (y)) \
182  ? ((void)0) \
183  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
184  << __FILE__ << ":" << __LINE__ << ":\n" \
185  << "FAILED: " \
186  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
187  << " <= " << #y << "\n" \
188  << "\tvalues were '" << (x) << "' and '" << (y) \
189  << "'\n"), \
190  (void)++unit_test_failures))
191 
192 #define OIIO_CHECK_GE(x, y) \
193  (((x) >= (y)) \
194  ? ((void)0) \
195  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
196  << __FILE__ << ":" << __LINE__ << ":\n" \
197  << "FAILED: " \
198  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
199  << " >= " << #y << "\n" \
200  << "\tvalues were '" << (x) << "' and '" << (y) \
201  << "'\n"), \
202  (void)++unit_test_failures))
203 
204 
205 // Special SIMD related equality checks that use all()
206 #define OIIO_CHECK_SIMD_EQUAL(x, y) \
207  (all((x) == (y)) \
208  ? ((void)0) \
209  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
210  << __FILE__ << ":" << __LINE__ << ":\n" \
211  << "FAILED: " \
212  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
213  << " == " << #y << "\n" \
214  << "\tvalues were '" << (x) << "' and '" << (y) \
215  << "'\n"), \
216  (void)++unit_test_failures))
217 
218 #define OIIO_CHECK_SIMD_EQUAL_THRESH(x, y, eps) \
219  (all(abs((x) - (y)) <= (eps)) \
220  ? ((void)0) \
221  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
222  << __FILE__ << ":" << __LINE__ << ":\n" \
223  << "FAILED: " \
224  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
225  << " == " << #y << "\n" \
226  << "\tvalues were '" << (x) << "' and '" << (y) \
227  << "'\n"), \
228  (void)++unit_test_failures))
229 
230 
231 // Test if ImageBuf operation got an error. It's a lot like simply testing
232 // OIIO_CHECK_ASSERT(x), but if x is false, it will get an error message
233 // from the buffer and incorporate it into the failure message.
234 // Call like this, for example:
235 // ImageBuf buf;
236 // OIIO_CHECK_IMAGEBUF_STATUS(buf,
237 // ImageBufAlgo::Func (buf, ...)
238 // );
239 #define OIIO_CHECK_IMAGEBUF_STATUS(buf, x) \
240  ((x && !buf.has_error()) \
241  ? ((void)0) \
242  : ((std::cout << OIIO::Sysutil::Term(std::cout).ansi("red,bold") \
243  << __FILE__ << ":" << __LINE__ << ":\n" \
244  << "FAILED: " \
245  << OIIO::Sysutil::Term(std::cout).ansi("normal") << #x \
246  << ": " << buf.geterror() << "\n"), \
247  (void)++unit_test_failures))
vint4 max(const vint4 &a, const vint4 &b)
Definition: simd.h:4845
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:4822
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:55
GLint GLenum GLint x
Definition: glcorearb.h:409
const UnitTestFailureCounter & operator++() noexcept
Definition: unittest.h:50
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 const
Definition: zconf.h:214
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:94
Classes for SIMD processing.
UnitTestFailureCounter operator+=(int i) noexcept
Definition: unittest.h:56
auto join(It begin, Sentinel end, string_view sep) -> join_view< It, Sentinel >
Definition: format.h:2559
#define OIIO_NAMESPACE_BEGIN
Definition: oiioversion.h:93
bool equal_approx(const X &x, const Y &y)
Definition: unittest.h:70