Skip to content

Commit

Permalink
Fix issue with copying files to test environment
Browse files Browse the repository at this point in the history
Signed-off-by: Ryan Levick <[email protected]>
  • Loading branch information
rylev committed Jan 16, 2024
1 parent 3f308b6 commit 49eb4c8
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 25 deletions.
4 changes: 2 additions & 2 deletions tests/runtime-tests/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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,
};

Expand Down Expand Up @@ -167,7 +167,7 @@ fn required_services(test_path: &Path) -> anyhow::Result<Vec<String>> {
/// Replaces template variables in the manifest file with components from the components path.
fn copy_manifest<R>(test_dir: &Path, env: &mut TestEnvironment<R>) -> 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()
Expand Down
15 changes: 12 additions & 3 deletions tests/testcases/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())?;
}
};
}
}

Expand Down
19 changes: 13 additions & 6 deletions tests/testing-framework/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -82,16 +82,23 @@ impl<E> From<anyhow::Error> for TestError<E> {
}
}

impl<E: std::fmt::Display + std::fmt::Debug> std::error::Error for TestError<E> {}
impl std::error::Error for TestError<anyhow::Error> {}

impl<E: std::fmt::Display> std::fmt::Display for TestError<E> {
impl std::fmt::Display for TestError<anyhow::Error> {
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(())
}
}
33 changes: 19 additions & 14 deletions tests/testing-framework/src/manifest_template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<regex::Regex> = OnceLock::new();
impl ManifestTemplate {
/// Read a manifest template from a file.
static TEMPLATE_REGEX: OnceLock<regex::Regex> = OnceLock::new();
impl EnvTemplate {
/// Instantiate a template.
pub fn new(content: String) -> anyhow::Result<Self> {
Ok(Self { content })
}

/// Read a template from a file.
pub fn from_file(path: impl AsRef<Path>) -> anyhow::Result<Self> {
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<R>(&mut self, env: &mut TestEnvironment<R>) -> 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;
};
Expand Down Expand Up @@ -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
}
}

0 comments on commit 49eb4c8

Please sign in to comment.