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