1// -*- C++ -*- 2// Utility subroutines for the C++ library testsuite. 3// 4// Copyright (C) 2000-2015 Free Software Foundation, Inc. 5// 6// This file is part of the GNU ISO C++ Library. This library is free 7// software; you can redistribute it and/or modify it under the 8// terms of the GNU General Public License as published by the 9// Free Software Foundation; either version 3, or (at your option) 10// any later version. 11// 12// This library is distributed in the hope that it will be useful, 13// but WITHOUT ANY WARRANTY; without even the implied warranty of 14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15// GNU General Public License for more details. 16// 17// You should have received a copy of the GNU General Public License along 18// with this library; see the file COPYING3. If not see 19// <http://www.gnu.org/licenses/>. 20// 21 22// This file provides the following: 23// 24// 1) VERIFY(), via _GLIBCXX_ASSERT, from Brent Verner <brent@rcfile.org>. 25// This file is included in the various testsuite programs to provide 26// #define(able) assert() behavior for debugging/testing. It may be 27// a suitable location for other furry woodland creatures as well. 28// 29// 2) set_memory_limits() 30// set_memory_limits() uses setrlimit() to restrict dynamic memory 31// allocation. We provide a default memory limit if none is passed by the 32// calling application. The argument to set_memory_limits() is the 33// limit in megabytes (a floating-point number). If _GLIBCXX_RES_LIMITS is 34// not #defined before including this header, then no limiting is attempted. 35// 36// 3) object_counter 37// This is a POD with a static data member, object_counter::count, 38// which starts at zero, increments on instance construction, and decrements 39// on instance destruction. "assert_count(n)" can be called to VERIFY() 40// that the count equals N. 41// 42// 4) copy_tracker, from Stephen M. Webb <stephen@bregmasoft.com>. 43// A class with nontrivial ctor/dtor that provides the ability to track the 44// number of copy ctors and dtors, and will throw on demand during copy. 45 46#ifndef _GLIBCXX_TESTSUITE_HOOKS_H 47#define _GLIBCXX_TESTSUITE_HOOKS_H 48 49#include <bits/c++config.h> 50#include <bits/functexcept.h> 51#include <ctime> 52 53#ifdef _GLIBCXX_HAVE_SYS_STAT_H 54#include <sys/stat.h> 55#endif 56 57#ifdef _GLIBCXX_ASSERT 58# include <cassert> 59# define VERIFY(fn) assert(fn) 60#else 61# define VERIFY(fn) test &= bool(fn) 62#endif 63 64#ifdef _GLIBCXX_HAVE_UNISTD_H 65# include <unistd.h> 66#else 67# define unlink(x) 68#endif 69 70namespace __gnu_test 71{ 72 // All macros are defined in GLIBCXX_CONFIGURE_TESTSUITE and imported 73 // from c++config.h 74 75 // Set memory limits if possible, if not set to 0. 76#ifndef _GLIBCXX_RES_LIMITS 77# define MEMLIMIT_MB 0 78#else 79# ifndef MEMLIMIT_MB 80# define MEMLIMIT_MB 16.0 81# endif 82#endif 83 extern void 84 set_memory_limits(float __size = MEMLIMIT_MB); 85 86 extern void 87 set_file_limit(unsigned long __size); 88 89 // Check mangled name demangles (using __cxa_demangle) as expected. 90 void 91 verify_demangle(const char* mangled, const char* wanted); 92 93 // Simple callback structure for variable numbers of tests (all with 94 // same signature). Assume all unit tests are of the signature 95 // void test01(); 96 class func_callback 97 { 98 public: 99 typedef void (*test_type) (void); 100 101 private: 102 int _M_size; 103 test_type _M_tests[15]; 104 105 func_callback& 106 operator=(const func_callback&); 107 108 func_callback(const func_callback&); 109 110 public: 111 func_callback(): _M_size(0) { } 112 113 int 114 size() const { return _M_size; } 115 116 const test_type* 117 tests() const { return _M_tests; } 118 119 void 120 push_back(test_type test) 121 { 122 _M_tests[_M_size] = test; 123 ++_M_size; 124 } 125 }; 126 127 128 // Run select unit tests after setting global locale. 129 void 130 run_tests_wrapped_locale(const char*, const func_callback&); 131 132 // Run select unit tests after setting environment variables. 133 void 134 run_tests_wrapped_env(const char*, const char*, const func_callback&); 135 136 // Counting. 137 struct object_counter 138 { 139 // Specifically and glaringly-obviously marked 'signed' so that 140 // when COUNT mistakenly goes negative, we can track the patterns 141 // of deletions more easily. 142 typedef signed int size_type; 143 static size_type count; 144 object_counter() { ++count; } 145 object_counter (const object_counter&) { ++count; } 146 ~object_counter() { --count; } 147 }; 148 149#define assert_count(n) VERIFY(__gnu_test::object_counter::count == n) 150 151 // A (static) class for counting copy constructors and possibly throwing an 152 // exception on a desired count. 153 class copy_constructor 154 { 155 public: 156 static unsigned int 157 count() { return count_; } 158 159 static void 160 mark_call() 161 { 162 count_++; 163 if (count_ == throw_on_) 164 std::__throw_runtime_error("copy_constructor::mark_call"); 165 } 166 167 static void 168 reset() 169 { 170 count_ = 0; 171 throw_on_ = 0; 172 } 173 174 static void 175 throw_on(unsigned int count) { throw_on_ = count; } 176 177 private: 178 static unsigned int count_; 179 static unsigned int throw_on_; 180 }; 181 182 // A (static) class for counting assignment operator calls and 183 // possibly throwing an exception on a desired count. 184 class assignment_operator 185 { 186 public: 187 static unsigned int 188 count() { return count_; } 189 190 static void 191 mark_call() 192 { 193 count_++; 194 if (count_ == throw_on_) 195 std::__throw_runtime_error("assignment_operator::mark_call"); 196 } 197 198 static void 199 reset() 200 { 201 count_ = 0; 202 throw_on_ = 0; 203 } 204 205 static void 206 throw_on(unsigned int count) { throw_on_ = count; } 207 208 private: 209 static unsigned int count_; 210 static unsigned int throw_on_; 211 }; 212 213 // A (static) class for tracking calls to an object's destructor. 214 class destructor 215 { 216 public: 217 static unsigned int 218 count() { return _M_count; } 219 220 static void 221 mark_call() { _M_count++; } 222 223 static void 224 reset() { _M_count = 0; } 225 226 private: 227 static unsigned int _M_count; 228 }; 229 230 // An class of objects that can be used for validating various 231 // behaviours and guarantees of containers and algorithms defined in 232 // the standard library. 233 class copy_tracker 234 { 235 public: 236 // Creates a copy-tracking object with the given ID number. If 237 // "throw_on_copy" is set, an exception will be thrown if an 238 // attempt is made to copy this object. 239 copy_tracker(int id = next_id_--, bool throw_on_copy = false) 240 : id_(id) , throw_on_copy_(throw_on_copy) { } 241 242 // Copy-constructs the object, marking a call to the copy 243 // constructor and forcing an exception if indicated. 244 copy_tracker(const copy_tracker& rhs) 245 : id_(rhs.id()), throw_on_copy_(rhs.throw_on_copy_) 246 { 247 if (throw_on_copy_) 248 copy_constructor::throw_on(copy_constructor::count() + 1); 249 copy_constructor::mark_call(); 250 } 251 252 // Assigns the value of another object to this one, tracking the 253 // number of times this member function has been called and if the 254 // other object is supposed to throw an exception when it is 255 // copied, well, make it so. 256 copy_tracker& 257 operator=(const copy_tracker& rhs) 258 { 259 id_ = rhs.id(); 260 if (rhs.throw_on_copy_) 261 assignment_operator::throw_on(assignment_operator::count() + 1); 262 assignment_operator::mark_call(); 263 return *this; 264 } 265 266 ~copy_tracker() 267 { destructor::mark_call(); } 268 269 int 270 id() const { return id_; } 271 272 static void 273 reset() 274 { 275 copy_constructor::reset(); 276 assignment_operator::reset(); 277 destructor::reset(); 278 } 279 280 private: 281 int id_; 282 const bool throw_on_copy_; 283 static int next_id_; 284 }; 285 286 inline bool 287 operator==(const copy_tracker& lhs, const copy_tracker& rhs) 288 { return lhs.id() == rhs.id(); } 289 290 inline bool 291 operator<(const copy_tracker& lhs, const copy_tracker& rhs) 292 { return lhs.id() < rhs.id(); } 293 294 // Class for checking required type conversions, implicit and 295 // explicit for given library data structures. 296 template<typename _Container> 297 struct conversion 298 { 299 typedef typename _Container::const_iterator const_iterator; 300 301 // Implicit conversion iterator to const_iterator. 302 static const_iterator 303 iterator_to_const_iterator() 304 { 305 _Container v; 306 const_iterator it = v.begin(); 307 const_iterator end = v.end(); 308 return it == end ? v.end() : it; 309 } 310 }; 311 312 // A binary semaphore for use across multiple processes. 313 class semaphore 314 { 315 public: 316 // Creates a binary semaphore. The semaphore is initially in the 317 // unsignaled state. 318 semaphore(); 319 320 // Destroy the semaphore. 321 ~semaphore(); 322 323 // Signal the semaphore. If there are processes blocked in 324 // "wait", exactly one will be permitted to proceed. 325 void signal(); 326 327 // Wait until the semaphore is signaled. 328 void wait(); 329 330 private: 331 int sem_set_; 332 333 pid_t pid_; 334 }; 335 336 // For use in 22_locale/time_get and time_put. 337 std::tm test_tm(int sec, int min, int hour, int mday, int mon, 338 int year, int wday, int yday, int isdst); 339 340} // namespace __gnu_test 341 342#endif // _GLIBCXX_TESTSUITE_HOOKS_H 343 344