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(|_| {});
 }