/build/source/nativelink-util/src/instant_wrapper.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2024 The NativeLink Authors. All rights reserved. |
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 | | use std::future::Future; |
16 | | use std::time::{Duration, SystemTime, UNIX_EPOCH}; |
17 | | |
18 | | use mock_instant::thread_local::{Instant as MockInstant, MockClock}; |
19 | | |
20 | | /// Wrapper used to abstract away which underlying Instant impl we are using. |
21 | | /// This is needed for testing. |
22 | | pub trait InstantWrapper: Send + Sync + Unpin + 'static { |
23 | | fn from_secs(secs: u64) -> Self; |
24 | | fn unix_timestamp(&self) -> u64; |
25 | | fn now(&self) -> SystemTime; |
26 | | fn elapsed(&self) -> Duration; |
27 | | fn sleep(self, duration: Duration) -> impl Future<Output = ()> + Send + Sync + 'static; |
28 | | } |
29 | | |
30 | | impl InstantWrapper for SystemTime { |
31 | 0 | fn from_secs(secs: u64) -> SystemTime { |
32 | 0 | SystemTime::UNIX_EPOCH |
33 | 0 | .checked_add(Duration::from_secs(secs)) |
34 | 0 | .unwrap() |
35 | 0 | } |
36 | | |
37 | 2 | fn unix_timestamp(&self) -> u64 { |
38 | 2 | self.duration_since(UNIX_EPOCH).unwrap().as_secs() |
39 | 2 | } |
40 | | |
41 | 0 | fn now(&self) -> SystemTime { |
42 | 0 | SystemTime::now() |
43 | 0 | } |
44 | | |
45 | 20.8k | fn elapsed(&self) -> Duration { |
46 | 20.8k | <SystemTime>::elapsed(self).unwrap() |
47 | 20.8k | } |
48 | | |
49 | 0 | async fn sleep(self, duration: Duration) { |
50 | 0 | tokio::time::sleep(duration).await; |
51 | 0 | } |
52 | | } |
53 | | |
54 | 0 | pub fn default_instant_wrapper() -> impl InstantWrapper { |
55 | 0 | SystemTime::now() |
56 | 0 | } |
57 | | |
58 | | /// Our mocked out instant that we can pass to our EvictionMap. |
59 | | pub struct MockInstantWrapped(MockInstant); |
60 | | |
61 | | impl Default for MockInstantWrapped { |
62 | 412 | fn default() -> Self { |
63 | 412 | Self(MockInstant::now()) |
64 | 412 | } |
65 | | } |
66 | | |
67 | | impl InstantWrapper for MockInstantWrapped { |
68 | 30 | fn from_secs(_secs: u64) -> Self { |
69 | 30 | MockInstantWrapped(MockInstant::now()) |
70 | 30 | } |
71 | | |
72 | 2 | fn unix_timestamp(&self) -> u64 { |
73 | 2 | MockClock::time().as_secs() |
74 | 2 | } |
75 | | |
76 | 110 | fn now(&self) -> SystemTime { |
77 | 110 | UNIX_EPOCH + MockClock::time() |
78 | 110 | } |
79 | | |
80 | 946 | fn elapsed(&self) -> Duration { |
81 | 946 | self.0.elapsed() |
82 | 946 | } |
83 | | |
84 | 213 | async fn sleep(self, duration: Duration) { |
85 | 162 | let baseline = self.0.elapsed(); |
86 | | loop { |
87 | 3.02k | tokio::task::yield_now().await2.97k ; |
88 | 2.97k | if self.0.elapsed() - baseline >= duration { Branch (88:16): [Folded - Ignored]
Branch (88:16): [Folded - Ignored]
Branch (88:16): [True: 0, False: 2]
Branch (88:16): [True: 113, False: 2.86k]
|
89 | 113 | break; |
90 | 2.86k | } |
91 | | } |
92 | 113 | } |
93 | | } |