127 lines
3.9 KiB
Rust
127 lines
3.9 KiB
Rust
//! The explicit importer must preserve source paths and never start on help/error.
|
|
use std::{fs, path::PathBuf, process::Command};
|
|
|
|
struct Fixture {
|
|
_temporary: tempfile::TempDir,
|
|
root: PathBuf,
|
|
launcher: PathBuf,
|
|
arguments: PathBuf,
|
|
environment: PathBuf,
|
|
}
|
|
|
|
impl Fixture {
|
|
fn new() -> Self {
|
|
let temporary = tempfile::tempdir().unwrap();
|
|
let root = temporary.path().to_path_buf();
|
|
let project = root.join("new application");
|
|
fs::create_dir(&project).unwrap();
|
|
let launcher = project.join("import-python.sh");
|
|
fs::write(&launcher, include_str!("../import-python.sh")).unwrap();
|
|
fs::write(
|
|
project.join("start.sh"),
|
|
"#!/usr/bin/env bash\nset -euo pipefail\nprintf '%s\\0' \"$@\" > \"$IMPORT_TEST_ARGS\"\nprintf '%s\\0' \"${DATA_DIR-}\" \"${DATABASE_PATH-}\" > \"$IMPORT_TEST_ENV\"\nexit \"${IMPORT_TEST_STATUS:-0}\"\n",
|
|
)
|
|
.unwrap();
|
|
Self {
|
|
_temporary: temporary,
|
|
launcher,
|
|
arguments: root.join("arguments"),
|
|
environment: root.join("environment"),
|
|
root,
|
|
}
|
|
}
|
|
|
|
fn command(&self) -> Command {
|
|
let mut command = Command::new("bash");
|
|
command
|
|
.arg(&self.launcher)
|
|
.current_dir(&self.root)
|
|
.env("IMPORT_TEST_ARGS", &self.arguments)
|
|
.env("IMPORT_TEST_ENV", &self.environment)
|
|
.env_remove("IMPORT_TEST_STATUS");
|
|
command
|
|
}
|
|
|
|
fn arguments(&self) -> Vec<String> {
|
|
let mut bytes = fs::read(&self.arguments).unwrap();
|
|
assert_eq!(bytes.pop(), Some(0));
|
|
bytes
|
|
.split(|byte| *byte == 0)
|
|
.map(|part| String::from_utf8(part.to_vec()).unwrap())
|
|
.collect()
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn help_and_invalid_sources_do_not_build_or_import() {
|
|
let fixture = Fixture::new();
|
|
let help = fixture.command().arg("--help").output().unwrap();
|
|
assert!(help.status.success());
|
|
assert!(
|
|
String::from_utf8(help.stdout)
|
|
.unwrap()
|
|
.contains("SOURCE_DIRECTORY")
|
|
);
|
|
assert!(!fixture.arguments.exists());
|
|
|
|
for arguments in [vec![], vec![""], vec!["missing source"]] {
|
|
let result = fixture.command().args(arguments).output().unwrap();
|
|
assert_eq!(result.status.code(), Some(2));
|
|
assert!(!fixture.arguments.exists());
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn resolves_source_and_preserves_arguments_and_destination_settings() {
|
|
let fixture = Fixture::new();
|
|
let source_name = "old app; literal $(no-command)";
|
|
let source = fixture.root.join(source_name);
|
|
fs::create_dir(&source).unwrap();
|
|
let result = fixture
|
|
.command()
|
|
.args([
|
|
source_name,
|
|
"--database",
|
|
"docker-data/db/original data.db",
|
|
"--backup-root",
|
|
"/srv/original backups",
|
|
])
|
|
.env("DATA_DIR", "./new storage")
|
|
.env("DATABASE_PATH", "./new storage/custom.db")
|
|
.env("CDPATH", &fixture.root)
|
|
.output()
|
|
.unwrap();
|
|
assert!(result.status.success(), "{:?}", result);
|
|
assert_eq!(
|
|
fixture.arguments(),
|
|
[
|
|
"import-python",
|
|
"--source",
|
|
source.canonicalize().unwrap().to_str().unwrap(),
|
|
"--database",
|
|
"docker-data/db/original data.db",
|
|
"--backup-root",
|
|
"/srv/original backups",
|
|
]
|
|
);
|
|
assert_eq!(
|
|
fs::read(&fixture.environment).unwrap(),
|
|
b"./new storage\0./new storage/custom.db\0"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn forwards_import_failure_without_falling_back_to_serve() {
|
|
let fixture = Fixture::new();
|
|
fs::create_dir(fixture.root.join("source")).unwrap();
|
|
let result = fixture
|
|
.command()
|
|
.arg("source")
|
|
.env("IMPORT_TEST_STATUS", "23")
|
|
.output()
|
|
.unwrap();
|
|
assert_eq!(result.status.code(), Some(23));
|
|
assert_eq!(fixture.arguments().len(), 3);
|
|
assert_eq!(fixture.arguments()[0], "import-python");
|
|
}
|