From 49eb4c81ee33bafff983cc49060e5ade13a5e22f Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Tue, 16 Jan 2024 20:43:21 +0100 Subject: [PATCH] Fix issue with copying files to test environment Signed-off-by: Ryan Levick --- tests/runtime-tests/src/lib.rs | 4 +-- tests/testcases/mod.rs | 15 +++++++-- tests/testing-framework/src/lib.rs | 19 +++++++---- .../src/manifest_template.rs | 33 +++++++++++-------- 4 files changed, 46 insertions(+), 25 deletions(-) diff --git a/tests/runtime-tests/src/lib.rs b/tests/runtime-tests/src/lib.rs index 3d983a5290..d581ab995c 100644 --- a/tests/runtime-tests/src/lib.rs +++ b/tests/runtime-tests/src/lib.rs @@ -1,7 +1,7 @@ use anyhow::Context; use std::path::{Path, PathBuf}; use testing_framework::{ - ManifestTemplate, OnTestError, ServicesConfig, Spin, TestEnvironment, TestEnvironmentConfig, + EnvTemplate, OnTestError, ServicesConfig, Spin, TestEnvironment, TestEnvironmentConfig, TestError, TestResult, }; @@ -167,7 +167,7 @@ fn required_services(test_path: &Path) -> anyhow::Result> { /// Replaces template variables in the manifest file with components from the components path. fn copy_manifest(test_dir: &Path, env: &mut TestEnvironment) -> anyhow::Result<()> { let manifest_path = test_dir.join("spin.toml"); - let mut manifest = ManifestTemplate::from_file(manifest_path).with_context(|| { + let mut manifest = EnvTemplate::from_file(manifest_path).with_context(|| { format!( "no spin.toml manifest found in test directory {}", test_dir.display() diff --git a/tests/testcases/mod.rs b/tests/testcases/mod.rs index a8af92991d..365a809b96 100644 --- a/tests/testcases/mod.rs +++ b/tests/testcases/mod.rs @@ -87,9 +87,18 @@ fn preboot( if path.is_dir() { env.copy_into(&path, path.file_name().unwrap())?; } else { - let mut template = testing_framework::ManifestTemplate::from_file(&path)?; - template.substitute(env)?; - env.write_file(path.file_name().unwrap(), template.contents())?; + let content = std::fs::read(&path) + .with_context(|| format!("failed to read file '{}' for copying", path.display()))?; + match String::from_utf8(content) { + Ok(content) => { + let mut template = testing_framework::EnvTemplate::new(content)?; + template.substitute(env)?; + env.write_file(path.file_name().unwrap(), template.contents())?; + } + Err(e) => { + env.write_file(path.file_name().unwrap(), e.as_bytes())?; + } + }; } } diff --git a/tests/testing-framework/src/lib.rs b/tests/testing-framework/src/lib.rs index a2a377b519..cc8c8fe267 100644 --- a/tests/testing-framework/src/lib.rs +++ b/tests/testing-framework/src/lib.rs @@ -10,7 +10,7 @@ mod services; mod spin; mod test_environment; -pub use manifest_template::ManifestTemplate; +pub use manifest_template::EnvTemplate; pub use services::ServicesConfig; pub use spin::{Request, Spin, SpinMode}; pub use test_environment::{TestEnvironment, TestEnvironmentConfig}; @@ -82,16 +82,23 @@ impl From for TestError { } } -impl std::error::Error for TestError {} +impl std::error::Error for TestError {} -impl std::fmt::Display for TestError { +impl std::fmt::Display for TestError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { + let e = match self { TestError::Failure(e) => { write!(f, "{e}")?; - Ok(()) + e } - TestError::Fatal(e) => write!(f, "Test failed to run: {}", e), + TestError::Fatal(e) => { + write!(f, "Test failed to run: {}", e)?; + e + } + }; + for cause in e.chain().skip(1) { + write!(f, "\n Caused by: {}", cause)?; } + Ok(()) } } diff --git a/tests/testing-framework/src/manifest_template.rs b/tests/testing-framework/src/manifest_template.rs index f1b4533a4b..6a7553dbd8 100644 --- a/tests/testing-framework/src/manifest_template.rs +++ b/tests/testing-framework/src/manifest_template.rs @@ -3,25 +3,30 @@ use std::{path::Path, sync::OnceLock}; use crate::TestEnvironment; -/// A manifest template with template variables that can be substituted. -pub struct ManifestTemplate { - manifest: String, +/// A template with variables that can be substituted with information from the testing environment. +pub struct EnvTemplate { + content: String, } -static TEMPLATE: OnceLock = OnceLock::new(); -impl ManifestTemplate { - /// Read a manifest template from a file. +static TEMPLATE_REGEX: OnceLock = OnceLock::new(); +impl EnvTemplate { + /// Instantiate a template. + pub fn new(content: String) -> anyhow::Result { + Ok(Self { content }) + } + + /// Read a template from a file. pub fn from_file(path: impl AsRef) -> anyhow::Result { let path = path.as_ref(); - let manifest = std::fs::read_to_string(path) - .with_context(|| format!("could not read manifest template at '{}'", path.display()))?; - Ok(Self { manifest }) + let content = std::fs::read_to_string(path) + .with_context(|| format!("could not read template at '{}'", path.display()))?; + Ok(Self { content }) } - /// Substitute template variables in the manifest template. + /// Substitute template variables in the template. pub fn substitute(&mut self, env: &mut TestEnvironment) -> Result<(), anyhow::Error> { - let regex = TEMPLATE.get_or_init(|| regex::Regex::new(r"%\{(.*?)\}").unwrap()); - while let Some(captures) = regex.captures(&self.manifest) { + let regex = TEMPLATE_REGEX.get_or_init(|| regex::Regex::new(r"%\{(.*?)\}").unwrap()); + while let Some(captures) = regex.captures(&self.content) { let (Some(full), Some(capture)) = (captures.get(0), captures.get(1)) else { continue; }; @@ -52,12 +57,12 @@ impl ManifestTemplate { anyhow::bail!("unknown template key: {template_key}"); } }; - self.manifest.replace_range(full.range(), &replacement); + self.content.replace_range(full.range(), &replacement); } Ok(()) } pub fn contents(&self) -> &str { - &self.manifest + &self.content } }