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