From a6e6db28c6f0b40314e203c0afa6b7e280c8bc9a Mon Sep 17 00:00:00 2001 From: Ed Morley <501702+edmorley@users.noreply.github.com> Date: Thu, 2 Nov 2023 19:51:24 +0000 Subject: [PATCH] Add more integration tests to libcnb-test (#717) Improves the integration test coverage in preparation for fixing #666, so as to (a) reduce the size of that PR, (b) make it easier to see the before/after of the error output. GUS-W-14416222. --- .../buildpacks/compile-error/Cargo.toml | 6 + .../buildpacks/compile-error/buildpack.toml | 8 + .../buildpacks/compile-error/src/main.rs | 3 + .../{libcnb-test-a => component-a}/Cargo.toml | 3 +- .../buildpack.toml | 0 .../src/main.rs | 0 .../{libcnb-test-b => component-b}/Cargo.toml | 3 +- .../buildpack.toml | 0 .../src/main.rs | 0 .../buildpack.toml | 11 + .../buildpack.toml | 4 + .../package.toml | 2 + .../invalid-buildpack-toml/buildpack.toml | 11 + .../buildpacks/invalid-cargo-toml/Cargo.toml | 4 + .../invalid-cargo-toml/buildpack.toml | 8 + libcnb-test/tests/integration_test.rs | 224 ++++++++++++++---- 16 files changed, 243 insertions(+), 44 deletions(-) create mode 100644 libcnb-test/tests/fixtures/buildpacks/compile-error/Cargo.toml create mode 100644 libcnb-test/tests/fixtures/buildpacks/compile-error/buildpack.toml create mode 100644 libcnb-test/tests/fixtures/buildpacks/compile-error/src/main.rs rename libcnb-test/tests/fixtures/buildpacks/{libcnb-test-a => component-a}/Cargo.toml (52%) rename libcnb-test/tests/fixtures/buildpacks/{libcnb-test-a => component-a}/buildpack.toml (100%) rename libcnb-test/tests/fixtures/buildpacks/{libcnb-test-a => component-a}/src/main.rs (100%) rename libcnb-test/tests/fixtures/buildpacks/{libcnb-test-b => component-b}/Cargo.toml (52%) rename libcnb-test/tests/fixtures/buildpacks/{libcnb-test-b => component-b}/buildpack.toml (100%) rename libcnb-test/tests/fixtures/buildpacks/{libcnb-test-b => component-b}/src/main.rs (100%) create mode 100644 libcnb-test/tests/fixtures/buildpacks/composite-missing-package-toml/buildpack.toml rename libcnb-test/tests/fixtures/buildpacks/{libcnb-test-composite => composite}/buildpack.toml (86%) rename libcnb-test/tests/fixtures/buildpacks/{libcnb-test-composite => composite}/package.toml (62%) create mode 100644 libcnb-test/tests/fixtures/buildpacks/invalid-buildpack-toml/buildpack.toml create mode 100644 libcnb-test/tests/fixtures/buildpacks/invalid-cargo-toml/Cargo.toml create mode 100644 libcnb-test/tests/fixtures/buildpacks/invalid-cargo-toml/buildpack.toml diff --git a/libcnb-test/tests/fixtures/buildpacks/compile-error/Cargo.toml b/libcnb-test/tests/fixtures/buildpacks/compile-error/Cargo.toml new file mode 100644 index 00000000..e3faf7b5 --- /dev/null +++ b/libcnb-test/tests/fixtures/buildpacks/compile-error/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "compile-error" +version = "0.0.0" +publish = false + +[workspace] diff --git a/libcnb-test/tests/fixtures/buildpacks/compile-error/buildpack.toml b/libcnb-test/tests/fixtures/buildpacks/compile-error/buildpack.toml new file mode 100644 index 00000000..ec475691 --- /dev/null +++ b/libcnb-test/tests/fixtures/buildpacks/compile-error/buildpack.toml @@ -0,0 +1,8 @@ +api = "0.8" + +[buildpack] +id = "libcnb-test/compile-error" +version = "0.0.0" + +[[stacks]] +id = "*" diff --git a/libcnb-test/tests/fixtures/buildpacks/compile-error/src/main.rs b/libcnb-test/tests/fixtures/buildpacks/compile-error/src/main.rs new file mode 100644 index 00000000..0dc993eb --- /dev/null +++ b/libcnb-test/tests/fixtures/buildpacks/compile-error/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + compile_error!("Example compile error"); +} diff --git a/libcnb-test/tests/fixtures/buildpacks/libcnb-test-a/Cargo.toml b/libcnb-test/tests/fixtures/buildpacks/component-a/Cargo.toml similarity index 52% rename from libcnb-test/tests/fixtures/buildpacks/libcnb-test-a/Cargo.toml rename to libcnb-test/tests/fixtures/buildpacks/component-a/Cargo.toml index d8e77621..5911f13c 100644 --- a/libcnb-test/tests/fixtures/buildpacks/libcnb-test-a/Cargo.toml +++ b/libcnb-test/tests/fixtures/buildpacks/component-a/Cargo.toml @@ -1,5 +1,6 @@ [package] -name = "one" +name = "component-a" version = "0.0.0" +publish = false [workspace] diff --git a/libcnb-test/tests/fixtures/buildpacks/libcnb-test-a/buildpack.toml b/libcnb-test/tests/fixtures/buildpacks/component-a/buildpack.toml similarity index 100% rename from libcnb-test/tests/fixtures/buildpacks/libcnb-test-a/buildpack.toml rename to libcnb-test/tests/fixtures/buildpacks/component-a/buildpack.toml diff --git a/libcnb-test/tests/fixtures/buildpacks/libcnb-test-a/src/main.rs b/libcnb-test/tests/fixtures/buildpacks/component-a/src/main.rs similarity index 100% rename from libcnb-test/tests/fixtures/buildpacks/libcnb-test-a/src/main.rs rename to libcnb-test/tests/fixtures/buildpacks/component-a/src/main.rs diff --git a/libcnb-test/tests/fixtures/buildpacks/libcnb-test-b/Cargo.toml b/libcnb-test/tests/fixtures/buildpacks/component-b/Cargo.toml similarity index 52% rename from libcnb-test/tests/fixtures/buildpacks/libcnb-test-b/Cargo.toml rename to libcnb-test/tests/fixtures/buildpacks/component-b/Cargo.toml index 504aeb84..8b26c691 100644 --- a/libcnb-test/tests/fixtures/buildpacks/libcnb-test-b/Cargo.toml +++ b/libcnb-test/tests/fixtures/buildpacks/component-b/Cargo.toml @@ -1,5 +1,6 @@ [package] -name = "two" +name = "component-b" version = "0.0.0" +publish = false [workspace] diff --git a/libcnb-test/tests/fixtures/buildpacks/libcnb-test-b/buildpack.toml b/libcnb-test/tests/fixtures/buildpacks/component-b/buildpack.toml similarity index 100% rename from libcnb-test/tests/fixtures/buildpacks/libcnb-test-b/buildpack.toml rename to libcnb-test/tests/fixtures/buildpacks/component-b/buildpack.toml diff --git a/libcnb-test/tests/fixtures/buildpacks/libcnb-test-b/src/main.rs b/libcnb-test/tests/fixtures/buildpacks/component-b/src/main.rs similarity index 100% rename from libcnb-test/tests/fixtures/buildpacks/libcnb-test-b/src/main.rs rename to libcnb-test/tests/fixtures/buildpacks/component-b/src/main.rs diff --git a/libcnb-test/tests/fixtures/buildpacks/composite-missing-package-toml/buildpack.toml b/libcnb-test/tests/fixtures/buildpacks/composite-missing-package-toml/buildpack.toml new file mode 100644 index 00000000..6761b6e3 --- /dev/null +++ b/libcnb-test/tests/fixtures/buildpacks/composite-missing-package-toml/buildpack.toml @@ -0,0 +1,11 @@ +api = "0.8" + +[buildpack] +id = "libcnb-test/composite-missing-package-toml" +version = "0.0.0" + +[[order]] + +[[order.group]] +id = "libcnb-test/a" +version = "0.0.0" diff --git a/libcnb-test/tests/fixtures/buildpacks/libcnb-test-composite/buildpack.toml b/libcnb-test/tests/fixtures/buildpacks/composite/buildpack.toml similarity index 86% rename from libcnb-test/tests/fixtures/buildpacks/libcnb-test-composite/buildpack.toml rename to libcnb-test/tests/fixtures/buildpacks/composite/buildpack.toml index 95706626..843db3dc 100644 --- a/libcnb-test/tests/fixtures/buildpacks/libcnb-test-composite/buildpack.toml +++ b/libcnb-test/tests/fixtures/buildpacks/composite/buildpack.toml @@ -20,3 +20,7 @@ version = "0.0.0" [[order.group]] id = "libcnb-test/b" version = "0.0.0" + +[[order.group]] +id = "heroku/procfile" +version = "2.0.2" diff --git a/libcnb-test/tests/fixtures/buildpacks/libcnb-test-composite/package.toml b/libcnb-test/tests/fixtures/buildpacks/composite/package.toml similarity index 62% rename from libcnb-test/tests/fixtures/buildpacks/libcnb-test-composite/package.toml rename to libcnb-test/tests/fixtures/buildpacks/composite/package.toml index 5371f16a..91658820 100644 --- a/libcnb-test/tests/fixtures/buildpacks/libcnb-test-composite/package.toml +++ b/libcnb-test/tests/fixtures/buildpacks/composite/package.toml @@ -7,3 +7,5 @@ uri = "libcnb:libcnb-test/a" [[dependencies]] uri = "libcnb:libcnb-test/b" +[[dependencies]] +uri = "docker://docker.io/heroku/procfile-cnb:2.0.2" diff --git a/libcnb-test/tests/fixtures/buildpacks/invalid-buildpack-toml/buildpack.toml b/libcnb-test/tests/fixtures/buildpacks/invalid-buildpack-toml/buildpack.toml new file mode 100644 index 00000000..a0fdf2ae --- /dev/null +++ b/libcnb-test/tests/fixtures/buildpacks/invalid-buildpack-toml/buildpack.toml @@ -0,0 +1,11 @@ +api = "0.8" + +[buildpack] +id = "libcnb-test/invalid-buildpack-toml" +version = "0.0.0" + +[[order]] + +[[order.group]] +id = "libcnb-test/a" +# `version` is a required field, but is missing. diff --git a/libcnb-test/tests/fixtures/buildpacks/invalid-cargo-toml/Cargo.toml b/libcnb-test/tests/fixtures/buildpacks/invalid-cargo-toml/Cargo.toml new file mode 100644 index 00000000..91548c09 --- /dev/null +++ b/libcnb-test/tests/fixtures/buildpacks/invalid-cargo-toml/Cargo.toml @@ -0,0 +1,4 @@ +[package] +# `name` and `version` are a required fields, but are missing. + +[workspace] diff --git a/libcnb-test/tests/fixtures/buildpacks/invalid-cargo-toml/buildpack.toml b/libcnb-test/tests/fixtures/buildpacks/invalid-cargo-toml/buildpack.toml new file mode 100644 index 00000000..3fec6b1e --- /dev/null +++ b/libcnb-test/tests/fixtures/buildpacks/invalid-cargo-toml/buildpack.toml @@ -0,0 +1,8 @@ +api = "0.8" + +[buildpack] +id = "libcnb-test/invalid-cargo-toml" +version = "0.0.0" + +[[stacks]] +id = "*" diff --git a/libcnb-test/tests/integration_test.rs b/libcnb-test/tests/integration_test.rs index 38b17f95..640acead 100644 --- a/libcnb-test/tests/integration_test.rs +++ b/libcnb-test/tests/integration_test.rs @@ -24,9 +24,13 @@ use std::{env, fs, panic, thread}; const PROCFILE_URL: &str = "heroku/procfile"; const TEST_PORT: u16 = 12345; +// Note: Since the `libcnb-test` crate isn't a buildpack itself, we can't test a successful +// build using `BuildpackReference::CurrentCrate` here, but we still have test coverage of it +// thanksĀ to the integration tests under `examples/` and `test-buildpacks/`. + #[test] #[ignore = "integration test"] -fn basic_build() { +fn build_other_buildpack() { TestRunner::default().build( BuildConfig::new("heroku/builder:22", "tests/fixtures/procfile") .buildpacks([BuildpackReference::Other(String::from(PROCFILE_URL))]), @@ -43,6 +47,73 @@ fn basic_build() { ); } +#[test] +#[ignore = "integration test"] +fn build_workspace_component_buildpack() { + TestRunner::default().build( + BuildConfig::new("heroku/builder:22", "tests/fixtures/empty").buildpacks([ + BuildpackReference::WorkspaceBuildpack(buildpack_id!("libcnb-test/a")), + ]), + |context| { + assert_empty!(context.pack_stderr); + assert_contains!( + context.pack_stdout, + indoc! {" + Buildpack A + "} + ); + }, + ); +} + +#[test] +#[ignore = "integration test"] +fn build_workspace_composite_buildpack() { + TestRunner::default().build( + BuildConfig::new("heroku/builder:22", "tests/fixtures/procfile").buildpacks([ + BuildpackReference::WorkspaceBuildpack(buildpack_id!("libcnb-test/composite")), + ]), + |context| { + assert_empty!(context.pack_stderr); + assert_contains!( + context.pack_stdout, + indoc! {" + Buildpack A + Buildpack B + + [Discovering process types] + Procfile declares types -> web, worker, echo-args + "} + ); + }, + ); +} + +#[test] +#[ignore = "integration test"] +fn build_multiple_buildpacks() { + TestRunner::default().build( + BuildConfig::new("heroku/builder:22", "tests/fixtures/procfile").buildpacks([ + BuildpackReference::WorkspaceBuildpack(buildpack_id!("libcnb-test/b")), + BuildpackReference::Other(String::from(PROCFILE_URL)), + BuildpackReference::WorkspaceBuildpack(buildpack_id!("libcnb-test/a")), + ]), + |context| { + assert_empty!(context.pack_stderr); + assert_contains!( + context.pack_stdout, + indoc! {" + Buildpack B + + [Discovering process types] + Procfile declares types -> web, worker, echo-args + Buildpack A + "} + ); + }, + ); +} + #[test] #[ignore = "integration test"] fn rebuild() { @@ -64,7 +135,7 @@ fn rebuild() { #[test] #[ignore = "integration test"] -fn buildpack_packaging_failure() { +fn packaging_failure_missing_buildpack_toml() { let err = panic::catch_unwind(|| { TestRunner::default().build(BuildConfig::new("invalid!", "tests/fixtures/empty"), |_| { unreachable!("The test should panic prior to the TestContext being invoked."); @@ -81,6 +152,114 @@ fn buildpack_packaging_failure() { ); } +#[test] +#[ignore = "integration test"] +// TODO: Fix the implementation to return the correct error message (that the buildpack.toml doesn't match the schema): +// https://github.com/heroku/libcnb.rs/issues/708 +#[should_panic( + expected = "Could not package directory as buildpack! No buildpack with id `libcnb-test/invalid-buildpack-toml` exists in the workspace at" +)] +fn packaging_failure_invalid_buildpack_toml() { + TestRunner::default().build( + BuildConfig::new("invalid!", "tests/fixtures/empty").buildpacks([ + BuildpackReference::WorkspaceBuildpack(buildpack_id!( + "libcnb-test/invalid-buildpack-toml" + )), + ]), + |_| { + unreachable!("The test should panic prior to the TestContext being invoked."); + }, + ); +} + +#[test] +#[ignore = "integration test"] +// TODO: Fix the implementation to return the correct error message. Has the same cause as: +// https://github.com/heroku/libcnb.rs/issues/704 +#[should_panic( + expected = "Test references buildpack `libcnb-test/composite-missing-package-toml`, but this directory wasn't packaged as a buildpack. This is an internal libcnb-test error, please report any occurrences" +)] +fn packaging_failure_composite_buildpack_missing_package_toml() { + TestRunner::default().build( + BuildConfig::new("invalid!", "tests/fixtures/empty").buildpacks([ + BuildpackReference::WorkspaceBuildpack(buildpack_id!( + "libcnb-test/composite-missing-package-toml" + )), + ]), + |_| { + unreachable!("The test should panic prior to the TestContext being invoked."); + }, + ); +} + +#[test] +#[ignore = "integration test"] +// TODO: Fix the implementation to return the correct error message. Has the same cause as: +// https://github.com/heroku/libcnb.rs/issues/704 +#[should_panic( + expected = "Test references buildpack `libcnb-test/invalid-cargo-toml`, but this directory wasn't packaged as a buildpack. This is an internal libcnb-test error, please report any occurrences" +)] +fn packaging_failure_invalid_cargo_toml() { + TestRunner::default().build( + BuildConfig::new("invalid!", "tests/fixtures/empty").buildpacks([ + BuildpackReference::WorkspaceBuildpack(buildpack_id!("libcnb-test/invalid-cargo-toml")), + ]), + |_| { + unreachable!("The test should panic prior to the TestContext being invoked."); + }, + ); +} + +#[test] +#[ignore = "integration test"] +// TODO: Fix the implementation to return the correct error message. Has the same cause as: +// https://github.com/heroku/libcnb.rs/issues/704 +#[should_panic( + expected = "Test references buildpack `libcnb-test/compile-error`, but this directory wasn't packaged as a buildpack. This is an internal libcnb-test error, please report any occurrences" +)] +fn packaging_failure_compile_error() { + TestRunner::default().build( + BuildConfig::new("invalid!", "tests/fixtures/empty").buildpacks([ + BuildpackReference::WorkspaceBuildpack(buildpack_id!("libcnb-test/compile-error")), + ]), + |_| { + unreachable!("The test should panic prior to the TestContext being invoked."); + }, + ); +} + +#[test] +#[ignore = "integration test"] +fn packaging_failure_non_existent_workspace_buildpack() { + let err = panic::catch_unwind(|| { + TestRunner::default().build( + BuildConfig::new("invalid!", "tests/fixtures/empty").buildpacks([ + BuildpackReference::WorkspaceBuildpack(buildpack_id!("non-existent")), + ]), + |_| { + unreachable!("The test should panic prior to the TestContext being invoked."); + }, + ); + }) + .unwrap_err(); + + assert_eq!( + err.downcast_ref::().unwrap(), + &format!( + "Could not package directory as buildpack! No buildpack with id `non-existent` exists in the workspace at {}", + // There is currently no env var for determining the workspace root directly: + // https://github.com/rust-lang/cargo/issues/3946 + env::var("CARGO_MANIFEST_DIR") + .map(PathBuf::from) + .unwrap() + .join("../") + .canonicalize() + .unwrap() + .display() + ) + ); +} + #[test] #[ignore = "integration test"] #[should_panic(expected = "Error performing pack build: @@ -257,7 +436,7 @@ pack command failed with exit code 1! ERROR: image 'libcnbtest_")] fn download_sbom_files_failure() { TestRunner::default().build( - BuildConfig::new("heroku/builder:22", "tests/fixtures/empty") + BuildConfig::new("invalid!", "tests/fixtures/empty") .buildpacks(Vec::new()) .expected_pack_result(PackResult::Failure), |context| { @@ -526,42 +705,3 @@ fn address_for_port_when_container_crashed() { "} ); } - -#[test] -#[ignore = "integration test"] -fn basic_build_with_libcnb_reference_to_single_buildpack() { - TestRunner::default().build( - BuildConfig::new("heroku/builder:22", "tests/fixtures/empty").buildpacks([ - BuildpackReference::WorkspaceBuildpack(buildpack_id!("libcnb-test/a")), - ]), - |context| { - assert_empty!(context.pack_stderr); - assert_contains!( - context.pack_stdout, - indoc! {" - Buildpack A - "} - ); - }, - ); -} - -#[test] -#[ignore = "integration test"] -fn basic_build_with_libcnb_reference_to_composite_buildpack() { - TestRunner::default().build( - BuildConfig::new("heroku/builder:22", "tests/fixtures/empty").buildpacks([ - BuildpackReference::WorkspaceBuildpack(buildpack_id!("libcnb-test/composite")), - ]), - |context| { - assert_empty!(context.pack_stderr); - assert_contains!( - context.pack_stdout, - indoc! {" - Buildpack A - Buildpack B - "} - ); - }, - ); -}