Maison  >  Article  >  développement back-end  >  Conteneur de test Golang avec pipeline Azure Devops : conteneur tué au hasard ?

Conteneur de test Golang avec pipeline Azure Devops : conteneur tué au hasard ?

WBOY
WBOYavant
2024-02-05 21:54:07974parcourir

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

Contenu de la question

Bien que l'implémentation et l'exécution de mes tests d'intégration de base de données à l'aide de golang testcontainers fonctionnent parfaitement localement, mes tests semblent ne pas fonctionner par hasard dans le pipeline Azure Devops.

Le journal du pipeline indique :

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

Après avoir ajouté la journalisation du conteneur, amélioré les critères d'attente, supprimé l'utilisation du fichier de configuration du conteneur db (pour ne pas avoir à copier les fichiers dans le conteneur) et désactivé ryuk, je me demande ce qu'il faut faire d'autre, ou si je n'initialise pas correctement le conteneur.

Pour chaque test unitaire, le conteneur de test démarre comme ceci :

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
}

...utilisez repository 创建存储库,err := new(ctx) et enfin migrez pour configurer une base de données similaire à notre base de données de production et utilisez gorm pour les connexions et le traitement de la base de données, etc.

Le modèle de base pour les tests unitaires est :

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
}

Pour le pipeline Azure, utilisez le pool d'agents Azure d'origine, la version Go est "1.18.0 x64".

Tout conseil serait grandement apprécié, merci d'avance.


Bonne réponse


Comme solution peu satisfaisante, j'ai ajouté un sommeil de 5 secondes après la création du conteneur mais avant de configurer la connexion à la base de données.

Il peut s'agir d'un problème spécifique à Azure DevOps, car nous constatons que des tests unitaires échouent de manière aléatoire, même lorsqu'ils sont exécutés dans un seul conteneur.

Accepter cela comme réponse est aussi un défi pour la communauté...

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer