LukeMathWalker / zero-to-production

Code for "Zero To Production In Rust", a book on API development using Rust.
https://www.zero2prod.com
Apache License 2.0
5.43k stars 470 forks source link

Chapter 3: Updating CI Pipeline #214

Closed DennisTheMenace780 closed 9 months ago

DennisTheMenace780 commented 1 year ago

At the start of the book I opted to go with CircleCI for my CI pipeline, but as I have worked through Chapter 3 I have noticed that Github Actions are the only supported CI pipeline here. I have been able to kind of get a configuration file set up, but my tests are failing in CI

You'll see below that I am ending up with a database connection problem.

#!/bin/bash -eo pipefail
docker run --security-opt seccomp=unconfined -v "${PWD}:/volume" xd009642/tarpaulin cargo tarpaulin --ignore-tests
Unable to find image 'xd009642/tarpaulin:latest' locally
latest: Pulling from xd009642/tarpaulin

737482dd: Pulling fs layer 
592d62aa: Pulling fs layer 
6935197e: Pulling fs layer 
026c6457: Pulling fs layer 
136223c1: Pulling fs layer 
4330ee83: Pulling fs layer 
Digest: sha256:a102d220216aee254b97fd6be5e5000a82ec26aa9c744f9c46f5860abc22f1ab
Status: Downloaded newer image for xd009642/tarpaulin:latest
Jun 05 22:46:49.303  INFO cargo_tarpaulin::config: Creating config
Jun 05 22:48:06.969  INFO cargo_tarpaulin: Running Tarpaulin
Jun 05 22:48:06.969  INFO cargo_tarpaulin: Building project
Jun 05 22:48:06.969  INFO cargo_tarpaulin::cargo: Cleaning project
warning: unused manifest key: target.aarch64-apple-darwin.rustflags
   Compiling libc v0.2.144
   Compiling cfg-if v1.0.0
   ... COMPILATION 
   ... STEPS LEFT
   ... OUT 
   Compiling newsletter v0.1.0 (/volume)
error: Broken pipe (os error 32)
warning: build failed, waiting for other jobs to finish...
error: could not compile `newsletter` due to 2 previous errors
Jun 05 22:49:33.241 ERROR cargo_tarpaulin: Failed to compile tests!
error: error communicating with database: Cannot assign requested address (os error 99)
  --> tests/test_health_check.rs:47:17
   |
47 |     let saved = sqlx::query!("SELECT email, name from subscriptions")
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query` (in Nightly builds, run with -Z macro-backtrace for more info)

The corresponding test is listed here:

#[tokio::test]
async fn subscribe_returns_200_for_valid_form_submission() {
    // Arrange
    let address = spawn_app();
    let configuration = get_configuration().expect("Failed to read configuration");
    let connection_string = configuration.database.connection_string();
    let mut connection = PgConnection::connect(&connection_string)
        .await
        .expect("Failed to connect to Postgres.");
    let client = reqwest::Client::new();
    let encoded_body = "name=le%20guin&email=ursula_le_guin%40gmail.com";

    // Act
    let response = client
        .post(&format!("{}/subscriptions", &address))
        .header("Content-Type", "application/x-www-form-urlencoded")
        .body(encoded_body)
        .send()
        .await
        .expect("Failed to execute request.");

    // Assert
    assert_eq!(200, response.status().as_u16());

    let saved = sqlx::query!("SELECT email, name from subscriptions")
        .fetch_one(&mut connection)
        .await
        .expect("Failed to fetch saved subscription");

    assert_eq!(saved.email, "ursula_le_guin@gmail.com");
    assert_eq!(saved.name, "le guin");
}

I'm curious if the reason that the test is failing in CI is because i'm not actually filling the database with the data, so query!() is unable to make the request.

Any thoughts on what could be happening here?

DennisTheMenace780 commented 1 year ago

Note that I have also tried with the Github Actions flow, but i'm still unable to connect:

running 3 tests
test health_check ... ok
test return_400_for_invalid_form_submission ... ok
test subscribe_returns_200_for_valid_form_submission ... FAILED

failures:

---- subscribe_returns_200_for_valid_form_submission stdout ----
thread 'subscribe_returns_200_for_valid_form_submission' panicked at 'Failed to connect to Postgres.: Database(PgDatabaseError { severity: Fatal, code: "28P01", message: "password authentication failed for user \"postgres\"", detail: None, hint: None, position: None, where: None, schema: None, table: None, column: None, data_type: None, constraint: None, file: Some("auth.c"), line: Some(335), routine: Some("auth_failed") })', tests/test_health_check.rs:31:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
LukeMathWalker commented 1 year ago

Can you share a link to your project, including the CI files?

DennisTheMenace780 commented 1 year ago

After running around in circles for a while I decided to just adopt the Github Actions workflow from Chapter 3 so that I could move forward. Once I have some time this week i'll upload the CircleCI config again and ping you.

One of the big challenges I faced with CircleCI is that I couldn't figure out how to do port mapping. For my project I use port 5069 and map it to 5432 in the Postgres docker container. I have an active Postgres DB already running locally on 5432 so I needed to forward the traffic so that I could also run tests locally against the correct Postgres Container.

I found that with the GH Actions configuration I was able to do that quite easily given how it was made explicit in the file.