1use crate::{
10 common::{App, CheckOptions, CheckTiming, ProtocolState, UpdateCheckSchedule},
11 installer::Plan,
12 policy::{CheckDecision, Policy, PolicyData, PolicyEngine, UpdateDecision},
13 request_builder::RequestParams,
14 time::TimeSource,
15};
16use futures::future::BoxFuture;
17use futures::prelude::*;
18
19pub struct StubPolicy<P: Plan> {
21 _phantom_data: std::marker::PhantomData<P>,
22}
23
24impl<P: Plan> Policy for StubPolicy<P> {
25 type ComputeNextUpdateTimePolicyData = PolicyData;
26 type UpdateCheckAllowedPolicyData = ();
27 type UpdateCanStartPolicyData = ();
28 type RebootPolicyData = ();
29 type InstallPlan = P;
30
31 fn compute_next_update_time(
32 policy_data: &Self::ComputeNextUpdateTimePolicyData,
33 _apps: &[App],
34 _scheduling: &UpdateCheckSchedule,
35 _protocol_state: &ProtocolState,
36 ) -> CheckTiming {
37 CheckTiming::builder()
38 .time(policy_data.current_time)
39 .build()
40 }
41
42 fn update_check_allowed(
43 _policy_data: &Self::UpdateCheckAllowedPolicyData,
44 _apps: &[App],
45 _scheduling: &UpdateCheckSchedule,
46 _protocol_state: &ProtocolState,
47 check_options: &CheckOptions,
48 ) -> CheckDecision {
49 CheckDecision::Ok(RequestParams {
50 source: check_options.source,
51 use_configured_proxies: true,
52 ..RequestParams::default()
53 })
54 }
55
56 fn update_can_start(
57 _policy_data: &Self::UpdateCanStartPolicyData,
58 _proposed_install_plan: &Self::InstallPlan,
59 ) -> UpdateDecision {
60 UpdateDecision::Ok
61 }
62
63 fn reboot_allowed(
64 _policy_data: &Self::RebootPolicyData,
65 _check_options: &CheckOptions,
66 ) -> bool {
67 true
68 }
69
70 fn reboot_needed(_install_plan: &Self::InstallPlan) -> bool {
71 true
72 }
73}
74
75#[derive(Debug)]
78pub struct StubPolicyEngine<P: Plan, T: TimeSource> {
79 time_source: T,
80 _phantom_data: std::marker::PhantomData<P>,
81}
82
83impl<P, T> StubPolicyEngine<P, T>
84where
85 T: TimeSource,
86 P: Plan,
87{
88 pub fn new(time_source: T) -> Self {
89 Self {
90 time_source,
91 _phantom_data: std::marker::PhantomData,
92 }
93 }
94}
95
96impl<P, T> PolicyEngine for StubPolicyEngine<P, T>
97where
98 T: TimeSource + Clone,
99 P: Plan,
100{
101 type TimeSource = T;
102 type InstallResult = ();
103 type InstallPlan = P;
104
105 fn time_source(&self) -> &Self::TimeSource {
106 &self.time_source
107 }
108
109 fn compute_next_update_time(
110 &mut self,
111 apps: &[App],
112 scheduling: &UpdateCheckSchedule,
113 protocol_state: &ProtocolState,
114 ) -> BoxFuture<'_, CheckTiming> {
115 let check_timing = StubPolicy::<P>::compute_next_update_time(
116 &PolicyData::builder()
117 .current_time(self.time_source.now())
118 .build(),
119 apps,
120 scheduling,
121 protocol_state,
122 );
123 future::ready(check_timing).boxed()
124 }
125
126 fn update_check_allowed(
127 &mut self,
128 apps: &[App],
129 scheduling: &UpdateCheckSchedule,
130 protocol_state: &ProtocolState,
131 check_options: &CheckOptions,
132 ) -> BoxFuture<'_, CheckDecision> {
133 let decision = StubPolicy::<P>::update_check_allowed(
134 &(),
135 apps,
136 scheduling,
137 protocol_state,
138 check_options,
139 );
140 future::ready(decision).boxed()
141 }
142
143 fn update_can_start<'p>(
144 &mut self,
145 proposed_install_plan: &'p Self::InstallPlan,
146 ) -> BoxFuture<'p, UpdateDecision> {
147 let decision = StubPolicy::<P>::update_can_start(&(), proposed_install_plan);
148 future::ready(decision).boxed()
149 }
150
151 fn reboot_allowed(
152 &mut self,
153 check_options: &CheckOptions,
154 _install_result: &Self::InstallResult,
155 ) -> BoxFuture<'_, bool> {
156 let decision = StubPolicy::<P>::reboot_allowed(&(), check_options);
157 future::ready(decision).boxed()
158 }
159
160 fn reboot_needed(&mut self, install_plan: &Self::InstallPlan) -> BoxFuture<'_, bool> {
161 let decision = StubPolicy::<P>::reboot_needed(install_plan);
162 future::ready(decision).boxed()
163 }
164}
165
166#[cfg(test)]
167mod tests {
168 use super::*;
169 use crate::{
170 installer::stub::StubPlan, protocol::request::InstallSource, time::MockTimeSource,
171 };
172
173 #[test]
174 fn test_compute_next_update_time() {
175 let policy_data = PolicyData::builder()
176 .current_time(MockTimeSource::new_from_now().now())
177 .build();
178 let update_check_schedule = UpdateCheckSchedule::default();
179 let result = StubPolicy::<StubPlan>::compute_next_update_time(
180 &policy_data,
181 &[],
182 &update_check_schedule,
183 &ProtocolState::default(),
184 );
185 let expected = CheckTiming::builder()
186 .time(policy_data.current_time)
187 .build();
188 assert_eq!(result, expected);
189 }
190
191 #[test]
192 fn test_update_check_allowed_on_demand() {
193 let check_options = CheckOptions {
194 source: InstallSource::OnDemand,
195 };
196 let result = StubPolicy::<StubPlan>::update_check_allowed(
197 &(),
198 &[],
199 &UpdateCheckSchedule::default(),
200 &ProtocolState::default(),
201 &check_options,
202 );
203 let expected = CheckDecision::Ok(RequestParams {
204 source: check_options.source,
205 use_configured_proxies: true,
206 ..RequestParams::default()
207 });
208 assert_eq!(result, expected);
209 }
210
211 #[test]
212 fn test_update_check_allowed_scheduled_task() {
213 let check_options = CheckOptions {
214 source: InstallSource::ScheduledTask,
215 };
216 let result = StubPolicy::<StubPlan>::update_check_allowed(
217 &(),
218 &[],
219 &UpdateCheckSchedule::default(),
220 &ProtocolState::default(),
221 &check_options,
222 );
223 let expected = CheckDecision::Ok(RequestParams {
224 source: check_options.source,
225 use_configured_proxies: true,
226 ..RequestParams::default()
227 });
228 assert_eq!(result, expected);
229 }
230
231 #[test]
232 fn test_update_can_start() {
233 let result = StubPolicy::update_can_start(&(), &StubPlan);
234 assert_eq!(result, UpdateDecision::Ok);
235 }
236}