Home  >  Article  >  Backend Development  >  Golang test container with Azure Devops pipeline: Container killed randomly?

Golang test container with Azure Devops pipeline: Container killed randomly?

WBOY
WBOYforward
2024-02-05 21:54:071014browse

Golang 测试容器与 Azure Devops 管道:容器被随机杀死?

Question content

While implementing and running my database integration tests using golang testcontainers works perfectly locally, my tests appear to be in the azure devops pipeline Random doesn't work.

Pipeline log display:

2023/01/09 16:06:02 (...) error: read tcp 127.0.0.1:52546->127.0.0.1:49161: read: connection reset by peer

After adding container logging, improving the wait criteria, removing the use of the db container config file (so I don't have to copy the files into the container) and disabling ryuk, I'm wondering what else needs to be done or if my initialization of the container doesn't work correct.

For each unit test, the test container is started like this:

func setuptestdatabase(ctx context.context) (testcontainers.container, project.repository, error) {
    containerreq := testcontainers.containerrequest{
        skipreaper:   true,
        image:        "postgres:11.18-alpine3.17",
        exposedports: []string{"5432/tcp"},
        cmd:          []string{"postgres", "-c", "fsync=off"},
        env: map[string]string{
            "postgres_db":         "postgre",
            "postgres_password":   "postgres",
            "postgres_user":       "postgres",
            "pguser":              "postgres",
            "postgres_extensions": "uuid-ossp",
        },
    }

    containerreq.waitingfor = wait.forall(
        wait.forlisteningport("5432/tcp"),
        wait.forexec([]string{"pg_isready", "-t 10", "-q"}), // postgre docs: https://www.postgresql.org/docs/9.4/app-pg-isready.html
    ).withdeadline(3 * time.minute)

    dbcontainer, err := testcontainers.genericcontainer(
        ctx,
        testcontainers.genericcontainerrequest{
            containerrequest: containerreq,
            started:          true,
        })
    if err != nil {
        log.fatalf("database container could not be started. error: %s", err)
        return nil, nil, errors.withstack(err)
    }

    err = dbcontainer.startlogproducer(ctx)
    if err != nil {
        log.fatalf("logproducer could not be started. error: %s", err)
        return nil, nil, errors.withstack(err)
    }
    defer dbcontainer.stoplogproducer()
    lc := logconsumer{}
    dbcontainer.followoutput(&lc)

    port, err := dbcontainer.mappedport(ctx, "5432")
    if err != nil {
        log.fatalf("mapped port could not be retrieved. error: %s", err)
        return nil, nil, errors.withstack(err)
    }
    host, err := dbcontainer.host(ctx)
    if err != nil {
        log.fatalf("hostname could not be retrieved. error: %s", err)
        return nil, nil, errors.withstack(err)
    }

    global.config.postgres.host = host
    global.config.postgres.port = port.port()
    global.config.postgres.user = "postgres"
    global.config.postgres.password = "postgres"
    global.config.postgres.dbname = "postgre"
    global.config.local = true

    global.logger = logger.newnull(config.config{
        logging: config.logging{
            level: "debug",
        },
    })

    repository, err := new(ctx)
    if err != nil {
        log.fatalf("repository could not be setup. error: %s", err)
        return nil, nil, errors.withstack(err)
    }

    return dbcontainer, repository, nil
}

...Create the repository using repository, err := new(ctx) Finally use migrate to set up a database similar to our production database, and use gorm for database connection and processing, etc.

The basic template for unit testing is:

func Test_pg_Has(t *testing.T) {
    ctx := context.TODO()
    dbContainer, repository, err := SetupTestDatabase(ctx)
    if err != nil {
        t.Errorf("error running testcontainers, error: %s", err)
    }
    t.Cleanup(func() {
        if err := dbContainer.Terminate(ctx); err != nil {
            t.Fatalf("failed to terminate container: %s", err)
        }
        time.Sleep(10 * time.Second)
    })
    
    ... TEST_CODE
}

For azure pipeline, use the stock azure agent pool, go version is "1.18.0 x64".

Any tips would be greatly appreciated, thank you in advance.


Correct answer


As a less satisfactory solution, I added a 5 second sleep after creating the container but before setting up the database connection.

This may be an Azure DevOps specific issue as we are seeing unit tests failing randomly even when running within a single container.

Accepting this as a response is also a challenge for the community...

The above is the detailed content of Golang test container with Azure Devops pipeline: Container killed randomly?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete