From 9a9ba9769215cbbee90b311f0afef916ce64dc88 Mon Sep 17 00:00:00 2001 From: Ed Morley <501702+edmorley@users.noreply.github.com> Date: Mon, 20 Jun 2022 13:52:00 +0100 Subject: [PATCH] Improve integration test coverage (#75) Whilst the unit tests for this repository are very comprehensive, much of the end buildpack behaviour depends on Pack CLI / `lifecycle` / the buildpack API version, which aren't tested by the unit tests. For example Buildpack API 0.6 changed the default process handling in a breaking way: https://github.com/buildpacks/spec/releases/tag/buildpack%2Fv0.6 Now that `libcnb-test` has added support for more methods of invoking the built containers (see https://github.com/heroku/libcnb.rs/pull/366), we are able to add integration tests for more than just a single `web` process example. This PR: - Adds five additional integration tests. - Drops the usage of `ureq` / making HTTPS requests to the `web` process, in favour of a simpler `echo` / logs output based approach. The only reason the former approach was used was because of the "valid Procfile but not valid YAML" case (see 741bbc03131eb6029ac86510c5816b3350de1f98), however that is now tested via a simpler `echo` fixture that includes the offending `"key: value"` substring, rather than the `socat` example command. - Drops usage of `tempfile` / manually writing files in the unit tests, in favour of reading files from the fixtures directory. - Uses `indoc!` to assert against multi-line log output strings, to make the end output more clearly visible from the test, and also reduce the chance of false positives (for example, `Procfile declares types -> web` would previously successfully match against `Procfile declares types -> web, something-else` since there was no end of line marker). - Uses the new `ignore = "reason"` support in Rust 1.61, to make it clearer why (integration) tests are being skipped when running `cargo test`. - Remove the redundant `.buildpacks(vec![BuildpackReference::Crate])` calls, since the current buildpack is the default when using `libcnb-test`'s `run_test()`. - Removes `RUST_BACKTRACE=1` from the Circle CI configs, since in general the backtraces are noisy (making it harder to read the actual error) and add little value over the file+line number that's already output in the standard error message. In rare scenarios where the backtrace is actually useful, it can be enabled locally, or on a Circle CI run with a debugging commit pushed to the PR etc. - Adds `heroku/builder:22` to the trusted builders list, since otherwise it slows down builds, and also means log output has additional prefixes, which mess up the multi-line assertions. Longer term we will add this builder to Pack's built-in trusted builders list, and also make `libcnb-test` pass `--trust-builder` to the `pack build` command: https://github.com/heroku/libcnb.rs/issues/407 GUS-W-11311966. --- .circleci/config.yml | 6 +- Cargo.lock | 287 +++++++++--------- Cargo.toml | 4 +- README.md | 12 +- src/main.rs | 19 +- tests/fixtures/app_with_procfile/Procfile | 2 - .../Procfile | 0 .../.gitkeep | 0 .../multiple_non_web_procfile/Procfile | 2 + tests/fixtures/not_yaml_procfile/Procfile | 7 + .../fixtures/web_and_worker_procfile/Procfile | 2 + tests/fixtures/worker_only_procfile/Procfile | 1 + tests/integration_test.rs | 174 +++++++++-- 13 files changed, 317 insertions(+), 199 deletions(-) delete mode 100644 tests/fixtures/app_with_procfile/Procfile rename tests/fixtures/{app_with_empty_procfile => empty_procfile}/Procfile (100%) rename tests/fixtures/{app_without_procfile => missing_procfile}/.gitkeep (100%) create mode 100644 tests/fixtures/multiple_non_web_procfile/Procfile create mode 100644 tests/fixtures/not_yaml_procfile/Procfile create mode 100644 tests/fixtures/web_and_worker_procfile/Procfile create mode 100644 tests/fixtures/worker_only_procfile/Procfile diff --git a/.circleci/config.yml b/.circleci/config.yml index 5b21ff3..d372540 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -59,9 +59,13 @@ jobs: - run: name: Add musl target command: rustup target add x86_64-unknown-linux-musl + # This can be removed when https://github.com/heroku/libcnb.rs/issues/407 is fixed. + - run: + name: Mark heroku/builder:22 as a trusted builder + command: pack config trusted-builders add heroku/builder:22 - run: name: Run tests - command: RUST_BACKTRACE=1 cargo test --all-features --locked -- --include-ignored + command: cargo test --all-features --locked -- --include-ignored - save-cargo-cache workflows: diff --git a/Cargo.lock b/Cargo.lock index f3029ea..23642c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -101,9 +101,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.9.1" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" +checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" [[package]] name = "bytes" @@ -113,9 +113,9 @@ checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] name = "camino" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3132262930b0522068049f5870a856ab8affc80c70d08b6ecb785771a6fc23" +checksum = "869119e97797867fd90f5e22af7d0bd274bd4635ebb9eb68c04f3f513ae6c412" dependencies = [ "serde", ] @@ -274,9 +274,9 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" +checksum = "c0408e2626025178a6a7f7ffc05a25bc47103229f19c113755de7bf63816290c" dependencies = [ "cfg-if", "libc", @@ -286,13 +286,11 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af" +checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" dependencies = [ - "cfg-if", "crc32fast", - "libc", "miniz_oxide", ] @@ -401,9 +399,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" [[package]] name = "hermit-abi" @@ -422,9 +420,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "http" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ "bytes", "fnv", @@ -433,9 +431,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", "http", @@ -444,9 +442,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.7.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6330e8a36bd8c859f3fa6d9382911fbb7147ec39807f63b923933a247240b9ba" +checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" [[package]] name = "httpdate" @@ -456,9 +454,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.18" +version = "0.14.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2" +checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f" dependencies = [ "bytes", "futures-channel", @@ -510,9 +508,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" +checksum = "6c6392766afd7964e2531940894cffe4bd8d7d17dbc3c1c4857040fd4b33bdb3" dependencies = [ "autocfg", "hashbrown", @@ -535,15 +533,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" [[package]] name = "js-sys" -version = "0.3.57" +version = "0.3.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" +checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" dependencies = [ "wasm-bindgen", ] @@ -556,9 +554,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.122" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" [[package]] name = "libcnb" @@ -651,9 +649,9 @@ checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" [[package]] name = "log" -version = "0.4.16" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] @@ -666,56 +664,36 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "memchr" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "miniz_oxide" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" +checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" +checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799" dependencies = [ "libc", "log", - "miow", - "ntapi", "wasi 0.11.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", -] - -[[package]] -name = "ntapi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" -dependencies = [ - "winapi", + "windows-sys", ] [[package]] name = "num-integer" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ "autocfg", "num-traits", @@ -723,9 +701,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", ] @@ -742,9 +720,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" [[package]] name = "pathdiff" @@ -780,9 +758,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "pin-utils" @@ -792,11 +770,11 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "proc-macro2" -version = "1.0.37" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" +checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] @@ -809,9 +787,7 @@ dependencies = [ "libherokubuildpack", "linked-hash-map", "regex", - "tempfile", "thiserror", - "ureq", ] [[package]] @@ -875,9 +851,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.4" +version = "0.20.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fbfeb8d0ddb84706bc597a5574ab8912817c52a397f819e5b614e2265206921" +checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" dependencies = [ "log", "ring", @@ -885,17 +861,11 @@ dependencies = [ "webpki", ] -[[package]] -name = "rustversion" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" - [[package]] name = "ryu" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" [[package]] name = "sct" @@ -909,27 +879,27 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.7" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4" +checksum = "a41d061efea015927ac527063765e73601444cdc344ba855bc7bd44578b25e1c" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.136" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.136" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" dependencies = [ "proc-macro2", "quote", @@ -938,9 +908,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.79" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" dependencies = [ "itoa", "ryu", @@ -961,11 +931,10 @@ dependencies = [ [[package]] name = "serde_with" -version = "1.12.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "946fa04a8ac43ff78a1f4b811990afb9ddbdf5890b46d6dda0ba1998230138b7" +checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff" dependencies = [ - "rustversion", "serde", "serde_with_macros", ] @@ -1023,13 +992,13 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.91" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" +checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -1099,9 +1068,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ "tinyvec_macros", ] @@ -1114,15 +1083,16 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.17.0" +version = "1.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee" +checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439" dependencies = [ "bytes", "libc", "memchr", "mio", "num_cpus", + "once_cell", "pin-project-lite", "socket2", "winapi", @@ -1130,9 +1100,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3" +checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9" dependencies = [ "futures-core", "pin-project-lite", @@ -1141,9 +1111,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764" +checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" dependencies = [ "bytes", "futures-core", @@ -1155,9 +1125,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" dependencies = [ "serde", ] @@ -1170,34 +1140,22 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.33" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80b9fa4360528139bc96100c160b7ae879f5567f49f1782b0b02035b0358ebf3" +checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" dependencies = [ "cfg-if", "pin-project-lite", - "tracing-attributes", "tracing-core", ] -[[package]] -name = "tracing-attributes" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "tracing-core" -version = "0.1.24" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90442985ee2f57c9e1b548ee72ae842f4a9a20e3f417cc38dbc5dc684d9bb4ee" +checksum = "7709595b8878a4965ce5e87ebf880a7d39c9afc6837721b21a5a816a8117d921" dependencies = [ - "lazy_static", + "once_cell", ] [[package]] @@ -1214,9 +1172,15 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "unicode-bidi" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" + +[[package]] +name = "unicode-ident" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" [[package]] name = "unicode-normalization" @@ -1227,12 +1191,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - [[package]] name = "untrusted" version = "0.7.1" @@ -1298,9 +1256,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" +checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1308,9 +1266,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" +checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" dependencies = [ "bumpalo", "lazy_static", @@ -1323,9 +1281,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" +checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1333,9 +1291,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" +checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" dependencies = [ "proc-macro2", "quote", @@ -1346,15 +1304,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" +checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" [[package]] name = "web-sys" -version = "0.3.57" +version = "0.3.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" +checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90" dependencies = [ "js-sys", "wasm-bindgen", @@ -1421,11 +1379,54 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + [[package]] name = "xattr" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" +checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" dependencies = [ "libc", ] diff --git a/Cargo.toml b/Cargo.toml index 80ef338..e94bc41 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ name = "procfile-buildpack" version = "0.0.0" publish = false edition = "2021" -rust-version = "1.60" +rust-version = "1.61" [dependencies] indoc = "1.0.6" @@ -16,5 +16,3 @@ thiserror = "1.0.31" [dev-dependencies] libcnb-test = "0.3.1" -tempfile = "3.3.0" -ureq = "2.4.0" diff --git a/README.md b/README.md index 253cece..b79e3a9 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ This is a [Cloud Native Buildpack](https://buildpacks.io/) that replicates the behavior of `Procfile` in [Heroku Buildpacks](https://devcenter.heroku.com/articles/buildpacks). -It is written in Rust using the Cloud Native Buildpack framework [libcnb.rs](https://github.com/Malax/libcnb.rs). +It is written in Rust using the Cloud Native Buildpack framework [libcnb.rs](https://github.com/heroku/libcnb.rs). ## Deployment @@ -30,7 +30,7 @@ version of the buildpack. A detailed procedure is available [here](github.com/he ### Prerequisites -See [Development Environment Setup](https://github.com/Malax/libcnb.rs#development-environment-setup). +See [Development Environment Setup](https://github.com/heroku/libcnb.rs#development-environment-setup). ### Test @@ -56,14 +56,14 @@ $ cargo test -- --include-ignored ``` $ cargo libcnb package \ -&& pack build procfile_example_app --builder heroku/builder:22 --buildpack target/buildpack/debug/heroku_procfile --path tests/fixtures/app_with_procfile --verbose \ +&& pack build procfile_example_app --builder heroku/builder:22 --buildpack target/buildpack/debug/heroku_procfile --path tests/fixtures/web_and_worker_procfile --verbose \ && docker run -it --rm --entrypoint worker procfile_example_app ``` ``` $ pack inspect procfile_example_app | grep -A10 Processes Processes: - TYPE SHELL COMMAND ARGS - web (default) bash node index.js - worker bash while true; do echo 'lol'; sleep 2; done + TYPE SHELL COMMAND ARGS WORK DIR + web (default) bash echo 'this is the web process!' /workspace + worker bash echo 'this is the worker process!' /workspace ``` diff --git a/src/main.rs b/src/main.rs index 6cc381f..ccc8ae0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,9 +23,6 @@ use std::path::Path; #[cfg(test)] use libcnb_test as _; -#[cfg(test)] -use ureq as _; - struct ProcfileBuildpack; impl Buildpack for ProcfileBuildpack { @@ -97,21 +94,15 @@ mod tests { #[test] fn test_valid_detect() { - let tmp_dir = tempfile::tempdir().unwrap(); - let procfile = tmp_dir.path().join("Procfile"); - std::fs::write( - procfile, - "julie_andrews: supercalifragilisticexpialidocious", - ) - .unwrap(); - - assert!(dir_has_procfile(tmp_dir)); + let app_dir = + Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/web_and_worker_procfile"); + assert!(dir_has_procfile(app_dir)); } #[test] fn test_missing_procfile_detect() { - let tmp_dir = tempfile::tempdir().unwrap(); - assert!(!dir_has_procfile(tmp_dir)); + let app_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/missing_procfile"); + assert!(!dir_has_procfile(app_dir)); } #[test] diff --git a/tests/fixtures/app_with_procfile/Procfile b/tests/fixtures/app_with_procfile/Procfile deleted file mode 100644 index 1fa3a06..0000000 --- a/tests/fixtures/app_with_procfile/Procfile +++ /dev/null @@ -1,2 +0,0 @@ -web: socat -v -T0.05 tcp-l:8080,reuseaddr,fork system:"echo 'HTTP/1.1 200 OK'; echo 'Connection: close'; echo; cat" -worker: while true; do echo 'lol'; sleep 2; done diff --git a/tests/fixtures/app_with_empty_procfile/Procfile b/tests/fixtures/empty_procfile/Procfile similarity index 100% rename from tests/fixtures/app_with_empty_procfile/Procfile rename to tests/fixtures/empty_procfile/Procfile diff --git a/tests/fixtures/app_without_procfile/.gitkeep b/tests/fixtures/missing_procfile/.gitkeep similarity index 100% rename from tests/fixtures/app_without_procfile/.gitkeep rename to tests/fixtures/missing_procfile/.gitkeep diff --git a/tests/fixtures/multiple_non_web_procfile/Procfile b/tests/fixtures/multiple_non_web_procfile/Procfile new file mode 100644 index 0000000..890c80d --- /dev/null +++ b/tests/fixtures/multiple_non_web_procfile/Procfile @@ -0,0 +1,2 @@ +worker: echo 'this is the worker process!' +console: echo 'this is the console process!' diff --git a/tests/fixtures/not_yaml_procfile/Procfile b/tests/fixtures/not_yaml_procfile/Procfile new file mode 100644 index 0000000..f346d4a --- /dev/null +++ b/tests/fixtures/not_yaml_procfile/Procfile @@ -0,0 +1,7 @@ +# Whilst `Procfile`s seem like they could be parsed as though they were a YAML file, +# this is not the case - for example the below is a valid Procfile, but parsing as +# YAML would fail with something like +# `Error : incomplete explicit mapping pair` +# There is also some leading/trailing whitespace thrown in to confirm we handle that too. + + web: echo foo: bar diff --git a/tests/fixtures/web_and_worker_procfile/Procfile b/tests/fixtures/web_and_worker_procfile/Procfile new file mode 100644 index 0000000..ef08892 --- /dev/null +++ b/tests/fixtures/web_and_worker_procfile/Procfile @@ -0,0 +1,2 @@ +web: echo 'this is the web process!' +worker: echo 'this is the worker process!' diff --git a/tests/fixtures/worker_only_procfile/Procfile b/tests/fixtures/worker_only_procfile/Procfile new file mode 100644 index 0000000..1717807 --- /dev/null +++ b/tests/fixtures/worker_only_procfile/Procfile @@ -0,0 +1 @@ +worker: echo 'this is the worker process!' diff --git a/tests/integration_test.rs b/tests/integration_test.rs index a1fb702..c560354 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -6,47 +6,161 @@ // Enable Clippy lints that are disabled by default. #![warn(clippy::pedantic)] +use indoc::indoc; use libcnb_test::assert_contains; -use libcnb_test::{BuildpackReference, IntegrationTest}; -use std::io; -use std::thread; -use std::time::Duration; +use libcnb_test::IntegrationTest; #[test] -#[ignore] -fn test() { - IntegrationTest::new("heroku/builder:22", "tests/fixtures/app_with_procfile") - .buildpacks(vec![BuildpackReference::Crate]) - .run_test(|context| { - assert_contains!(context.pack_stdout, "[Discovering process types]"); +#[ignore = "integration test"] +fn test_web_and_worker_procfile() { + IntegrationTest::new( + "heroku/builder:22", + "tests/fixtures/web_and_worker_procfile", + ) + .run_test(|context| { + assert_contains!( + context.pack_stdout, + indoc! {" + [Discovering process types] + Procfile declares types -> web, worker + "} + ); + + // When there is a web process type, it should be made the default even if there + // are multiple process types declared. + assert_contains!(context.pack_stdout, "Setting default process type 'web'"); + context + .prepare_container() + .start_with_default_process(|container| { + let log_output = container.logs_wait(); + assert_eq!(log_output.stdout, "this is the web process!\n"); + }); + + context + .prepare_container() + .start_with_process(String::from("worker"), |container| { + let log_output = container.logs_wait(); + assert_eq!(log_output.stdout, "this is the worker process!\n"); + }); + }); +} + +#[test] +#[ignore = "integration test"] +fn test_worker_only_procfile() { + IntegrationTest::new("heroku/builder:22", "tests/fixtures/worker_only_procfile").run_test( + |context| { assert_contains!( context.pack_stdout, - "Procfile declares types -> web, worker" + indoc! {" + [Discovering process types] + Procfile declares types -> worker + "} ); - assert_contains!(context.pack_stdout, "Setting default process type 'web'"); + // When there is only one process type, it should be made the default process + // type even when it doesn't have the name "web". + assert_contains!(context.pack_stdout, "Setting default process type 'worker'"); + context + .prepare_container() + .start_with_default_process(|container| { + let log_output = container.logs_wait(); + assert_eq!(log_output.stdout, "this is the worker process!\n"); + }); + }, + ); +} + +#[test] +#[ignore = "integration test"] +fn test_multiple_non_web_procfile() { + IntegrationTest::new( + "heroku/builder:22", + "tests/fixtures/multiple_non_web_procfile", + ) + .run_test(|context| { + assert_contains!( + context.pack_stdout, + indoc! {" + [Discovering process types] + Procfile declares types -> worker, console + "} + ); + + // When there are multiple process types, and none of them has name "web", + // then none of them should be set as the default process type. + assert_contains!(context.pack_stdout, "no default process type"); + context + .prepare_container() + .start_with_default_process(|container| { + let log_output = container.logs_wait(); + assert_contains!( + log_output.stdout, + "when there is no default process a command is required" + ); + }); + + context + .prepare_container() + .start_with_process(String::from("worker"), |container| { + let log_output = container.logs_wait(); + assert_eq!(log_output.stdout, "this is the worker process!\n"); + }); + + context + .prepare_container() + .start_with_process(String::from("console"), |container| { + let log_output = container.logs_wait(); + assert_eq!(log_output.stdout, "this is the console process!\n"); + }); + }); +} + +#[test] +#[ignore = "integration test"] +// Tests a Procfile that happens to not be valid YAML, but is still valid according +// to the supported Procfile syntax. +fn test_not_yaml_procfile() { + IntegrationTest::new("heroku/builder:22", "tests/fixtures/not_yaml_procfile").run_test( + |context| { + assert_contains!( + context.pack_stdout, + indoc! {" + [Discovering process types] + Procfile declares types -> web + "} + ); + assert_contains!(context.pack_stdout, "Setting default process type 'web'"); context .prepare_container() - .expose_port(8080) .start_with_default_process(|container| { - thread::sleep(Duration::from_secs(1)); - let result = call_test_fixture_service( - container.address_for_port(8080).unwrap(), - "Aeluon", - ) - .unwrap(); - - assert_contains!(result, "payload=Aeluon"); + let log_output = container.logs_wait(); + assert_eq!(log_output.stdout, "foo: bar\n"); }); - }); + }, + ); } -fn call_test_fixture_service(addr: std::net::SocketAddr, payload: &str) -> io::Result<String> { - let req = ureq::get(&format!( - "http://{}:{}/?payload={}", - addr.ip(), - addr.port(), - payload - )); - req.call().unwrap().into_string() +#[test] +#[ignore = "integration test"] +fn test_empty_procfile() { + IntegrationTest::new("heroku/builder:22", "tests/fixtures/empty_procfile").run_test( + |context| { + assert_contains!( + context.pack_stdout, + indoc! {" + [Discovering process types] + Procfile declares types -> (none) + "} + ); + assert_contains!(context.pack_stdout, "no default process type"); + }, + ); +} + +#[test] +#[ignore = "integration test"] +#[should_panic(expected = "ERROR: No buildpack groups passed detection.")] +fn test_missing_procfile() { + IntegrationTest::new("heroku/builder:22", "tests/fixtures/missing_procfile").run_test(|_| {}); }