blob: 2e0f91db7c89da00869e50c5aa03564b76e02972 [file] [log] [blame]
// Copyright 2020 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 {
crate::{
DEFAULT_BLOB_DOWNLOAD_RESUMPTION_ATTEMPTS_LIMIT, DEFAULT_BLOB_NETWORK_BODY_TIMEOUT,
DEFAULT_BLOB_NETWORK_HEADER_TIMEOUT, DEFAULT_TUF_METADATA_TIMEOUT,
},
argh::FromArgs,
std::time::Duration,
};
#[derive(Debug, Eq, FromArgs, PartialEq)]
/// Arguments for the package resolver.
pub struct Args {
#[argh(option, default = "false")]
/// if true, allow resolving packages using `fuchsia.pkg/LocalMirror`.
pub allow_local_mirror: bool,
#[argh(
option,
default = "DEFAULT_TUF_METADATA_TIMEOUT",
from_str_fn(parse_unsigned_integer_as_seconds),
long = "tuf-metadata-timeout-seconds"
)]
/// the timeout, in seconds, to use when performing TUF metadata operations.
/// The default is 240 seconds. This flag exists for integration testing and
/// should not be used elsewhere.
pub tuf_metadata_timeout: Duration,
#[argh(
option,
default = "DEFAULT_BLOB_NETWORK_HEADER_TIMEOUT",
from_str_fn(parse_unsigned_integer_as_seconds),
long = "blob-network-header-timeout-seconds"
)]
/// the timeout, in seconds, to use when GET'ing a blob http header.
/// The default is 30 seconds. This flag exists for integration testing and
/// should not be used elsewhere.
pub blob_network_header_timeout: Duration,
#[argh(
option,
default = "DEFAULT_BLOB_NETWORK_BODY_TIMEOUT",
from_str_fn(parse_unsigned_integer_as_seconds),
long = "blob-network-body-timeout-seconds"
)]
/// the timeout, in seconds, to use when waiting for a blob's http body bytes.
/// The default is 30 seconds. This flag exists for integration testing and
/// should not be used elsewhere.
pub blob_network_body_timeout: Duration,
#[argh(
option,
default = "DEFAULT_BLOB_DOWNLOAD_RESUMPTION_ATTEMPTS_LIMIT",
long = "blob-download-resumption-attempts-limit"
)]
/// the maximum number of times to try resuming a blob download using HTTP Range
/// requests.
/// The default is 50 attempts. This flag exists for integration testing and
/// should not be used elsewhere.
pub blob_download_resumption_attempts_limit: u64,
}
fn parse_unsigned_integer_as_seconds(flag: &str) -> Result<Duration, String> {
if let Ok(duration) = flag.parse::<u64>() {
Ok(Duration::from_secs(duration))
} else {
Err(String::from("value should be an unsigned integer"))
}
}
#[cfg(test)]
mod tests {
use {super::*, assert_matches::assert_matches};
#[test]
fn local_mirror_allowed() {
assert_matches!(
Args::from_args(&["pkg-resolver"], &["--allow-local-mirror", "true"]),
Ok(Args { allow_local_mirror: true, .. })
);
}
#[test]
fn local_mirror_disallowed() {
assert_matches!(
Args::from_args(&["pkg-resolver"], &["--allow-local-mirror", "false"]),
Ok(Args { allow_local_mirror: false, .. })
);
}
#[test]
fn tuf_metadata_timeout_seconds_success() {
assert_matches!(
Args::from_args(&["pkg-resolver"], &["--tuf-metadata-timeout-seconds", "23"]),
Ok(Args { tuf_metadata_timeout, .. })
if tuf_metadata_timeout == Duration::from_secs(23)
);
}
#[test]
fn tuf_metadata_timeout_seconds_failure() {
assert_matches!(
Args::from_args(
&["pkg-resolver"],
&["--tuf-metadata-timeout-seconds", "not-an-integer"]
),
Err(_)
);
}
#[test]
fn blob_network_header_timeout_seconds_success() {
assert_matches!(
Args::from_args(&["pkg-resolver"], &["--blob-network-header-timeout-seconds", "24"]),
Ok(Args { blob_network_header_timeout, .. })
if blob_network_header_timeout == Duration::from_secs(24)
);
}
#[test]
fn blob_network_header_timeout_seconds_failure() {
assert_matches!(
Args::from_args(
&["pkg-resolver"],
&["--blob-network-header-timeout-seconds", "also-not-an-integer"]
),
Err(_)
);
}
#[test]
fn blob_network_body_timeout_seconds_success() {
assert_matches!(
Args::from_args(&["pkg-resolver"], &["--blob-network-body-timeout-seconds", "25"]),
Ok(Args { blob_network_body_timeout, .. })
if blob_network_body_timeout == Duration::from_secs(25)
);
}
#[test]
fn blob_network_body_timeout_seconds_failure() {
assert_matches!(
Args::from_args(
&["pkg-resolver"],
&["--blob-network-body-timeout-seconds", "also-not-an-integer-too"]
),
Err(_)
);
}
#[test]
fn blob_download_resumption_attempts_limit_success() {
assert_matches!(
Args::from_args(&["pkg-resolver"], &["--blob-download-resumption-attempts-limit", "26"]),
Ok(Args { blob_download_resumption_attempts_limit, .. })
if blob_download_resumption_attempts_limit == 26
);
}
#[test]
fn blob_download_resumption_attempts_limit_failure() {
assert_matches!(
Args::from_args(
&["pkg-resolver"],
&["--blob-download-resumption-attempts-limit", "also-not-an-integer-three"]
),
Err(_)
);
}
#[test]
fn default() {
assert_eq!(
Args::from_args(&["pkg-resolver"], &[]),
Ok(Args {
allow_local_mirror: false,
tuf_metadata_timeout: DEFAULT_TUF_METADATA_TIMEOUT,
blob_network_body_timeout: DEFAULT_BLOB_NETWORK_BODY_TIMEOUT,
blob_network_header_timeout: DEFAULT_BLOB_NETWORK_HEADER_TIMEOUT,
blob_download_resumption_attempts_limit:
DEFAULT_BLOB_DOWNLOAD_RESUMPTION_ATTEMPTS_LIMIT,
})
);
}
}