build_systems / prebuild-common-x86-64-v3 (pull_request) Successful in 20s
build_systems / build-portal-1 (pull_request) Successful in 16s
test ebook search / test-ebook-search (pull_request) Successful in 1m8s
build_systems / build-bob (pull_request) Successful in 1m42s
build_systems / build-rhapsody-in-green (pull_request) Successful in 1m41s
build_systems / build-jeeves (pull_request) Successful in 1m44s
build_systems / build-brain (pull_request) Successful in 1m57s
treefmt / nix fmt (pull_request) Successful in 6s
treefmt / nix fmt (push) Successful in 3s
build_systems / prebuild-common-x86-64-v3 (push) Successful in 8s
build_systems / build-portal-1 (push) Successful in 21s
build_systems / build-bob (push) Successful in 30s
build_systems / build-brain (push) Successful in 38s
build_systems / build-rhapsody-in-green (push) Successful in 39s
test ebook search / test-ebook-search (push) Successful in 1m14s
build_systems / build-jeeves (push) Successful in 1m8s
203 lines
6.7 KiB
Rust
203 lines
6.7 KiB
Rust
#![cfg(test)]
|
|
|
|
use std::{fs, os::unix::fs::symlink, path::Path, process::Command};
|
|
|
|
use tempfile::tempdir;
|
|
|
|
fn command() -> Command {
|
|
let mut command = Command::new(env!("CARGO_BIN_EXE_snapshot-manager"));
|
|
command
|
|
.env_remove("SIGNAL_ALERTS")
|
|
.env_remove("SIGNAL_ALERT_FROM_PHONE")
|
|
.env_remove("SIGNAL_ALERT_TO_PHONE")
|
|
.env_remove("SNAPSHOT_TEST_SCRIPT")
|
|
.env_remove("RUST_LOG");
|
|
command
|
|
}
|
|
|
|
#[test]
|
|
fn help_works_without_phone_numbers() {
|
|
let output = command().arg("--help").output().unwrap();
|
|
assert!(output.status.success());
|
|
assert!(
|
|
String::from_utf8(output.stdout)
|
|
.unwrap()
|
|
.contains("<CONFIG_FILE>")
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn help_documents_environment_variables_without_exposing_phone_numbers() {
|
|
let output = command()
|
|
.env("SIGNAL_ALERT_FROM_PHONE", "+15555550101")
|
|
.env("SIGNAL_ALERT_TO_PHONE", "+15555550102")
|
|
.arg("--help")
|
|
.output()
|
|
.unwrap();
|
|
assert!(output.status.success());
|
|
let stdout = String::from_utf8(output.stdout).unwrap();
|
|
for name in [
|
|
"SIGNAL_ALERTS",
|
|
"SIGNAL_ALERT_FROM_PHONE",
|
|
"SIGNAL_ALERT_TO_PHONE",
|
|
] {
|
|
assert!(stdout.contains(name), "{stdout}");
|
|
}
|
|
assert!(!stdout.contains("+15555550101"), "{stdout}");
|
|
assert!(!stdout.contains("+15555550102"), "{stdout}");
|
|
}
|
|
|
|
#[test]
|
|
fn config_argument_is_required() {
|
|
let output = command().output().unwrap();
|
|
assert_eq!(output.status.code(), Some(2));
|
|
}
|
|
|
|
#[test]
|
|
fn enabled_alerts_require_phone_numbers_before_running() {
|
|
for use_env in [false, true] {
|
|
for (from, to, expected) in [
|
|
(None, None, "--signal-alert-from-phone"),
|
|
(Some(""), None, "--signal-alert-from-phone"),
|
|
(Some("+15555550101"), None, "--signal-alert-to-phone"),
|
|
(Some("+15555550101"), Some(""), "--signal-alert-to-phone"),
|
|
(None, Some("+15555550102"), "--signal-alert-from-phone"),
|
|
] {
|
|
let mut command = command();
|
|
if use_env {
|
|
command.env("SIGNAL_ALERTS", "true");
|
|
} else {
|
|
command.args(["--signal-alerts", "true"]);
|
|
}
|
|
if let Some(from) = from {
|
|
command.env("SIGNAL_ALERT_FROM_PHONE", from);
|
|
}
|
|
if let Some(to) = to {
|
|
command.env("SIGNAL_ALERT_TO_PHONE", to);
|
|
}
|
|
let output = command.arg("unused.toml").output().unwrap();
|
|
let stderr = String::from_utf8(output.stderr).unwrap();
|
|
assert_eq!(output.status.code(), Some(2), "{stderr}");
|
|
assert!(stderr.contains(expected), "{stderr}");
|
|
assert!(!stderr.contains("Starting snapshot_manager"), "{stderr}");
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn enabled_alerts_accept_environment_variables_and_cli_overrides() {
|
|
let dir = tempdir().unwrap();
|
|
let config = dir.path().join("config.toml");
|
|
let scenario = dir.path().join("scenario");
|
|
fs::write(&config, "").unwrap();
|
|
// An empty dataset list completes successfully without sending an alert.
|
|
fs::write(&scenario, "").unwrap();
|
|
symlink(
|
|
Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/zfs"),
|
|
dir.path().join("zfs"),
|
|
)
|
|
.unwrap();
|
|
|
|
for use_cli in [false, true] {
|
|
let mut command = command();
|
|
if use_cli {
|
|
command
|
|
.env("SIGNAL_ALERTS", "invalid")
|
|
.env("SIGNAL_ALERT_FROM_PHONE", "")
|
|
.env("SIGNAL_ALERT_TO_PHONE", "")
|
|
.args([
|
|
"--signal-alerts",
|
|
"true",
|
|
"--signal-alert-from-phone",
|
|
"+15555550101",
|
|
"--signal-alert-to-phone",
|
|
"+15555550102",
|
|
]);
|
|
} else {
|
|
command
|
|
.env("SIGNAL_ALERTS", "true")
|
|
.env("SIGNAL_ALERT_FROM_PHONE", "+15555550101")
|
|
.env("SIGNAL_ALERT_TO_PHONE", "+15555550102");
|
|
}
|
|
let output = command
|
|
.current_dir(dir.path())
|
|
.env("PATH", dir.path())
|
|
.env("SNAPSHOT_TEST_SCRIPT", &scenario)
|
|
.arg(&config)
|
|
.output()
|
|
.unwrap();
|
|
let stderr = String::from_utf8(output.stderr).unwrap();
|
|
assert!(output.status.success(), "{stderr}");
|
|
assert!(stderr.contains("snapshot_manager completed"), "{stderr}");
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn disabled_alerts_allow_snapshot_failures_without_phone_numbers() {
|
|
let dir = tempdir().unwrap();
|
|
let config = dir.path().join("config.toml");
|
|
fs::write(&config, "").unwrap();
|
|
symlink(
|
|
Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/zfs"),
|
|
dir.path().join("zfs"),
|
|
)
|
|
.unwrap();
|
|
|
|
for (env_value, args) in [
|
|
(None, vec![]),
|
|
(Some("false"), vec![]),
|
|
(None, vec!["--signal-alerts", "false"]),
|
|
(Some("true"), vec!["--signal-alerts", "false"]),
|
|
] {
|
|
let mut command = command();
|
|
if let Some(value) = env_value {
|
|
command.env("SIGNAL_ALERTS", value);
|
|
}
|
|
let output = command
|
|
.env("PATH", dir.path())
|
|
.args(args)
|
|
.arg(&config)
|
|
.output()
|
|
.unwrap();
|
|
let stderr = String::from_utf8(output.stderr).unwrap();
|
|
assert!(output.status.success(), "{stderr}");
|
|
assert!(
|
|
stderr.contains("pool/home failed to create snapshot"),
|
|
"{stderr}"
|
|
);
|
|
assert!(stderr.contains("snapshot_manager completed"), "{stderr}");
|
|
assert!(!stderr.contains("Signal"), "{stderr}");
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn disabled_alerts_preserve_fatal_errors_without_phone_numbers() {
|
|
let dir = tempdir().unwrap();
|
|
for args in [vec![], vec!["--signal-alerts", "false"]] {
|
|
let output = command()
|
|
.args(args)
|
|
.arg(dir.path().join("missing.toml"))
|
|
.output()
|
|
.unwrap();
|
|
let stderr = String::from_utf8(output.stderr).unwrap();
|
|
assert_eq!(output.status.code(), Some(1), "{stderr}");
|
|
assert!(stderr.contains("Failed to read configuration"), "{stderr}");
|
|
assert!(!stderr.contains("SIGNAL_ALERT_"), "{stderr}");
|
|
assert!(!stderr.contains("Failed to send failure alert"), "{stderr}");
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn signal_alerts_requires_a_boolean_value() {
|
|
for use_env in [false, true] {
|
|
let mut command = command();
|
|
if use_env {
|
|
command.env("SIGNAL_ALERTS", "invalid");
|
|
} else {
|
|
command.args(["--signal-alerts", "invalid"]);
|
|
}
|
|
let output = command.arg("unused.toml").output().unwrap();
|
|
assert_eq!(output.status.code(), Some(2));
|
|
}
|
|
}
|