blob: 71195bc8a4270b76094f31796b9925031f1352e0 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use fuchsia_uri::pkg_uri::PkgUri;
use log::{error, info, warn};
use omaha_client::install_plan::InstallPlan;
use omaha_client::protocol::response::{OmahaStatus, Response};
#[derive(Debug, PartialEq)]
pub struct FuchsiaInstallPlan {
/// The fuchsia TUF repo URI, e.g. fuchsia-pkg://fuchsia.com/update/0?hash=...
pub uri: PkgUri,
}
impl InstallPlan for FuchsiaInstallPlan {
fn from_response(resp: &Response) -> Option<Self> {
let (app, rest) = if let Some((app, rest)) = resp.apps.split_first() {
(app, rest)
} else {
error!("No app in Omaha response.");
return None;
};
if !rest.is_empty() {
warn!("Only 1 app is supported, found {}", resp.apps.len());
}
if app.status != OmahaStatus::Ok {
error!("Found non-ok app status: {:?}", app.status);
return None;
}
let update_check = if let Some(update_check) = &app.update_check {
update_check
} else {
error!("No update_check in Omaha response.");
return None;
};
let urls = match update_check.status {
OmahaStatus::Ok => {
if let Some(urls) = &update_check.urls {
&urls.url
} else {
error!("No urls in Omaha response.");
return None;
}
}
OmahaStatus::NoUpdate => {
info!("Omaha returned that there is no update available at this time.");
return None;
}
_ => {
warn!("Unexpected update check status: {:?}", update_check.status);
if let Some(info) = &update_check.info {
warn!("update check status info: {}", info);
}
return None;
}
};
let (url, rest) = if let Some((url, rest)) = urls.split_first() {
(url, rest)
} else {
error!("No url in Omaha response.");
return None;
};
if !rest.is_empty() {
warn!("Only 1 url is supported, found {}", urls.len());
}
match PkgUri::parse(&url.codebase) {
Ok(uri) => Some(FuchsiaInstallPlan { uri: uri }),
Err(err) => {
error!("Failed to parse {} to PkgUri: {}", url.codebase, err);
None
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use omaha_client::protocol::response::{App, UpdateCheck};
const TEST_URI: &str = "fuchsia-pkg://fuchsia.com/update/0";
#[test]
fn test_simple_response() {
let response = Response {
apps: vec![App {
update_check: Some(UpdateCheck::ok(vec![TEST_URI.to_string()])),
..App::default()
}],
..Response::default()
};
let install_plan = FuchsiaInstallPlan::from_response(&response).unwrap();
assert_eq!(install_plan.uri.to_string(), TEST_URI);
}
#[test]
fn test_no_app() {
let response = Response::default();
assert_eq!(FuchsiaInstallPlan::from_response(&response), None);
}
#[test]
fn test_multiple_app() {
let response = Response {
apps: vec![
App {
update_check: Some(UpdateCheck::ok(vec![TEST_URI.to_string()])),
..App::default()
},
App::default(),
],
..Response::default()
};
let install_plan = FuchsiaInstallPlan::from_response(&response).unwrap();
assert_eq!(install_plan.uri.to_string(), TEST_URI);
}
#[test]
fn test_no_update_check() {
let response = Response { apps: vec![App::default()], ..Response::default() };
assert_eq!(FuchsiaInstallPlan::from_response(&response), None);
}
#[test]
fn test_no_urls() {
let response = Response {
apps: vec![App { update_check: Some(UpdateCheck::default()), ..App::default() }],
..Response::default()
};
assert_eq!(FuchsiaInstallPlan::from_response(&response), None);
}
#[test]
fn test_app_error_status() {
let response = Response {
apps: vec![App {
status: OmahaStatus::Error("error-unknownApplication".to_string()),
..App::default()
}],
..Response::default()
};
assert_eq!(FuchsiaInstallPlan::from_response(&response), None);
}
#[test]
fn test_no_update() {
let response = Response {
apps: vec![App { update_check: Some(UpdateCheck::no_update()), ..App::default() }],
..Response::default()
};
assert_eq!(FuchsiaInstallPlan::from_response(&response), None);
}
#[test]
fn test_invalid_uri() {
let response = Response {
apps: vec![App {
update_check: Some(UpdateCheck::ok(vec!["invalid-uri".to_string()])),
..App::default()
}],
..Response::default()
};
assert_eq!(FuchsiaInstallPlan::from_response(&response), None);
}
}