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