1a5728872c7702ddd09537c95bc3cbd20e1f2fb09Daniel Dunbar// Copyright 2008 Google Inc. 235080844d3e634c7c1b2875f476ab5f697eece61Chris Lattner// Authors: Craig Silverstein, Lincoln Smith 335080844d3e634c7c1b2875f476ab5f697eece61Chris Lattner// 435080844d3e634c7c1b2875f476ab5f697eece61Chris Lattner// Licensed under the Apache License, Version 2.0 (the "License"); 535080844d3e634c7c1b2875f476ab5f697eece61Chris Lattner// you may not use this file except in compliance with the License. 635080844d3e634c7c1b2875f476ab5f697eece61Chris Lattner// You may obtain a copy of the License at 735080844d3e634c7c1b2875f476ab5f697eece61Chris Lattner// 835080844d3e634c7c1b2875f476ab5f697eece61Chris Lattner// http://www.apache.org/licenses/LICENSE-2.0 935080844d3e634c7c1b2875f476ab5f697eece61Chris Lattner// 1035080844d3e634c7c1b2875f476ab5f697eece61Chris Lattner// Unless required by applicable law or agreed to in writing, software 1135080844d3e634c7c1b2875f476ab5f697eece61Chris Lattner// distributed under the License is distributed on an "AS IS" BASIS, 12baf0d6678418e0dd9309438c3e50274253cfc7b2Chris Lattner// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13baf0d6678418e0dd9309438c3e50274253cfc7b2Chris Lattner// See the License for the specific language governing permissions and 14baf0d6678418e0dd9309438c3e50274253cfc7b2Chris Lattner// limitations under the License. 15baf0d6678418e0dd9309438c3e50274253cfc7b2Chris Lattner 16baf0d6678418e0dd9309438c3e50274253cfc7b2Chris Lattner#ifndef OPEN_VCDIFF_TESTING_H_ 17baf0d6678418e0dd9309438c3e50274253cfc7b2Chris Lattner#define OPEN_VCDIFF_TESTING_H_ 182c15647dce6de66f673cc64236913732d6289317Chris Lattner 192c15647dce6de66f673cc64236913732d6289317Chris Lattner#include <config.h> 202c15647dce6de66f673cc64236913732d6289317Chris Lattner#include <assert.h> 212c15647dce6de66f673cc64236913732d6289317Chris Lattner#include <stdint.h> // int64_t 222c15647dce6de66f673cc64236913732d6289317Chris Lattner#include <stdlib.h> // rand 23399bd1bc2b801ad85e4575e2401bb43919fcbee8Chris Lattner#include <time.h> // gettimeofday 242c15647dce6de66f673cc64236913732d6289317Chris Lattner#include "gtest/gtest.h" 25399bd1bc2b801ad85e4575e2401bb43919fcbee8Chris Lattner 26399bd1bc2b801ad85e4575e2401bb43919fcbee8Chris Lattner#ifdef HAVE_SYS_TIME_H 27399bd1bc2b801ad85e4575e2401bb43919fcbee8Chris Lattner#include <sys/time.h> // struct timeval 283e87209798bcc3fe39254c1b700b0c8251623b98Chris Lattner#endif // HAVE_SYS_TIME_H 293e87209798bcc3fe39254c1b700b0c8251623b98Chris Lattner 303e87209798bcc3fe39254c1b700b0c8251623b98Chris Lattner#ifdef HAVE_WINDOWS_H 313e87209798bcc3fe39254c1b700b0c8251623b98Chris Lattner#include <windows.h> // QueryPerformanceCounter 322c15647dce6de66f673cc64236913732d6289317Chris Lattner#endif // HAVE_WINDOWS_H 332c15647dce6de66f673cc64236913732d6289317Chris Lattner 34ca354faa7e9b99af17070c82b9662a5fca76422cChris Lattner// CHECK is used for assertions that verify the consistency of the test itself, 35ca354faa7e9b99af17070c82b9662a5fca76422cChris Lattner// rather than correctness of the code that is being tested. 36ca354faa7e9b99af17070c82b9662a5fca76422cChris Lattner// 3744e35f7b2b5da1eb338639e46bf0b5522e75c5f3Daniel Dunbar// It is better to use a preprocessor macro for CHECK 3844e35f7b2b5da1eb338639e46bf0b5522e75c5f3Daniel Dunbar// than an inline function, because assert() may report 39ca354faa7e9b99af17070c82b9662a5fca76422cChris Lattner// the source file and line where the failure occurred. 40ca354faa7e9b99af17070c82b9662a5fca76422cChris Lattner// 41b1b4d337fafe30823b581cbfaa1641f37541fffeChris Lattner// Putting parentheses around the macro arguments 42b1b4d337fafe30823b581cbfaa1641f37541fffeChris Lattner// (e.g. "assert((X) == (Y))") would be good practice 43b1b4d337fafe30823b581cbfaa1641f37541fffeChris Lattner// but would produce error messages that are inconsistent 44b1b4d337fafe30823b581cbfaa1641f37541fffeChris Lattner// with those expected in the unit tests. 457ca14257731eedb4cd16104cc20a6813d2deb0dbChris Lattner 467ca14257731eedb4cd16104cc20a6813d2deb0dbChris Lattner#define CHECK(CONDITION) assert(CONDITION) 477ca14257731eedb4cd16104cc20a6813d2deb0dbChris Lattner#define CHECK_EQ(X, Y) assert(X == Y) 487ca14257731eedb4cd16104cc20a6813d2deb0dbChris Lattner#define CHECK_NE(X, Y) assert(X != Y) 497ca14257731eedb4cd16104cc20a6813d2deb0dbChris Lattner#define CHECK_GE(X, Y) assert(X >= Y) 50670a62cd1d51042ea076cda5e93f26a1d8327fb3Chris Lattner#define CHECK_GT(X, Y) assert(X > Y) 51670a62cd1d51042ea076cda5e93f26a1d8327fb3Chris Lattner#define CHECK_LE(X, Y) assert(X <= Y) 52670a62cd1d51042ea076cda5e93f26a1d8327fb3Chris Lattner#define CHECK_LT(X, Y) assert(X < Y) 53670a62cd1d51042ea076cda5e93f26a1d8327fb3Chris Lattner 54eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedmannamespace open_vcdiff { 55670a62cd1d51042ea076cda5e93f26a1d8327fb3Chris Lattner 56670a62cd1d51042ea076cda5e93f26a1d8327fb3Chris Lattner// Support for timing tests 5731e21e05623ce9d11b1a893fecb87ad349df6c7dChris Lattner#if defined(HAVE_GETTIMEOFDAY) 5831e21e05623ce9d11b1a893fecb87ad349df6c7dChris Lattnerclass CycleTimer { 5931e21e05623ce9d11b1a893fecb87ad349df6c7dChris Lattner public: 6031e21e05623ce9d11b1a893fecb87ad349df6c7dChris Lattner inline CycleTimer() { 6131e21e05623ce9d11b1a893fecb87ad349df6c7dChris Lattner Reset(); 62da0274725667d1168867dc404417f2c68c8dc0c5Chris Lattner } 6331fddcca28ffb7a569ee8f5d565a856827d92adaAnders Carlsson 64eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman inline void Reset() { 6531fddcca28ffb7a569ee8f5d565a856827d92adaAnders Carlsson start_time_.tv_sec = 0; 66da0274725667d1168867dc404417f2c68c8dc0c5Chris Lattner start_time_.tv_usec = 0; 6731e21e05623ce9d11b1a893fecb87ad349df6c7dChris Lattner cumulative_time_in_usec_ = 0; 6831e21e05623ce9d11b1a893fecb87ad349df6c7dChris Lattner } 6956cd21bd52aed7a32f3ff11b7e480f664d0b4262Chris Lattner 7056cd21bd52aed7a32f3ff11b7e480f664d0b4262Chris Lattner inline void Start() { 7156cd21bd52aed7a32f3ff11b7e480f664d0b4262Chris Lattner CHECK(!IsStarted()); 7256cd21bd52aed7a32f3ff11b7e480f664d0b4262Chris Lattner gettimeofday(&start_time_, NULL); 7356cd21bd52aed7a32f3ff11b7e480f664d0b4262Chris Lattner } 7456cd21bd52aed7a32f3ff11b7e480f664d0b4262Chris Lattner 7556cd21bd52aed7a32f3ff11b7e480f664d0b4262Chris Lattner inline void Restart() { 76d0344a4a6182ad704881cbbaa21cca14913d2296Chris Lattner Reset(); 77d0344a4a6182ad704881cbbaa21cca14913d2296Chris Lattner Start(); 78d0344a4a6182ad704881cbbaa21cca14913d2296Chris Lattner } 79d0344a4a6182ad704881cbbaa21cca14913d2296Chris Lattner 80d0344a4a6182ad704881cbbaa21cca14913d2296Chris Lattner inline void Stop() { 8155660a74897bf42111a8ae61c1f617645e5a9274Chris Lattner struct timeval end_time; 826409625011e4a11ff07956ff46a44d6ca4473992Argyrios Kyrtzidis gettimeofday(&end_time, NULL); 83d0344a4a6182ad704881cbbaa21cca14913d2296Chris Lattner CHECK(IsStarted()); 84d0344a4a6182ad704881cbbaa21cca14913d2296Chris Lattner cumulative_time_in_usec_ += 8555660a74897bf42111a8ae61c1f617645e5a9274Chris Lattner (1000000 * (end_time.tv_sec - start_time_.tv_sec)) 8655660a74897bf42111a8ae61c1f617645e5a9274Chris Lattner + end_time.tv_usec - start_time_.tv_usec; 87466a7f8aa61ca0d1df1f11ed2dfb2510a386cfa6Chris Lattner start_time_.tv_sec = 0; 8855660a74897bf42111a8ae61c1f617645e5a9274Chris Lattner start_time_.tv_usec = 0; 8955660a74897bf42111a8ae61c1f617645e5a9274Chris Lattner } 90d1e4d9bfd57f643d950eb1373f582bda4dfb8dc7Douglas Gregor 91d1e4d9bfd57f643d950eb1373f582bda4dfb8dc7Douglas Gregor inline int64_t GetInUsec() { 92d1e4d9bfd57f643d950eb1373f582bda4dfb8dc7Douglas Gregor return cumulative_time_in_usec_; 93d1e4d9bfd57f643d950eb1373f582bda4dfb8dc7Douglas Gregor } 949af5500f3f132f9a2f9abbe82113a7c7bb751472Chris Lattner 959af5500f3f132f9a2f9abbe82113a7c7bb751472Chris Lattner private: 969af5500f3f132f9a2f9abbe82113a7c7bb751472Chris Lattner inline bool IsStarted() { 979af5500f3f132f9a2f9abbe82113a7c7bb751472Chris Lattner return (start_time_.tv_usec > 0) || (start_time_.tv_sec > 0); 989af5500f3f132f9a2f9abbe82113a7c7bb751472Chris Lattner } 999af5500f3f132f9a2f9abbe82113a7c7bb751472Chris Lattner 100d013aa1ee78d8ead93179c179b7c0746e8d97dbbChris Lattner struct timeval start_time_; 101d013aa1ee78d8ead93179c179b7c0746e8d97dbbChris Lattner int64_t cumulative_time_in_usec_; 102eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman}; 103eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman#elif defined(HAVE_QUERYPERFORMANCECOUNTER) 104d013aa1ee78d8ead93179c179b7c0746e8d97dbbChris Lattnerclass CycleTimer { 1059c10fcfc3b9d2076efe701b60644a9987a93c503Chris Lattner public: 106d013aa1ee78d8ead93179c179b7c0746e8d97dbbChris Lattner inline CycleTimer() { 1079c10fcfc3b9d2076efe701b60644a9987a93c503Chris Lattner LARGE_INTEGER frequency; 108d013aa1ee78d8ead93179c179b7c0746e8d97dbbChris Lattner QueryPerformanceFrequency(&frequency); // counts per second 109d013aa1ee78d8ead93179c179b7c0746e8d97dbbChris Lattner usecs_per_count_ = 1000000.0 / static_cast<double>(frequency.QuadPart); 1100a026af6deb4a9e9f30ff047e04db56eb4333741Chris Lattner Reset(); 1110a026af6deb4a9e9f30ff047e04db56eb4333741Chris Lattner } 1120a026af6deb4a9e9f30ff047e04db56eb4333741Chris Lattner 1130a026af6deb4a9e9f30ff047e04db56eb4333741Chris Lattner inline void Reset() { 1140a026af6deb4a9e9f30ff047e04db56eb4333741Chris Lattner start_time_.QuadPart = 0; 1150a026af6deb4a9e9f30ff047e04db56eb4333741Chris Lattner cumulative_time_in_usec_ = 0; 1160a026af6deb4a9e9f30ff047e04db56eb4333741Chris Lattner } 1170a026af6deb4a9e9f30ff047e04db56eb4333741Chris Lattner 11802dd4b1e279114cc51422fab8b42a7759421800eChris Lattner inline void Start() { 11902dd4b1e279114cc51422fab8b42a7759421800eChris Lattner CHECK(!IsStarted()); 1200a026af6deb4a9e9f30ff047e04db56eb4333741Chris Lattner QueryPerformanceCounter(&start_time_); 1217ef655a78863c0a7550bfe51174b9c340ab1dce0Chris Lattner } 1227ef655a78863c0a7550bfe51174b9c340ab1dce0Chris Lattner 1237ef655a78863c0a7550bfe51174b9c340ab1dce0Chris Lattner inline void Restart() { 1247ef655a78863c0a7550bfe51174b9c340ab1dce0Chris Lattner Reset(); 1257ef655a78863c0a7550bfe51174b9c340ab1dce0Chris Lattner Start(); 1267ef655a78863c0a7550bfe51174b9c340ab1dce0Chris Lattner } 127cb329c506d0e041b9523618158ac925d620c24acChris Lattner 128cb329c506d0e041b9523618158ac925d620c24acChris Lattner inline void Stop() { 1297ef655a78863c0a7550bfe51174b9c340ab1dce0Chris Lattner LARGE_INTEGER end_time; 1307ef655a78863c0a7550bfe51174b9c340ab1dce0Chris Lattner QueryPerformanceCounter(&end_time); 131 CHECK(IsStarted()); 132 double count_diff = static_cast<double>( 133 end_time.QuadPart - start_time_.QuadPart); 134 cumulative_time_in_usec_ += 135 static_cast<int64_t>(count_diff * usecs_per_count_); 136 start_time_.QuadPart = 0; 137 } 138 139 inline int64_t GetInUsec() { 140 return cumulative_time_in_usec_; 141 } 142 143 private: 144 inline bool IsStarted() { 145 return start_time_.QuadPart > 0; 146 } 147 148 LARGE_INTEGER start_time_; 149 int64_t cumulative_time_in_usec_; 150 double usecs_per_count_; 151}; 152#else 153#error CycleTimer needs an implementation that does not use gettimeofday or QueryPerformanceCounter 154#endif // HAVE_GETTIMEOFDAY 155 156// This function returns a pseudo-random value of type IntType between 0 and 157// limit. It uses the standard rand() function to produce the value, and makes 158// as many calls to rand() as needed to ensure that the values returned can fall 159// within the full range specified. It is slow, so don't include calls to this 160// function when calculating the execution time of tests. 161// 162template<typename IntType> 163inline IntType PortableRandomInRange(IntType limit) { 164 uint64_t value = rand(); 165 double rand_limit = RAND_MAX; // The maximum possible value 166 while (rand_limit < limit) { 167 // value is multiplied by (RAND_MAX + 1) each iteration. This factor will be 168 // canceled out when we divide by rand_limit to get scaled_value, below. 169 value = (value * (static_cast<uint64_t>(RAND_MAX) + 1)) + rand(); 170 rand_limit = (rand_limit * (RAND_MAX + 1.0)) + RAND_MAX; 171 } 172 // Translate the random 64-bit integer into a floating-point value between 173 // 0.0 (inclusive) and 1.0 (inclusive). 174 const double scaled_value = value / rand_limit; 175 return static_cast<IntType>(limit * scaled_value); 176} 177 178} // namespace open_vcdiff 179 180#endif // OPEN_VCDIFF_TESTING_H_ 181