From d3ad13279a057c9063573a6c46aed0c0ab1b0fb3 Mon Sep 17 00:00:00 2001 From: Ed Morley <501702+edmorley@users.noreply.github.com> Date: Mon, 27 Nov 2023 14:15:53 +0000 Subject: [PATCH] Add tests for runtime.txt containing invalid unicode Since: - It's not unheard of for apps to contain files with broken content - This is one of the few ways we can integration test the I/O error message generation/copy (most of the other approaches like bad permissions or broken symlinks get filtered out when Pack normalises/transfers the source into the build container. Also removes some unnecessary `vec!` macro usages from some other tests. --- src/layers/pip_dependencies.rs | 4 ++-- src/layers/python.rs | 12 +++++------ src/runtime_txt.rs | 4 ++++ .../requirements.txt | 0 .../runtime_txt_invalid_unicode/runtime.txt | 1 + tests/pip_test.rs | 2 +- tests/python_version_test.rs | 20 +++++++++++++++++++ 7 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 tests/fixtures/runtime_txt_invalid_unicode/requirements.txt create mode 100644 tests/fixtures/runtime_txt_invalid_unicode/runtime.txt diff --git a/src/layers/pip_dependencies.rs b/src/layers/pip_dependencies.rs index 1b31bb8..bbbb212 100644 --- a/src/layers/pip_dependencies.rs +++ b/src/layers/pip_dependencies.rs @@ -159,11 +159,11 @@ mod tests { assert_eq!( utils::environment_as_sorted_vector(&layer_env.apply(Scope::Build, &base_env)), - vec![("PYTHONUSERBASE", "/layers/dependencies")] + [("PYTHONUSERBASE", "/layers/dependencies")] ); assert_eq!( utils::environment_as_sorted_vector(&layer_env.apply(Scope::Launch, &base_env)), - vec![("PYTHONUSERBASE", "/layers/dependencies")] + [("PYTHONUSERBASE", "/layers/dependencies")] ); } } diff --git a/src/layers/python.rs b/src/layers/python.rs index 6331b9c..e62d60f 100644 --- a/src/layers/python.rs +++ b/src/layers/python.rs @@ -477,7 +477,7 @@ mod tests { }; assert_eq!( cache_invalidation_reasons(&cached_metadata, &new_metadata), - vec!["The Python version has changed from 3.11.0 to 3.11.1"] + ["The Python version has changed from 3.11.0 to 3.11.1"] ); } @@ -503,7 +503,7 @@ mod tests { }; assert_eq!( cache_invalidation_reasons(&cached_metadata, &new_metadata), - vec![ + [ "The stack has changed from heroku-20 to heroku-22", "The Python version has changed from 3.9.0 to 3.11.1", "The pip version has changed from A.B.C to A.B.C-new", @@ -527,7 +527,7 @@ mod tests { // Remember to force invalidation of the cached layer if these env vars ever change. assert_eq!( utils::environment_as_sorted_vector(&layer_env.apply_to_empty(Scope::Build)), - vec![ + [ ("CPATH", "/layers/python/include/python3.9"), ("LANG", "C.UTF-8"), ("PIP_DISABLE_PIP_VERSION_CHECK", "1"), @@ -539,7 +539,7 @@ mod tests { ); assert_eq!( utils::environment_as_sorted_vector(&layer_env.apply_to_empty(Scope::Launch)), - vec![ + [ ("CPATH", "/layers/python/include/python3.9"), ("LANG", "C.UTF-8"), ("PIP_DISABLE_PIP_VERSION_CHECK", "1"), @@ -573,7 +573,7 @@ mod tests { // Remember to force invalidation of the cached layer if these env vars ever change. assert_eq!( utils::environment_as_sorted_vector(&layer_env.apply(Scope::Build, &base_env)), - vec![ + [ ("CPATH", "/layers/python/include/python3.11:/base"), ("LANG", "C.UTF-8"), ("PIP_DISABLE_PIP_VERSION_CHECK", "1"), @@ -585,7 +585,7 @@ mod tests { ); assert_eq!( utils::environment_as_sorted_vector(&layer_env.apply(Scope::Launch, &base_env)), - vec![ + [ ("CPATH", "/layers/python/include/python3.11:/base"), ("LANG", "C.UTF-8"), ("PIP_DISABLE_PIP_VERSION_CHECK", "1"), diff --git a/src/runtime_txt.rs b/src/runtime_txt.rs index 481a1d7..e4092a8 100644 --- a/src/runtime_txt.rs +++ b/src/runtime_txt.rs @@ -218,6 +218,10 @@ mod tests { read_version(Path::new("tests/fixtures/empty/.gitkeep")).unwrap_err(), RuntimeTxtError::Read(_) )); + assert!(matches!( + read_version(Path::new("tests/fixtures/runtime_txt_invalid_unicode")).unwrap_err(), + RuntimeTxtError::Read(_) + )); } #[test] diff --git a/tests/fixtures/runtime_txt_invalid_unicode/requirements.txt b/tests/fixtures/runtime_txt_invalid_unicode/requirements.txt new file mode 100644 index 0000000..e69de29 diff --git a/tests/fixtures/runtime_txt_invalid_unicode/runtime.txt b/tests/fixtures/runtime_txt_invalid_unicode/runtime.txt new file mode 100644 index 0000000..bdeb23f --- /dev/null +++ b/tests/fixtures/runtime_txt_invalid_unicode/runtime.txt @@ -0,0 +1 @@ + diff --git a/tests/pip_test.rs b/tests/pip_test.rs index a44233e..638cbb9 100644 --- a/tests/pip_test.rs +++ b/tests/pip_test.rs @@ -106,7 +106,7 @@ fn pip_cache_invalidation_and_metadata_compatibility() { let config = BuildConfig::new(builder(), "tests/fixtures/pip_basic"); TestRunner::default().build( - config.clone().buildpacks(vec![BuildpackReference::Other( + config.clone().buildpacks([BuildpackReference::Other( "docker://docker.io/heroku/buildpack-python:0.1.0".to_string(), )]), |context| { diff --git a/tests/python_version_test.rs b/tests/python_version_test.rs index 1c7cfdd..32502db 100644 --- a/tests/python_version_test.rs +++ b/tests/python_version_test.rs @@ -144,6 +144,26 @@ fn builds_with_python_version(fixture_path: &str, python_version: &str) { }); } +#[test] +#[ignore = "integration test"] +fn runtime_txt_io_error() { + TestRunner::default().build( + BuildConfig::new(builder(), "tests/fixtures/runtime_txt_invalid_unicode") + .expected_pack_result(PackResult::Failure), + |context| { + assert_contains!( + context.pack_stderr, + &formatdoc! {" + [Error: Unable to read runtime.txt] + An unexpected error occurred whilst reading the (optional) runtime.txt file. + + Details: I/O Error: stream did not contain valid UTF-8 + "} + ); + }, + ); +} + #[test] #[ignore = "integration test"] fn runtime_txt_invalid_version() {