Coverage Report

Created: 2025-04-19 16:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/build/source/nativelink-util/src/instant_wrapper.rs
Line
Count
Source
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.9k
    fn elapsed(&self) -> Duration {
46
20.9k
        <SystemTime>::elapsed(self).unwrap()
47
20.9k
    }
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
#[derive(Debug, Clone, Copy)]
60
pub struct MockInstantWrapped(MockInstant);
61
62
impl Default for MockInstantWrapped {
63
983
    fn default() -> Self {
64
983
        Self(MockInstant::now())
65
983
    }
66
}
67
68
impl InstantWrapper for MockInstantWrapped {
69
32
    fn from_secs(_secs: u64) -> Self {
70
32
        MockInstantWrapped(MockInstant::now())
71
32
    }
72
73
2
    fn unix_timestamp(&self) -> u64 {
74
2
        MockClock::time().as_secs()
75
2
    }
76
77
671
    fn now(&self) -> SystemTime {
78
671
        UNIX_EPOCH + MockClock::time()
79
671
    }
80
81
456
    fn elapsed(&self) -> Duration {
82
456
        self.0.elapsed()
83
456
    }
84
85
178
    
async fn sleep(self, duration: Duration) 0
{
86
178
        let baseline = self.0.elapsed();
87
        loop {
88
3.04k
            tokio::task::yield_now().await;
89
2.97k
            if self.0.elapsed() - baseline >= duration {
  Branch (89:16): [Folded - Ignored]
  Branch (89:16): [Folded - Ignored]
  Branch (89:16): [True: 0, False: 1]
  Branch (89:16): [True: 114, False: 2.86k]
90
114
                break;
91
2.86k
            }
92
        }
93
114
    }
94
}