5

I'm having trouble running my automated tests with GitHub actions. I can't figure out why I can't connect with the MongoDB service running my integration tests. I tried different hosts: localhost, 127.0.0.1, 0.0.0.0, but none of them can connect with the database.

It works perfectly fine in my docker setup, but for some reason not with GitHub actions.

    name: CI master
    
    on: [push, pull_request]
    
    env:
      RUST_BACKTRACE: 1
      CARGO_TERM_COLOR: always
      APP_ENV: development
      APP_MONGO_USER: test
      APP_MONGO_PASS: password
      APP_MONGO_DB: test
    
    jobs:
      # Run tests
      test:
        name: Test
        runs-on: ubuntu-latest
        services:
          mongo:
            image: mongo
            env:
              MONGO_INITDB_ROOT_USERNAME: ${APP_MONGO_USER}
              MONGO_INITDB_ROOT_PASSWORD: ${APP_MONGO_PASS}
              MONGO_INITDB_DATABASE: ${APP_MONGO_DB}
            ports:
              - 27017:27017
        steps:
          - uses: actions/checkout@v2
          - uses: actions-rs/toolchain@v1
            with:
              profile: minimal
              toolchain: stable
              override: true
          - uses: actions-rs/cargo@v1
            with:
              command: test

Config file (development.toml).

[application]
host = "127.0.0.1"
port = 8080

Connecting to the database. The environment variables and config file get merged and I'm accessing them here through config: &Settings.

pub async fn init(config: &Settings) -> Result<Database> {
    let client_options = ClientOptions::parse(
        format!(
            "mongodb://{}:{}@{}:27017",
            config.mongo.user, config.mongo.pass, config.application.host
        )
        .as_str(),
    )
    .await?;

    let client = Client::with_options(client_options)?;
    let database = client.database("test"); // TODO: replace with env var

    database.run_command(doc! {"ping": 1}, None).await?;
    println!("Connected successfully.");

    Ok(database)
}

Calling the init function.

// Mongo
let mongo = mongo::init(&config).await.expect("Failed to init mongo");

The error I get.

thread 'health_check' panicked at 'Failed to init mongo: Error { kind: ServerSelectionError { message: "Server selection timeout: No available servers. Topology: { Type: Unknown, Servers: [ { Address: 127.0.0.1:27017, Type: Unknown, Error: Connection refused (os error 111) }, ] }" }, labels: [] }', tests/health_check.rs:31:44
E_net4
  • 27,810
  • 13
  • 101
  • 139
owebiletelma
  • 171
  • 3
  • 7
  • seems similar problem: https://stackoverflow.com/questions/57915791/how-to-connect-to-postgres-in-githhub-actions – Sunil Kumar Feb 22 '21 at 14:15
  • Use `ps` or similar to verify you have a server running. – D. SM Feb 22 '21 at 16:50
  • @D.SM Should you be able see the services in a separate container? When I add `- run: docker ps` I only see the ubuntu containers. – owebiletelma Feb 22 '21 at 17:38
  • Your question has no indication that you verified that the server is running. Before troubleshooting the client side, verify you have a server at all. – D. SM Feb 23 '21 at 05:33
  • @D.SM Well that's what I was asking how can I verify that the MongoDB service is running? Docker ps only shows the VM container Ubuntu. – owebiletelma Feb 23 '21 at 08:31
  • Run ps in the host system or run it in the container. How would you do this locally? – D. SM Feb 23 '21 at 17:56

2 Answers2

12

I eventually solved it by adding a health check to my service. Seems that my issue had something to do with my database not being up yet before running the tests.

services:
          mongodb:
              image: mongo
              env:
                MONGO_INITDB_ROOT_USERNAME: test
                MONGO_INITDB_ROOT_PASSWORD: password
                MONGO_INITDB_DATABASE: test
              options: >-
                --health-cmd mongo
                --health-interval 10s
                --health-timeout 5s
                --health-retries 5
              ports:
                - 27017:27017
owebiletelma
  • 171
  • 3
  • 7
0

Add a health check to the service that uses mongosh to check if it's possible to ping the database.

    services:
      mongo:
        image: mongo
        env:
          MONGO_INITDB_ROOT_USERNAME: username
          MONGO_INITDB_ROOT_PASSWORD: password
        options: >-
          --health-cmd "echo 'db.runCommand("ping").ok' | mongosh --quiet"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
          --name mongo_container