1311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Copyright 2008 Google Inc. 2311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Authors: Craig Silverstein, Lincoln Smith 3311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// 4311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Licensed under the Apache License, Version 2.0 (the "License"); 5311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// you may not use this file except in compliance with the License. 6311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// You may obtain a copy of the License at 7311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// 8311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// http://www.apache.org/licenses/LICENSE-2.0 9311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// 10311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Unless required by applicable law or agreed to in writing, software 11311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// distributed under the License is distributed on an "AS IS" BASIS, 12311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// See the License for the specific language governing permissions and 14311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// limitations under the License. 15311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 16311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#ifndef OPEN_VCDIFF_TESTING_H_ 17311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define OPEN_VCDIFF_TESTING_H_ 18311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 19311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include <config.h> 2028db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff#include <assert.h> 2128db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff#include <stdint.h> // int64_t 2228db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff#include <stdlib.h> // rand 23311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include <time.h> // gettimeofday 24311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include "gtest/gtest.h" 25311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 26311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#ifdef HAVE_SYS_TIME_H 27311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include <sys/time.h> // struct timeval 28311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#endif // HAVE_SYS_TIME_H 29311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 30311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#ifdef HAVE_WINDOWS_H 31311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include <windows.h> // QueryPerformanceCounter 32311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#endif // HAVE_WINDOWS_H 33311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 34311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// CHECK is used for assertions that verify the consistency of the test itself, 35311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// rather than correctness of the code that is being tested. 36311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// 37311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// It is better to use a preprocessor macro for CHECK 38311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// than an inline function, because assert() may report 39311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// the source file and line where the failure occurred. 40311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// 41311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Putting parentheses around the macro arguments 42311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// (e.g. "assert((X) == (Y))") would be good practice 43311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// but would produce error messages that are inconsistent 44311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// with those expected in the unit tests. 45311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 46311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define CHECK(CONDITION) assert(CONDITION) 47311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define CHECK_EQ(X, Y) assert(X == Y) 48311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define CHECK_NE(X, Y) assert(X != Y) 49311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define CHECK_GE(X, Y) assert(X >= Y) 50311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define CHECK_GT(X, Y) assert(X > Y) 51311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define CHECK_LE(X, Y) assert(X <= Y) 52311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define CHECK_LT(X, Y) assert(X < Y) 53311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 54311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffnamespace open_vcdiff { 55311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 56311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Support for timing tests 57311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#if defined(HAVE_GETTIMEOFDAY) 58311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffclass CycleTimer { 59311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff public: 60311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff inline CycleTimer() { 61311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff Reset(); 62311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 63311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 64311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff inline void Reset() { 65311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff start_time_.tv_sec = 0; 66311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff start_time_.tv_usec = 0; 67311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff cumulative_time_in_usec_ = 0; 68311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 69311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 70311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff inline void Start() { 71311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff CHECK(!IsStarted()); 72311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff gettimeofday(&start_time_, NULL); 73311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 74311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 75311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff inline void Restart() { 76311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff Reset(); 77311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff Start(); 78311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 79311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 80311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff inline void Stop() { 81311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff struct timeval end_time; 82311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff gettimeofday(&end_time, NULL); 83311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff CHECK(IsStarted()); 84311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff cumulative_time_in_usec_ += 85311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff (1000000 * (end_time.tv_sec - start_time_.tv_sec)) 86311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff + end_time.tv_usec - start_time_.tv_usec; 87311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff start_time_.tv_sec = 0; 88311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff start_time_.tv_usec = 0; 89311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 90311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 91311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff inline int64_t GetInUsec() { 92311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return cumulative_time_in_usec_; 93311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 94311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 95311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff private: 96311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff inline bool IsStarted() { 97311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return (start_time_.tv_usec > 0) || (start_time_.tv_sec > 0); 98311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 99311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 100311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff struct timeval start_time_; 101311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff int64_t cumulative_time_in_usec_; 102311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff}; 103311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#elif defined(HAVE_QUERYPERFORMANCECOUNTER) 104311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffclass CycleTimer { 105311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff public: 106311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff inline CycleTimer() { 107311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff LARGE_INTEGER frequency; 108311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff QueryPerformanceFrequency(&frequency); // counts per second 109311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff usecs_per_count_ = 1000000.0 / static_cast<double>(frequency.QuadPart); 110311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff Reset(); 111311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 112311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 113311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff inline void Reset() { 114311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff start_time_.QuadPart = 0; 115311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff cumulative_time_in_usec_ = 0; 116311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 117311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 118311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff inline void Start() { 119311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff CHECK(!IsStarted()); 120311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff QueryPerformanceCounter(&start_time_); 121311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 122311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 123311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff inline void Restart() { 124311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff Reset(); 125311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff Start(); 126311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 127311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 128311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff inline void Stop() { 129311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff LARGE_INTEGER end_time; 130311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff QueryPerformanceCounter(&end_time); 131311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff CHECK(IsStarted()); 132311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff double count_diff = static_cast<double>( 133311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff end_time.QuadPart - start_time_.QuadPart); 134311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff cumulative_time_in_usec_ += 135311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff static_cast<int64_t>(count_diff * usecs_per_count_); 136311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff start_time_.QuadPart = 0; 137311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 138311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 139311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff inline int64_t GetInUsec() { 140311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return cumulative_time_in_usec_; 141311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 142311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 143311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff private: 144311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff inline bool IsStarted() { 145311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return start_time_.QuadPart > 0; 146311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 147311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 148311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff LARGE_INTEGER start_time_; 149311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff int64_t cumulative_time_in_usec_; 150311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff double usecs_per_count_; 151311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff}; 152311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#else 153311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#error CycleTimer needs an implementation that does not use gettimeofday or QueryPerformanceCounter 154311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#endif // HAVE_GETTIMEOFDAY 155311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 156311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// This function returns a pseudo-random value of type IntType between 0 and 157311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// limit. It uses the standard rand() function to produce the value, and makes 158311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// as many calls to rand() as needed to ensure that the values returned can fall 159311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// within the full range specified. It is slow, so don't include calls to this 160311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// function when calculating the execution time of tests. 161311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// 162311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdifftemplate<typename IntType> 163311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffinline IntType PortableRandomInRange(IntType limit) { 164311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff uint64_t value = rand(); 165311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff double rand_limit = RAND_MAX; // The maximum possible value 166311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff while (rand_limit < limit) { 167311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // value is multiplied by (RAND_MAX + 1) each iteration. This factor will be 168311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // canceled out when we divide by rand_limit to get scaled_value, below. 169311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff value = (value * (static_cast<uint64_t>(RAND_MAX) + 1)) + rand(); 170311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff rand_limit = (rand_limit * (RAND_MAX + 1.0)) + RAND_MAX; 171311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 172311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // Translate the random 64-bit integer into a floating-point value between 173311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff // 0.0 (inclusive) and 1.0 (inclusive). 174311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff const double scaled_value = value / rand_limit; 175311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return static_cast<IntType>(limit * scaled_value); 176311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 177311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 178311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} // namespace open_vcdiff 179311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 180311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#endif // OPEN_VCDIFF_TESTING_H_ 181