1 | /* |
2 | * Copyright 2014-present Facebook, Inc. |
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 | #pragma once |
17 | |
18 | #include <chrono> |
19 | #include <iosfwd> |
20 | |
21 | #include <folly/portability/SysTypes.h> |
22 | |
23 | namespace folly { |
24 | |
25 | /** |
26 | * A class for tracking time durations in test code. |
27 | * |
28 | * This is primarily useful for testing timeout functionality. When comparing |
29 | * the differences between two TimePoints, it can exclude time spent waiting on |
30 | * the OS scheduler. This helps avoid spurious test failures when timeouts are |
31 | * exceeded by longer than expected simply because the underlying system was |
32 | * busy and could not schedule this thread in time. |
33 | */ |
34 | class TimePoint { |
35 | public: |
36 | explicit TimePoint(bool set = true) : tid_(0) { |
37 | if (set) { |
38 | reset(); |
39 | } |
40 | } |
41 | |
42 | void reset(); |
43 | |
44 | bool isUnset() const { |
45 | return ( |
46 | timeStart_.time_since_epoch().count() == 0 && |
47 | timeEnd_.time_since_epoch().count() == 0 && timeWaiting_.count() == 0); |
48 | } |
49 | |
50 | std::chrono::steady_clock::time_point getTime() const { |
51 | return timeStart_; |
52 | } |
53 | |
54 | std::chrono::steady_clock::time_point getTimeStart() const { |
55 | return timeStart_; |
56 | } |
57 | |
58 | std::chrono::steady_clock::time_point getTimeEnd() const { |
59 | return timeStart_; |
60 | } |
61 | |
62 | std::chrono::nanoseconds getTimeWaiting() const { |
63 | return timeWaiting_; |
64 | } |
65 | |
66 | pid_t getTid() const { |
67 | return tid_; |
68 | } |
69 | |
70 | private: |
71 | std::chrono::steady_clock::time_point timeStart_; |
72 | std::chrono::steady_clock::time_point timeEnd_; |
73 | std::chrono::nanoseconds timeWaiting_{0}; |
74 | pid_t tid_; |
75 | }; |
76 | |
77 | std::ostream& operator<<(std::ostream& os, const TimePoint& timePoint); |
78 | |
79 | bool checkTimeout( |
80 | const TimePoint& start, |
81 | const TimePoint& end, |
82 | std::chrono::nanoseconds expected, |
83 | bool allowSmaller, |
84 | std::chrono::nanoseconds tolerance = std::chrono::milliseconds(5)); |
85 | } // namespace folly |
86 | |