• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2008 Google Inc.
2 // Authors: Craig Silverstein, Lincoln Smith
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #ifndef OPEN_VCDIFF_TESTING_H_
17 #define OPEN_VCDIFF_TESTING_H_
18 
19 #include <config.h>
20 #include <assert.h>
21 #include <stdint.h>  // int64_t
22 #include <stdlib.h>  // rand
23 #include <time.h>  // gettimeofday
24 #include "gtest/gtest.h"
25 
26 #ifdef HAVE_SYS_TIME_H
27 #include <sys/time.h>  // struct timeval
28 #endif  // HAVE_SYS_TIME_H
29 
30 #ifdef HAVE_WINDOWS_H
31 #include <windows.h>  // QueryPerformanceCounter
32 #endif  // HAVE_WINDOWS_H
33 
34 // CHECK is used for assertions that verify the consistency of the test itself,
35 // rather than correctness of the code that is being tested.
36 //
37 // It is better to use a preprocessor macro for CHECK
38 // than an inline function, because assert() may report
39 // the source file and line where the failure occurred.
40 //
41 // Putting parentheses around the macro arguments
42 // (e.g. "assert((X) == (Y))") would be good practice
43 // but would produce error messages that are inconsistent
44 // with those expected in the unit tests.
45 
46 #define CHECK(CONDITION) assert(CONDITION)
47 #define CHECK_EQ(X, Y) assert(X == Y)
48 #define CHECK_NE(X, Y) assert(X != Y)
49 #define CHECK_GE(X, Y) assert(X >= Y)
50 #define CHECK_GT(X, Y) assert(X > Y)
51 #define CHECK_LE(X, Y) assert(X <= Y)
52 #define CHECK_LT(X, Y) assert(X < Y)
53 
54 namespace open_vcdiff {
55 
56 // Support for timing tests
57 #if defined(HAVE_GETTIMEOFDAY)
58 class CycleTimer {
59  public:
CycleTimer()60   inline CycleTimer() {
61     Reset();
62   }
63 
Reset()64   inline void Reset() {
65     start_time_.tv_sec = 0;
66     start_time_.tv_usec = 0;
67     cumulative_time_in_usec_ = 0;
68   }
69 
Start()70   inline void Start() {
71     CHECK(!IsStarted());
72     gettimeofday(&start_time_, NULL);
73   }
74 
Restart()75   inline void Restart() {
76     Reset();
77     Start();
78   }
79 
Stop()80   inline void Stop() {
81     struct timeval end_time;
82     gettimeofday(&end_time, NULL);
83     CHECK(IsStarted());
84     cumulative_time_in_usec_ +=
85         (1000000 * (end_time.tv_sec - start_time_.tv_sec))
86         + end_time.tv_usec - start_time_.tv_usec;
87     start_time_.tv_sec = 0;
88     start_time_.tv_usec = 0;
89   }
90 
GetInUsec()91   inline int64_t GetInUsec() {
92     return cumulative_time_in_usec_;
93   }
94 
95  private:
IsStarted()96   inline bool IsStarted() {
97     return (start_time_.tv_usec > 0) || (start_time_.tv_sec > 0);
98   }
99 
100   struct timeval start_time_;
101   int64_t cumulative_time_in_usec_;
102 };
103 #elif defined(HAVE_QUERYPERFORMANCECOUNTER)
104 class CycleTimer {
105  public:
106   inline CycleTimer() {
107     LARGE_INTEGER frequency;
108     QueryPerformanceFrequency(&frequency);  // counts per second
109     usecs_per_count_ = 1000000.0 / static_cast<double>(frequency.QuadPart);
110     Reset();
111   }
112 
113   inline void Reset() {
114     start_time_.QuadPart = 0;
115     cumulative_time_in_usec_ = 0;
116   }
117 
118   inline void Start() {
119     CHECK(!IsStarted());
120     QueryPerformanceCounter(&start_time_);
121   }
122 
123   inline void Restart() {
124     Reset();
125     Start();
126   }
127 
128   inline void Stop() {
129     LARGE_INTEGER end_time;
130     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 //
162 template<typename IntType>
PortableRandomInRange(IntType limit)163 inline 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