omaha_client/policy/
stub.rs

1// Copyright 2019 The Fuchsia Authors
2//
3// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6// This file may not be copied, modified, or distributed except according to
7// those terms.
8//
9use 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
19/// A stub policy implementation that allows everything immediately.
20pub 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/// A stub PolicyEngine that just gathers the current time and hands it off to the StubPolicy as the
76/// PolicyData.
77#[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}