Coverage Report

Created: 2024-10-22 12:33

/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
0
    fn unix_timestamp(&self) -> u64 {
38
0
        self.duration_since(UNIX_EPOCH).unwrap().as_secs()
39
0
    }
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
365
    fn default() -> Self {
63
365
        Self(MockInstant::now())
64
365
    }
65
}
66
67
impl InstantWrapper for MockInstantWrapped {
68
28
    fn from_secs(_secs: u64) -> Self {
69
28
        MockInstantWrapped(MockInstant::now())
70
28
    }
71
72
2
    fn unix_timestamp(&self) -> u64 {
73
2
        MockClock::time().as_secs()
74
2
    }
75
76
64
    fn now(&self) -> SystemTime {
77
64
        UNIX_EPOCH + MockClock::time()
78
64
    }
79
80
945
    fn elapsed(&self) -> Duration {
81
945
        self.0.elapsed()
82
945
    }
83
84
212
    async fn sleep(self, duration: Duration) {
85
174
        let baseline = self.0.elapsed();
86
        loop {
87
3.03k
            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: 114, False: 2.86k]
89
114
                break;
90
2.86k
            }
91
        }
92
114
    }
93
}