blob: 595c9174f32f67368f4abb06d1cc014f09ec6734 [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 argh::FromArgs;
#[derive(Debug, Eq, FromArgs, PartialEq)]
/// Manage updates.
pub struct Update {
#[argh(subcommand)]
pub cmd: Command,
}
#[derive(Debug, Eq, FromArgs, PartialEq)]
#[argh(subcommand)]
pub enum Command {
// fuchsia.update.channelcontrol.ChannelControl protocol:
Channel(Channel),
// fuchsia.update Manager protocol:
CheckNow(CheckNow),
// fuchsia.update.installer protocol:
ForceInstall(ForceInstall),
// fuchsia.update CommitStatusProvider protocol:
WaitForCommit(WaitForCommit),
Revert(Revert),
}
#[derive(Debug, Eq, FromArgs, PartialEq)]
#[argh(subcommand, name = "channel")]
/// Get the current (running) channel.
pub struct Channel {
#[argh(subcommand)]
pub cmd: channel::Command,
}
pub mod channel {
use argh::FromArgs;
#[derive(Debug, Eq, FromArgs, PartialEq)]
#[argh(subcommand)]
pub enum Command {
Get(Get),
Target(Target),
Set(Set),
List(List),
}
#[derive(Debug, Eq, FromArgs, PartialEq)]
#[argh(subcommand, name = "get")]
/// Get the current (running) channel.
pub struct Get {}
#[derive(Debug, Eq, FromArgs, PartialEq)]
#[argh(subcommand, name = "target")]
/// Get the target channel.
pub struct Target {}
#[derive(Debug, Eq, FromArgs, PartialEq)]
#[argh(subcommand, name = "set")]
/// Set the target channel.
pub struct Set {
#[argh(positional)]
pub channel: String,
}
#[derive(Debug, Eq, FromArgs, PartialEq)]
#[argh(subcommand, name = "list")]
/// List of known target channels.
pub struct List {}
}
#[derive(Debug, Eq, FromArgs, PartialEq)]
#[argh(subcommand, name = "check-now")]
/// Start an update.
pub struct CheckNow {
/// the update check was initiated by a service, in the background.
#[argh(switch)]
pub service_initiated: bool,
/// monitor for state update.
#[argh(switch)]
pub monitor: bool,
}
#[derive(Debug, Eq, FromArgs, PartialEq)]
#[argh(subcommand, name = "force-install")]
/// Directly invoke the system updater to install the provided update, bypassing any update checks.
pub struct ForceInstall {
/// whether or not the system updater should reboot into the new system.
#[argh(option, default = "true")]
pub reboot: bool,
/// the url of the update package describing the update to install. Ex:
/// fuchsia-pkg://fuchsia.com/update.
#[argh(positional)]
pub update_pkg_url: String,
/// the force install was initiated by a service, in the background.
#[argh(switch)]
pub service_initiated: bool,
}
#[derive(Debug, Eq, FromArgs, PartialEq)]
#[argh(subcommand, name = "wait-for-commit")]
/// Wait for the update to be committed.
pub struct WaitForCommit {}
#[derive(Debug, Eq, FromArgs, PartialEq)]
#[argh(subcommand, name = "revert")]
/// Revert the update.
pub struct Revert {}
#[cfg(test)]
mod tests {
use {super::*, matches::assert_matches};
#[test]
fn test_unknown_option() {
assert_matches!(Update::from_args(&["update"], &["--unkown"]), Err(_));
}
#[test]
fn test_unknown_subcommand() {
assert_matches!(Update::from_args(&["update"], &["unkown"]), Err(_));
}
#[test]
fn test_channel_get() {
let update = Update::from_args(&["update"], &["channel", "get"]).unwrap();
assert_eq!(
update,
Update {
cmd: Command::Channel(Channel { cmd: channel::Command::Get(channel::Get {}) })
}
);
}
#[test]
fn test_channel_target() {
let update = Update::from_args(&["update"], &["channel", "target"]).unwrap();
assert_eq!(
update,
Update {
cmd: Command::Channel(Channel {
cmd: channel::Command::Target(channel::Target {})
})
}
);
}
#[test]
fn test_channel_set() {
let update = Update::from_args(&["update"], &["channel", "set", "new-channel"]).unwrap();
assert_eq!(
update,
Update {
cmd: Command::Channel(Channel {
cmd: channel::Command::Set(channel::Set { channel: "new-channel".to_string() })
})
}
);
}
#[test]
fn test_channel_list() {
let update = Update::from_args(&["update"], &["channel", "list"]).unwrap();
assert_eq!(
update,
Update {
cmd: Command::Channel(Channel { cmd: channel::Command::List(channel::List {}) })
}
);
}
#[test]
fn test_check_now() {
let update = Update::from_args(&["update"], &["check-now"]).unwrap();
assert_eq!(
update,
Update {
cmd: Command::CheckNow(CheckNow { service_initiated: false, monitor: false })
}
);
}
#[test]
fn test_check_now_monitor() {
let update = Update::from_args(&["update"], &["check-now", "--monitor"]).unwrap();
assert_eq!(
update,
Update { cmd: Command::CheckNow(CheckNow { service_initiated: false, monitor: true }) }
);
}
#[test]
fn test_check_now_service_initiated() {
let update = Update::from_args(&["update"], &["check-now", "--service-initiated"]).unwrap();
assert_eq!(
update,
Update { cmd: Command::CheckNow(CheckNow { service_initiated: true, monitor: false }) }
);
}
#[test]
fn test_force_install_requires_positional_arg() {
assert_matches!(Update::from_args(&["update"], &["force-install"]), Err(_));
}
#[test]
fn test_force_install() {
let update = Update::from_args(&["update"], &["force-install", "url"]).unwrap();
assert_eq!(
update,
Update {
cmd: Command::ForceInstall(ForceInstall {
update_pkg_url: "url".to_owned(),
reboot: true,
service_initiated: false,
})
}
);
}
#[test]
fn test_force_install_no_reboot() {
let update =
Update::from_args(&["update"], &["force-install", "--reboot", "false", "url"]).unwrap();
assert_eq!(
update,
Update {
cmd: Command::ForceInstall(ForceInstall {
update_pkg_url: "url".to_owned(),
reboot: false,
service_initiated: false,
})
}
);
}
#[test]
fn test_force_install_service_initiated() {
let update =
Update::from_args(&["update"], &["force-install", "--service-initiated", "url"])
.unwrap();
assert_eq!(
update,
Update {
cmd: Command::ForceInstall(ForceInstall {
update_pkg_url: "url".to_owned(),
reboot: true,
service_initiated: true,
})
}
);
}
#[test]
fn test_wait_for_commit() {
let update = Update::from_args(&["update"], &["wait-for-commit"]).unwrap();
assert_eq!(update, Update { cmd: Command::WaitForCommit(WaitForCommit {}) });
}
#[test]
fn test_revert() {
let update = Update::from_args(&["update"], &["revert"]).unwrap();
assert_eq!(update, Update { cmd: Command::Revert(Revert {}) });
}
}