Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-49339

Add ability to get test results for a given Maven execution

      The problem is that our Jenkins file is using parallel() and executes several maven builds (using withMaven).

      We then have some custom logic after each maven execution to analyze failing tests. The problem is that they accumulate in "currentBuild" and we cannot find the tests related to the maven execution that just happened.

      FYI the way we retrieve failing tests is:

      AbstractTestResultAction testResultAction = currentBuild.rawBuild.getAction(AbstractTestResultAction.class)
      def failedTests = testResultAction.getResult().getFailedTests()
      

      See also https://groups.google.com/forum/?nomobile=true#!topic/jenkinsci-users/dDDPC486JWE

      I've tried to put some logic to save failing tests before and after each maven execution but it cannot work because of "parallel" (all maven executions starting in parallel save an empty state of failing tests and as soon as one of them gets a failing test, they'll all report it failing and send duplicate emails):

      So right now we're stuck and missing a way to get the test result for a single maven execution.

      Thanks

          [JENKINS-49339] Add ability to get test results for a given Maven execution

          Olivier Lamy added a comment -

          I have similar issue.

          The Jenkinsfile is running the same maven project in parallel with jdk8 and jdk9.

          So the results are confusing and no easy way to understand which test has failed with which jdk.

          Could we have more than one TestResultAction per build?

          Ideally I would like to add a label to it.

          ```
          step([$class: 'JUnitResultArchiver', label: somelabel here,
          testResults: '*/target/surefire-reports/TEST-.xml'])
          ```
          WDYT?

          Olivier Lamy added a comment - I have similar issue. The Jenkinsfile is running the same maven project in parallel with jdk8 and jdk9. So the results are confusing and no easy way to understand which test has failed with which jdk. Could we have more than one TestResultAction per build? Ideally I would like to add a label to it. ``` step([$class: 'JUnitResultArchiver', label: somelabel here, testResults: '* /target/surefire-reports/TEST- .xml']) ``` WDYT?

          Olivier Lamy added a comment -

          Hi,
          Are you happy with such proposal? I can help with a PR.
          I'm not a cloudbees employee but I can help if you're happy to accept contributions?

          Olivier Lamy added a comment - Hi, Are you happy with such proposal? I can help with a PR. I'm not a cloudbees employee but I can help if you're happy to accept contributions?

          olamy Could you explain how we would get the test results?

          As I mentioned above this is what I'm doing now:

          AbstractTestResultAction testResultAction = currentBuild.rawBuild.getAction(AbstractTestResultAction.class)
          def failedTests = testResultAction.getResult().getFailedTests()
          

          What would be the new way for getting the TestResult/CaseResult objects associated to a single withMaven execution?

          Thanks!

          Vincent Massol added a comment - olamy Could you explain how we would get the test results? As I mentioned above this is what I'm doing now: AbstractTestResultAction testResultAction = currentBuild.rawBuild.getAction(AbstractTestResultAction.class) def failedTests = testResultAction.getResult().getFailedTests() What would be the new way for getting the TestResult/CaseResult objects associated to a single withMaven execution? Thanks!

          Olivier Lamy added a comment -

          vmassol we definitely need to keep backward comp here. An idea could be to introduce the label (jdk/os/etc..) at the SuiteResult class level.

          Olivier Lamy added a comment - vmassol we definitely need to keep backward comp here. An idea could be to introduce the label (jdk/os/etc..) at the SuiteResult class level.

          cleclerc alobato WDYT about it ?

          Arnaud Héritier added a comment - cleclerc alobato WDYT about it ?

          Wouldn't this problem be fixed by JENKINS-41710 ?

          Cyrille Le Clerc added a comment - Wouldn't this problem be fixed by JENKINS-41710 ?

          Olivier Lamy added a comment -

          I wish but is it fixed as described? I'm not sure when looking at the code here https://github.com/jenkinsci/junit-plugin/blob/master/src/main/java/hudson/tasks/junit/pipeline/JUnitResultsStep.java or JUnitResultArchiver class.

          Olivier Lamy added a comment - I wish but is it fixed as described? I'm not sure when looking at the code here https://github.com/jenkinsci/junit-plugin/blob/master/src/main/java/hudson/tasks/junit/pipeline/JUnitResultsStep.java or JUnitResultArchiver class.

          Vincent Massol added a comment - - edited

          cleclerc Thanks for the hint with JENKINS-41710. It took me a while to read all the context of this issue and this lead me to find TestResult#getResultInRun(Run).

          I've modified the XWiki pipeline code to find the failing tests from a withMaven execution like this:

          /**
           * @return the failing tests for the current build
           */
          def getFailingTests()
          {
              def failingTests
              AbstractTestResultAction testResultAction = currentBuild.rawBuild.getAction(AbstractTestResultAction.class)
              if (testResultAction != null) {
                  failingTests = testResultAction.getResult().getResultInRun(currentBuild.rawBuild).getFailedTests()
              } else {
                  // No tests were run in this build, nothing left to do.
                  failingTests = []
              }
              return failingTests
          }
          

          I've yet to verify if it works fine (i.e. no more side effects from parallel runs). However I've noticed another problem which feels weird. In the XWiki pipeline we look for failing tests and look for screenshots taken by our selenium tests and attach the screenshot to the Jenkins job page:

          This is what we call (full code at https://github.com/xwiki/xwiki-jenkins-pipeline/blob/3a38a609126e5e2007754d9937871a100b029a9b/vars/xwikiBuild.groovy#L467):

          def failingTests = getFailingTests() // the method above
          ...
          for (def failedTest : failingTests) {
            def moduleFile = failedTest.getSuiteResult().getFile().getParent().getParent()
          ...
          

          The problem is that in some cases the moduleFile for the failing test points to the wrong maven module.

          For example in a job I got:

          21:34:45.868 [main] INFO  org.xwiki.test.ui.TestDebugger - Screenshot for failing test [NotificationsIT-testNotificationDisplayerClass] saved at [/home/hudsonagent/jenkins_root/workspace/XWiki_xwiki-platform_master/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-test/xwiki-platform-notifications-test-tests/target/screenshots/NotificationsIT-testNotificationDisplayerClass.png].
          

          This means the failing test was in module xwiki-platform-notifications-test-tests.

          But getSuiteResult().getFile().getParent().getParent() returned /home/hudsonagent/jenkins_root/workspace/XWiki_xwiki-platform_master/xwiki-platform-core/xwiki-platform-activeinstalls/xwiki-platform-activeinstalls-test/xwiki-platform-activeinstalls-test-tests/target, i.e. the xwiki-platform-activeinstalls-test-tests maven module.

          Any idea or direction I could check for why the failing test class (CaseResult) would give me a completely wrong file path for the surefire XML report file?

          Thanks a lot

          Vincent Massol added a comment - - edited cleclerc Thanks for the hint with JENKINS-41710 . It took me a while to read all the context of this issue and this lead me to find TestResult#getResultInRun(Run) . I've modified the XWiki pipeline code to find the failing tests from a withMaven execution like this: /** * @ return the failing tests for the current build */ def getFailingTests() { def failingTests AbstractTestResultAction testResultAction = currentBuild.rawBuild.getAction(AbstractTestResultAction.class) if (testResultAction != null ) { failingTests = testResultAction.getResult().getResultInRun(currentBuild.rawBuild).getFailedTests() } else { // No tests were run in this build, nothing left to do . failingTests = [] } return failingTests } I've yet to verify if it works fine (i.e. no more side effects from parallel runs). However I've noticed another problem which feels weird. In the XWiki pipeline we look for failing tests and look for screenshots taken by our selenium tests and attach the screenshot to the Jenkins job page: This is what we call (full code at https://github.com/xwiki/xwiki-jenkins-pipeline/blob/3a38a609126e5e2007754d9937871a100b029a9b/vars/xwikiBuild.groovy#L467): def failingTests = getFailingTests() // the method above ... for (def failedTest : failingTests) { def moduleFile = failedTest.getSuiteResult().getFile().getParent().getParent() ... The problem is that in some cases the moduleFile for the failing test points to the wrong maven module. For example in a job I got: 21:34:45.868 [main] INFO org.xwiki.test.ui.TestDebugger - Screenshot for failing test [NotificationsIT-testNotificationDisplayerClass] saved at [/home/hudsonagent/jenkins_root/workspace/XWiki_xwiki-platform_master/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-test/xwiki-platform-notifications-test-tests/target/screenshots/NotificationsIT-testNotificationDisplayerClass.png]. This means the failing test was in module xwiki-platform-notifications-test-tests . But getSuiteResult().getFile().getParent().getParent()  returned /home/hudsonagent/jenkins_root/workspace/XWiki_xwiki-platform_master/xwiki-platform-core/xwiki-platform-activeinstalls/xwiki-platform-activeinstalls-test/xwiki-platform-activeinstalls-test-tests/target , i.e. the xwiki-platform-activeinstalls-test-tests maven module. Any idea or direction I could check for why the failing test class ( CaseResult ) would give me a completely wrong file path for the surefire XML report file? Thanks a lot

          So I can now confirm that "getResultInRun()" is not helping and is returning all results from the job (i.e. accumulated) and not from the test results from the last withMaven step.

          In the attached screenshot we can see:

          • We have several maven builds executing in parallel in the same job. Each maven build executes only a single test.
          • Yet the failing lists in the screenshots list all failing tests so far, from all maven executions and not just from the current maven run.

          I'd love to know how to get the tests results only from the current maven execution that just finished.

          Thanks

          Vincent Massol added a comment - So I can now confirm that "getResultInRun()" is not helping and is returning all results from the job (i.e. accumulated) and not from the test results from the last withMaven step. In the attached screenshot we can see: We have several maven builds executing in parallel in the same job. Each maven build executes only a single test. Yet the failing lists in the screenshots list all failing tests so far, from all maven executions and not just from the current maven run. I'd love to know how to get the tests results only from the current maven execution that just finished. Thanks

            Unassigned Unassigned
            vmassol Vincent Massol
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: