omaha_client_fuchsia/
install_plan.rs

1// Copyright 2023 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use fuchsia_url::PinnedAbsolutePackageUrl;
6use omaha_client::cup_ecdsa::RequestMetadata;
7use omaha_client::installer::Plan;
8use omaha_client::protocol::request::InstallSource;
9use std::fmt;
10
11#[derive(Debug, PartialEq, Eq)]
12pub enum UpdatePackageUrl {
13    /// The pinned fuchsia update package URL, e.g. fuchsia-pkg://fuchsia.example/update/0?hash=...
14    System(url::Url),
15    /// The pinned package URL for eagerly updated package.
16    Package(PinnedAbsolutePackageUrl),
17}
18
19impl fmt::Display for UpdatePackageUrl {
20    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21        match self {
22            UpdatePackageUrl::System(url) => write!(f, "System({url})"),
23            UpdatePackageUrl::Package(url) => write!(f, "Package({url})"),
24        }
25    }
26}
27
28#[derive(Debug, Default, PartialEq, Eq)]
29pub struct FuchsiaInstallPlan {
30    pub update_package_urls: Vec<UpdatePackageUrl>,
31    pub install_source: InstallSource,
32    pub urgent_update: bool,
33    pub omaha_response: Vec<u8>,
34    pub request_metadata: Option<RequestMetadata>,
35    pub ecdsa_signature: Option<Vec<u8>>,
36}
37
38impl Plan for FuchsiaInstallPlan {
39    fn id(&self) -> String {
40        self.update_package_urls.iter().map(|url| url.to_string()).collect::<Vec<_>>().join(", ")
41    }
42}
43
44impl FuchsiaInstallPlan {
45    pub fn new_test() -> Self {
46        Self {
47            update_package_urls: vec![UpdatePackageUrl::System(
48                "fuchsia-pkg://fuchsia.test/update/0?hash=0000000000000000000000000000000000000000000000000000000000000000".parse().unwrap(),
49            )],
50            install_source: InstallSource::OnDemand,
51            urgent_update: false,
52            omaha_response: vec![],
53            request_metadata: None,
54            ecdsa_signature: None,
55        }
56    }
57
58    pub fn is_system_update(&self) -> bool {
59        self.update_package_urls.iter().any(|u| matches!(u, UpdatePackageUrl::System(_)))
60    }
61}
62
63#[cfg(test)]
64mod tests {
65    use super::*;
66
67    #[test]
68    fn test_install_plan_id_system_update() {
69        let url = "fuchsia-pkg://fuchsia.test/update/0?hash=0000000000000000000000000000000000000000000000000000000000000000";
70        let install_plan = FuchsiaInstallPlan {
71            update_package_urls: vec![UpdatePackageUrl::System(url.parse().unwrap())],
72            ..FuchsiaInstallPlan::default()
73        };
74
75        assert_eq!(install_plan.id(), format!("System({url})"));
76    }
77
78    #[test]
79    fn test_install_plan_id_package_groups() {
80        let url1 = "fuchsia-pkg://foo.test/foo?hash=0000000000000000000000000000000000000000000000000000000000000000";
81        let url2 = "fuchsia-pkg://bar.test/bar?hash=1111111111111111111111111111111111111111111111111111111111111111";
82        let install_plan = FuchsiaInstallPlan {
83            update_package_urls: vec![
84                UpdatePackageUrl::System(url1.parse().unwrap()),
85                UpdatePackageUrl::Package(url2.parse().unwrap()),
86            ],
87            ..FuchsiaInstallPlan::default()
88        };
89
90        assert_eq!(install_plan.id(), format!("System({url1}), Package({url2})"));
91    }
92}