web-dev-qa-db-fra.com

Comment puis-je détecter que mon test s'exécute sur un environnement Jenkins?

J'ai un test JUnit utilisant Assumption pour ignorer le test si l'ordinateur du développeur n'a pas le logiciel prérequis pour l'exécuter. En dépit d'être "junit", c'est un test d'intégration. Quelque chose comme ça:

int isSoftwarePresent = new ProcessBuilder("check software presence").start().waitFor();
Assume.assumeThat("Software not present", isSoftwarePresent, is(equalTo(0)));

Cependant, à un moment donné, j'ai réalisé que le test avait arrêté exécuté sur la construction automatisée de Jenkins, en raison de cette hypothèse, et finalement une régression a été introduite que le test était censé arrêter.

En d'autres termes, le logiciel requis a disparu de l'environnement esclave Jenkins, ce qui a fait sauter le test.

Le test automatisé est exécuté par maven avec le plug-in FailSafe, sur un plan de build Jenkins Pipeline. Comment puis-je détecter que mon environnement est Jenkins afin de rendre la condition d'hypothèse plus stricte?

Autrement dit, je veux que la condition soit quelque chose comme ceci:

boolean isJenkinsBuild = /* true if this is being run inside a Jenkins build, false otherwise */;
boolean isSoftwarePresent = new ProcessBuilder("check software presence").start().waitFor() == 0;
Assume.assumeTrue("Software not present", isSoftwarePresent || isJenkinsBuild);

Ou même,

@Test
void testJenkinsEnvironment() {
    ...
    Assume.assumeTrue(isJenkinsBuild);
    Assert.assertTrue(isSoftwarePresent);
}

@Test
void testFeature() {
    ...
    Assume.assumeTrue(isSoftwarePresent);
    ...
}
8
Daniel C. Sobral

Puisqu'ils sont faciles à tester et passés à chaque programme exécuté par la construction, j'ai choisi de baser la vérification sur les variables d'environnement.

Bien que la réponse rohit montre une façon de définir des variables sur Jenkinsfile, je préfère me fier aux choses que Jenkins fait lui-même, j'ai donc vérifié les variables d'environnement définies sur mes travaux Jenkins, et il existe de nombreuses options à choisir:

Informations générales sur Jenkins

Celles-ci semblent être constantes sur une instance Jenkins.

  • HUDSON_URL
  • JENKINS_URL

Pas spécifique à Jenkins, mais ce qui suit est également utile:

  • USER

Notre Jenkins fonctionne sous l'utilisateur jenkins, donc tester cette valeur est également une possibilité.

Information sur l'emploi

Ceux-ci ont des valeurs constantes à travers les builds pour le même travail.

  • JOB_URL
  • JOB_NAME
  • JOB_BASE_NAME
  • JOB_DISPLAY_URL

Construire des informations

Ceux-ci ont des valeurs constantes sur la même version (c'est-à-dire pour différentes invocations sh).

  • BUILD_URL
  • BUILD_TAG
  • RUN_CHANGES_DISPLAY
  • RUN_DISPLAY
  • BUILD_DISPLAY_NAME
  • BUILD_ID
  • BUILD_NUMBER

Informations sur le nœud

Ceux-ci sont liés au nœud sur lequel la commande en cours est exécutée.

  • JENKINS_HOME
  • JENKINS_NODE_COOKIE
  • NODE_LABELS
  • NODE_NAME

Spécial

Celui-ci change avec chaque build, peut changer d'un nœud à l'autre, et peut même changer avec la configuration de Jenkinsfile:

  • WORKSPACE

Divers

Je n'en suis pas sûr. Ils sont certainement de Jenkins, mais je ne sais pas quel est leur cycle de vie.

  • HUDSON_SERVER_COOKIE
  • JENKINS_SERVER_COOKIE
  • HUDSON_COOKIE

Considérations finales

Pour mes propres besoins, j'ai décidé d'aller avec JENKINS_HOME. Le nom est très spécifique à Jenkins, et il semble plus fondamental que, disons, JENKINS_URL. Bien que cela n'implique pas que la construction est exécutée par Jenkins, elle sera toujours définie dans ce cas. Cela ne me dérange pas les faux positifs, tant que je n'ai pas de faux négatifs.

15
Daniel C. Sobral

Vous pouvez y parvenir de deux manières:

  1. Vous pouvez faire en sorte que votre application accepte les arguments, puis passer une valeur TRUE/FALSE indiquant qu'elle s'exécute à partir de Jenkins ou non.

  2. Vous pouvez également lire les propriétés système d'os

par exemple. System.getProperty ("os.Arch");

Mais cela ne fonctionnera pas si votre environnement Jenkins et votre espace de travail sont sur la même machine

  1. Vous pouvez simplement définir une variable env dans votre pipeline (existe uniquement dans le pipeline) et dans l'application, vous pouvez lire cette valeur

Ainsi :

Pipeline- option1

     pipeline {
            environment {
                FROM_JENKINS= "TRUE" 
            } stage('test'){ 

                   sh "mvn test"
             }
        }

Pipeline - option2

     pipeline {
            stage('test'){ 

                    sh '''FROM_JENKINS="TRUE" // setting the env variable in the same Shell where you are running mvn
                        mvn test'''
             }
        }

Application

boolean isJenkinsBuild = Boolean.valueOf(System.getenv("FROM_JENKINS"));
boolean isSoftwarePresent = new ProcessBuilder("check software presence").start().waitFor() == 0;
Assume.assumeTrue("Software not present", isSoftwarePresent || isJenkinsBuild);

J'espère que ça aide :)

2
rohit thomas