Coverage Report

Created: 2026-07-21 15:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/build/source/nativelink-scheduler/src/mock_scheduler.rs
Line
Count
Source
1
// Copyright 2024 The NativeLink Authors. All rights reserved.
2
//
3
// Licensed under the Functional Source License, Version 1.1, Apache 2.0 Future License (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
//    See LICENSE file for details
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::sync::Arc;
16
17
use async_trait::async_trait;
18
use nativelink_error::Error;
19
use nativelink_metric::{MetricsComponent, RootMetricsComponent};
20
use nativelink_util::action_messages::{ActionInfo, OperationId};
21
use nativelink_util::operation_state_manager::{
22
    ActionStateResult, ActionStateResultStream, ClientStateManager, OperationFilter,
23
};
24
use tokio::sync::{Mutex, mpsc};
25
use tonic::Code;
26
27
use crate::known_platform_property_provider::KnownPlatformPropertyProvider;
28
29
#[allow(
30
    clippy::large_enum_variant,
31
    reason = "Testing, so this doesn't really matter. Doesn't trigger on nightly"
32
)]
33
#[allow(dead_code, reason = "https://github.com/rust-lang/rust/issues/46379")]
34
enum ActionSchedulerCalls {
35
    GetGetKnownProperties(String),
36
    AddAction((OperationId, ActionInfo)),
37
    FilterOperations(OperationFilter),
38
}
39
40
#[allow(dead_code, reason = "https://github.com/rust-lang/rust/issues/46379")]
41
enum ActionSchedulerReturns {
42
    GetGetKnownProperties(Result<Vec<String>, Error>),
43
    AddAction(Result<Box<dyn ActionStateResult>, Error>),
44
    FilterOperations(Result<ActionStateResultStream<'static>, Error>),
45
}
46
47
#[derive(MetricsComponent, Debug)]
48
pub struct MockActionScheduler {
49
    rx_call: Mutex<mpsc::UnboundedReceiver<ActionSchedulerCalls>>,
50
    tx_call: mpsc::UnboundedSender<ActionSchedulerCalls>,
51
52
    rx_resp: Mutex<mpsc::UnboundedReceiver<ActionSchedulerReturns>>,
53
    tx_resp: mpsc::UnboundedSender<ActionSchedulerReturns>,
54
}
55
56
impl Default for MockActionScheduler {
57
0
    fn default() -> Self {
58
0
        Self::new()
59
0
    }
60
}
61
62
impl MockActionScheduler {
63
28
    pub fn new() -> Self {
64
28
        let (tx_call, rx_call) = mpsc::unbounded_channel();
65
28
        let (tx_resp, rx_resp) = mpsc::unbounded_channel();
66
28
        Self {
67
28
            rx_call: Mutex::new(rx_call),
68
28
            tx_call,
69
28
            rx_resp: Mutex::new(rx_resp),
70
28
            tx_resp,
71
28
        }
72
28
    }
73
74
    #[allow(dead_code, reason = "https://github.com/rust-lang/rust/issues/46379")]
75
4
    pub async fn expect_get_known_properties(&self, result: Result<Vec<String>, Error>) -> String {
76
4
        let mut rx_call_lock = self.rx_call.lock().await;
77
4
        let ActionSchedulerCalls::GetGetKnownProperties(req) = rx_call_lock
78
4
            .recv()
79
4
            .await
80
4
            .expect("Could not receive msg in mpsc")
81
        else {
82
0
            panic!("Got incorrect call waiting for get_known_properties")
83
        };
84
4
        self.tx_resp
85
4
            .send(ActionSchedulerReturns::GetGetKnownProperties(result))
86
4
            .map_err(|err| 
{0
87
0
                Error::from_std_err(Code::InvalidArgument, &err)
88
0
                    .append("Could not send request to mpsc")
89
0
            })
90
4
            .unwrap();
91
4
        req
92
4
    }
93
94
    #[allow(dead_code, reason = "https://github.com/rust-lang/rust/issues/46379")]
95
0
    pub async fn expect_add_action(
96
0
        &self,
97
0
        result: Result<Box<dyn ActionStateResult>, Error>,
98
10
    ) -> (OperationId, ActionInfo) {
99
10
        let mut rx_call_lock = self.rx_call.lock().await;
100
10
        let ActionSchedulerCalls::AddAction(req) = rx_call_lock
101
10
            .recv()
102
10
            .await
103
10
            .expect("Could not receive msg in mpsc")
104
        else {
105
0
            panic!("Got incorrect call waiting for get_known_properties")
106
        };
107
10
        self.tx_resp
108
10
            .send(ActionSchedulerReturns::AddAction(result))
109
10
            .map_err(|err| 
{0
110
0
                Error::from_std_err(Code::InvalidArgument, &err)
111
0
                    .append("Could not send request to mpsc")
112
0
            })
113
10
            .unwrap();
114
10
        req
115
10
    }
116
117
    #[allow(dead_code, reason = "https://github.com/rust-lang/rust/issues/46379")]
118
0
    pub async fn expect_filter_operations(
119
0
        &self,
120
0
        result: Result<ActionStateResultStream<'static>, Error>,
121
6
    ) -> OperationFilter {
122
6
        let mut rx_call_lock = self.rx_call.lock().await;
123
6
        let ActionSchedulerCalls::FilterOperations(req) = rx_call_lock
124
6
            .recv()
125
6
            .await
126
6
            .expect("Could not receive msg in mpsc")
127
        else {
128
0
            panic!("Got incorrect call waiting for find_by_client_operation_id")
129
        };
130
6
        self.tx_resp
131
6
            .send(ActionSchedulerReturns::FilterOperations(result))
132
6
            .map_err(|err| 
{0
133
0
                Error::from_std_err(Code::InvalidArgument, &err)
134
0
                    .append("Could not send request to mpsc")
135
0
            })
136
6
            .unwrap();
137
6
        req
138
6
    }
139
}
140
141
#[async_trait]
142
impl KnownPlatformPropertyProvider for MockActionScheduler {
143
4
    async fn get_known_properties(&self, instance_name: &str) -> Result<Vec<String>, Error> {
144
        self.tx_call
145
            .send(ActionSchedulerCalls::GetGetKnownProperties(
146
                instance_name.to_string(),
147
            ))
148
            .expect("Could not send request to mpsc");
149
        let mut rx_resp_lock = self.rx_resp.lock().await;
150
        match rx_resp_lock
151
            .recv()
152
            .await
153
            .expect("Could not receive msg in mpsc")
154
        {
155
            ActionSchedulerReturns::GetGetKnownProperties(result) => result,
156
            _ => panic!("Expected get_known_properties return value"),
157
        }
158
4
    }
159
}
160
161
#[async_trait]
162
impl ClientStateManager for MockActionScheduler {
163
    async fn add_action(
164
        &self,
165
        client_operation_id: OperationId,
166
        action_info: Arc<ActionInfo>,
167
10
    ) -> Result<Box<dyn ActionStateResult>, Error> {
168
        self.tx_call
169
            .send(ActionSchedulerCalls::AddAction((
170
                client_operation_id,
171
                action_info.as_ref().clone(),
172
            )))
173
            .expect("Could not send request to mpsc");
174
        let mut rx_resp_lock = self.rx_resp.lock().await;
175
        match rx_resp_lock
176
            .recv()
177
            .await
178
            .expect("Could not receive msg in mpsc")
179
        {
180
            ActionSchedulerReturns::AddAction(result) => result,
181
            _ => panic!("Expected add_action return value"),
182
        }
183
10
    }
184
185
    async fn filter_operations<'a>(
186
        &'a self,
187
        filter: OperationFilter,
188
6
    ) -> Result<ActionStateResultStream<'a>, Error> {
189
        self.tx_call
190
            .send(ActionSchedulerCalls::FilterOperations(filter))
191
            .expect("Could not send request to mpsc");
192
        let mut rx_resp_lock = self.rx_resp.lock().await;
193
        match rx_resp_lock
194
            .recv()
195
            .await
196
            .expect("Could not receive msg in mpsc")
197
        {
198
            ActionSchedulerReturns::FilterOperations(result) => result,
199
            _ => panic!("Expected find_by_client_operation_id return value"),
200
        }
201
6
    }
202
}
203
204
impl RootMetricsComponent for MockActionScheduler {}