1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_TESTING_FAKE_CLOCK_H
16 #define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_TESTING_FAKE_CLOCK_H
17 
18 #include "google/cloud/spanner/internal/clock.h"
19 #include "google/cloud/spanner/version.h"
20 #include <chrono>
21 #include <mutex>
22 
23 namespace google {
24 namespace cloud {
25 namespace spanner_testing {
26 inline namespace SPANNER_CLIENT_NS {
27 
28 /**
29  * A fake clock intended for use in tests.
30  *
31  * The `time_point` returned from `Now()` only changes via explicit calls to
32  * `SetTime` or `AdvanceTime`.
33  *
34  * `RealClock` should be an `internal::Clock<TrivialClock>` type that is being
35  * faked - see `internal/clock.h` for details.
36  */
37 template <typename RealClock>
38 class FakeClock : public RealClock {
39  public:
40   using time_point = typename RealClock::time_point;
41   using duration = typename RealClock::duration;
42 
Now()43   time_point Now() const override {
44     std::lock_guard<std::mutex> lock(mu_);
45     return now_;
46   }
47 
48   /// Sets the time to `now`.
SetTime(time_point now)49   void SetTime(time_point now) {
50     std::lock_guard<std::mutex> lock(mu_);
51     now_ = now;
52   }
53   /// Advances the time by `increment`.
AdvanceTime(duration increment)54   void AdvanceTime(duration increment) {
55     std::lock_guard<std::mutex> lock(mu_);
56     now_ += increment;
57   }
58 
59  private:
60   mutable std::mutex mu_;
61   time_point now_;
62 };
63 
64 using FakeSteadyClock =
65     FakeClock<google::cloud::spanner::internal::SteadyClock>;
66 
67 using FakeSystemClock =
68     FakeClock<google::cloud::spanner::internal::SystemClock>;
69 
70 }  // namespace SPANNER_CLIENT_NS
71 }  // namespace spanner_testing
72 }  // namespace cloud
73 }  // namespace google
74 
75 #endif  // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_SPANNER_TESTING_FAKE_CLOCK_H
76