diff --git a/src/main/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/actions/ProvideReportLogsAction.groovy b/src/main/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/actions/ProvideLogsAction.groovy similarity index 83% rename from src/main/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/actions/ProvideReportLogsAction.groovy rename to src/main/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/actions/ProvideLogsAction.groovy index 1f2a3108..87ec7106 100644 --- a/src/main/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/actions/ProvideReportLogsAction.groovy +++ b/src/main/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/actions/ProvideLogsAction.groovy @@ -4,10 +4,10 @@ import hudson.FilePath import hudson.model.Run import jenkins.model.RunAction2 -class ProvideReportLogsAction implements RunAction2 { +class ProvideLogsAction implements RunAction2 { private transient Run run - ProvideReportLogsAction(Run run) { + ProvideLogsAction(Run run) { this.run = run } @@ -41,7 +41,7 @@ class ProvideReportLogsAction implements RunAction2 { return run } - List getReportLogs() { + List getLogs() { return run?.artifacts ?: [] } } diff --git a/src/main/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideReportLogsStep.groovy b/src/main/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideLogsStep.groovy similarity index 82% rename from src/main/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideReportLogsStep.groovy rename to src/main/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideLogsStep.groovy index 9efc9d66..27bd0694 100644 --- a/src/main/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideReportLogsStep.groovy +++ b/src/main/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideLogsStep.groovy @@ -9,7 +9,7 @@ package de.tracetronic.jenkins.plugins.ecutestexecution.steps import com.google.common.collect.ImmutableSet import de.tracetronic.jenkins.plugins.ecutestexecution.clients.RestApiClient import de.tracetronic.jenkins.plugins.ecutestexecution.clients.RestApiClientFactory -import de.tracetronic.jenkins.plugins.ecutestexecution.actions.ProvideReportLogsAction +import de.tracetronic.jenkins.plugins.ecutestexecution.actions.ProvideLogsAction import de.tracetronic.jenkins.plugins.ecutestexecution.clients.model.ApiException import de.tracetronic.jenkins.plugins.ecutestexecution.clients.model.ReportInfo import de.tracetronic.jenkins.plugins.ecutestexecution.util.PathUtil @@ -21,9 +21,7 @@ import hudson.Launcher import hudson.model.Run import hudson.model.TaskListener import hudson.util.ListBoxModel -import jenkins.model.Jenkins import jenkins.security.MasterToSlaveCallable -import org.apache.commons.lang.StringUtils import org.jenkinsci.plugins.workflow.steps.Step import org.jenkinsci.plugins.workflow.steps.StepContext import org.jenkinsci.plugins.workflow.steps.StepDescriptor @@ -31,14 +29,13 @@ import org.jenkinsci.plugins.workflow.steps.StepExecution import org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution import org.kohsuke.stapler.DataBoundConstructor -import java.text.SimpleDateFormat import java.util.zip.ZipEntry import java.util.zip.ZipInputStream -class ProvideReportLogsStep extends Step { +class ProvideLogsStep extends Step { @DataBoundConstructor - ProvideReportLogsStep() { + ProvideLogsStep() { super() } @@ -47,17 +44,13 @@ class ProvideReportLogsStep extends Step { return new Execution(this, context) } - private static List removeEmptyReportIds(List reportIds) { - return reportIds.findAll { id -> StringUtils.isNotBlank(id) } - } - static class Execution extends SynchronousNonBlockingStepExecution { private static final long serialVersionUID = 1L - private final transient ProvideReportLogsStep step + private final transient ProvideLogsStep step - Execution(ProvideReportLogsStep step, StepContext context) { + Execution(ProvideLogsStep step, StepContext context) { super(context) this.step = step } @@ -83,17 +76,16 @@ class ProvideReportLogsStep extends Step { def logDirPath = PathUtil.makeAbsoluteInPipelineHome("${logDirName}", context) // Download report logs to workspace - List logFiles = [] try { - logFiles = launcher.getChannel().call( + launcher.getChannel().call( new ExecutionCallable(startTimeMillis, envVars, logDirPath, listener) ) } catch (Exception e) { throw e } - if (workspace.child(logDirName).list().size() > 0 && logFiles) { - FilePath[] reportLogs = workspace.list("${logDirName}/*.log") + if (workspace.child(logDirName).list().size() > 0) { + FilePath[] reportLogs = workspace.list("${logDirName}/**/*.log") def artifactsMap = new HashMap() reportLogs.each { log -> def relativePath = log.getRemote().substring(workspace.getRemote().length() + 1) @@ -101,7 +93,7 @@ class ProvideReportLogsStep extends Step { } listener.logger.println("Adding report logs to artifacts") run.artifactManager.archive(workspace, launcher, listener, artifactsMap) - run.addAction(new ProvideReportLogsAction(run)) + run.addAction(new ProvideLogsAction(run)) } listener.logger.println("Cleaning report folder in jenkins workspace") @@ -114,7 +106,6 @@ class ProvideReportLogsStep extends Step { private static final long serialVersionUID = 1L - private List reportIds private final long startTimeMillis private final EnvVars envVars private final String logDirPath @@ -131,12 +122,12 @@ class ProvideReportLogsStep extends Step { /** * Calls downloadReportFolder via the RestApiClient for all report ids. * Then extracts and saves the ecu.test log out of the returned zip folder. - * Logs a warning if no reportIds were returned by ecu.test. + * Logs a warning if no reports were returned by ecu.test. * @return List of strings containing the paths of the logs. */ @Override List call() throws IOException { - listener.logger.println("Providing ecu.test report logs to jenkins.") + listener.logger.println("Providing ecu.test logs to jenkins.") List logs = [] RestApiClient apiClient = RestApiClientFactory.getRestApiClient(envVars.get('ET_API_HOSTNAME'), envVars.get('ET_API_PORT')) List reports = apiClient.getAllReports() @@ -144,18 +135,17 @@ class ProvideReportLogsStep extends Step { if (reports == null || reports.isEmpty()) { listener.logger.println("[WARNING] No report files returned by ecu.test") } - reports*.reportDir.each { String reportDir -> + for (def report : reports) { + String reportDir = report.reportDir.split('/').last() if (!checkReportFolderCreationDate(reportDir)) { - listener.logger.println("[WARNING] ecu.test report folder includes files older than this run. ${reportDir}") + listener.logger.println("[WARNING] ecu.test report folder includes files older than this run. ${report.reportDir}") } - } - reports*.testReportId.each { String reportId -> - listener.logger.println("Downloading reportFolder for ${reportId}") + listener.logger.println("Downloading reportFolder for ${report.testReportId}") try { - File reportFolderZip = apiClient.downloadReportFolder(reportId) - File log = extractLogFileFromZip(reportFolderZip, "test/ecu.test_out.log", reportId) - logs.add(log.name) + File reportFolderZip = apiClient.downloadReportFolder(report.testReportId) + extractLogFileFromZip(reportFolderZip, "test/ecu.test_out.log", "${logDirPath}/${reportDir}/${reportDir}_test_out.log") + extractLogFileFromZip(reportFolderZip, "test/ecu.test_err.log", "${logDirPath}/${reportDir}/${reportDir}_test_err.log") } catch (ApiException e) { if (e instanceof de.tracetronic.cxs.generated.et.client.v2.ApiException && e.code == 404) { @@ -184,13 +174,12 @@ class ProvideReportLogsStep extends Step { } } - File extractLogFileFromZip(File reportFolderZip, String fileNameToExtract, String newName) { + File extractLogFileFromZip(File reportFolderZip, String fileNameToExtract, String saveToPath) { ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(reportFolderZip)) ZipEntry entry while ((entry = zipInputStream.nextEntry) != null) { - newName if (entry.name == fileNameToExtract) { - File outputFile = new File("${logDirPath}/${newName}.log") + File outputFile = new File(saveToPath) outputFile.parentFile.mkdirs() def outputStream = new FileOutputStream(outputFile) @@ -199,12 +188,11 @@ class ProvideReportLogsStep extends Step { } finally { outputStream.close() } - listener.logger.println("Extracted ${fileNameToExtract} to ${logDirPath}") zipInputStream.close() return outputFile } } - throw new Exception("No ecu.test log not found in given report zip!") + throw new Exception("No ecu.test logs not found in given report zip!") } } @@ -223,12 +211,12 @@ class ProvideReportLogsStep extends Step { @Override String getFunctionName() { - 'ttProvideReportLogs' + 'ttProvideLogs' } @Override String getDisplayName() { - '[TT] Provide ecu.test report logs in jenkins.' + '[TT] Provide ecu.test logs in jenkins.' } @Override diff --git a/src/main/resources/de/tracetronic/jenkins/plugins/ecutestexecution/actions/ProvideReportLogsAction/index.jelly b/src/main/resources/de/tracetronic/jenkins/plugins/ecutestexecution/actions/ProvideLogsAction/index.jelly similarity index 91% rename from src/main/resources/de/tracetronic/jenkins/plugins/ecutestexecution/actions/ProvideReportLogsAction/index.jelly rename to src/main/resources/de/tracetronic/jenkins/plugins/ecutestexecution/actions/ProvideLogsAction/index.jelly index 2812034e..446428a4 100644 --- a/src/main/resources/de/tracetronic/jenkins/plugins/ecutestexecution/actions/ProvideReportLogsAction/index.jelly +++ b/src/main/resources/de/tracetronic/jenkins/plugins/ecutestexecution/actions/ProvideLogsAction/index.jelly @@ -6,7 +6,7 @@

${it.displayName}

    - +
  • ${log.fileName} diff --git a/src/main/resources/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideReportLogsStep/config.jelly b/src/main/resources/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideLogsStep/config.jelly similarity index 100% rename from src/main/resources/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideReportLogsStep/config.jelly rename to src/main/resources/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideLogsStep/config.jelly diff --git a/src/main/resources/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideReportLogsStep/config.properties b/src/main/resources/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideLogsStep/config.properties similarity index 100% rename from src/main/resources/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideReportLogsStep/config.properties rename to src/main/resources/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideLogsStep/config.properties diff --git a/src/test/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/ETV1ContainerTest.groovy b/src/test/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/ETV1ContainerTest.groovy index a9ff46bc..3e571100 100644 --- a/src/test/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/ETV1ContainerTest.groovy +++ b/src/test/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/ETV1ContainerTest.groovy @@ -39,7 +39,7 @@ class ETV1ContainerTest extends ETContainerTest { .waitingFor(Wait.forHttp("/api/v1/live")) } - def "Perform provide report logs step with reports"() { + def "Perform provide logs step with reports"() { given: "a test execution pipeline" String script = """ node { @@ -55,7 +55,7 @@ class ETV1ContainerTest extends ETContainerTest { WorkflowRun run = jenkins.buildAndAssertStatus(Result.FAILURE, job) then: "expect successful test completion" - jenkins.assertLogContains("Providing ecu.test report logs to jenkins.", run) - jenkins.assertLogContains("Adding report logs to artifacts", run) + jenkins.assertLogContains("Providing ecu.test logs to jenkins.", run) + jenkins.assertLogContains("Downloading report folders is not supported by api v1. Use ecu.test > 2024.2 with api v2 instead.", run) } } diff --git a/src/test/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/ETV2ContainerTest.groovy b/src/test/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/ETV2ContainerTest.groovy index 6568dbff..fe4311da 100644 --- a/src/test/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/ETV2ContainerTest.groovy +++ b/src/test/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/ETV2ContainerTest.groovy @@ -39,12 +39,12 @@ class ETV2ContainerTest extends ETContainerTest { .waitingFor(Wait.forHttp("/api/v2/live")) } - def "Perform provide report logs step with no reports"() { + def "Perform provide logs step with no reports"() { given: "a test execution pipeline" String script = """ node { withEnv(['ET_API_HOSTNAME=${etContainer.host}', 'ET_API_PORT=${etContainer.getMappedPort(ET_PORT)}']) { - ttProvideReportLogs() + ttProvideLogs() } } """.stripIndent() @@ -54,17 +54,17 @@ class ETV2ContainerTest extends ETContainerTest { WorkflowRun run = jenkins.buildAndAssertStatus(Result.SUCCESS, job) then: "expect successful test completion" - jenkins.assertLogContains("Providing ecu.test report logs to jenkins.", run) + jenkins.assertLogContains("Providing ecu.test logs to jenkins.", run) jenkins.assertLogContains("[WARNING] No report files returned by ecu.test", run) } - def "Perform provide report logs step with reports"() { + def "Perform provide logs step with reports"() { given: "a test execution pipeline" String script = """ node { withEnv(['ET_API_HOSTNAME=${etContainer.host}', 'ET_API_PORT=${etContainer.getMappedPort(ET_PORT)}']) { ttRunPackage testCasePath: 'test.pkg' - ttProvideReportLogs() + ttProvideLogs() } } """.stripIndent() @@ -74,7 +74,7 @@ class ETV2ContainerTest extends ETContainerTest { WorkflowRun run = jenkins.buildAndAssertStatus(Result.SUCCESS, job) then: "expect successful test completion" - jenkins.assertLogContains("Providing ecu.test report logs to jenkins.", run) - jenkins.assertLogContains("Adding report logs to artifacts", run) + jenkins.assertLogContains("Providing ecu.test logs to jenkins.", run) + jenkins.assertLogContains("Adding logs to artifacts", run) } } diff --git a/src/test/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideReportLogStepIT.groovy b/src/test/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideLogStepIT.groovy similarity index 80% rename from src/test/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideReportLogStepIT.groovy rename to src/test/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideLogStepIT.groovy index b1bbb6a0..07f359e5 100644 --- a/src/test/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideReportLogStepIT.groovy +++ b/src/test/groovy/de/tracetronic/jenkins/plugins/ecutestexecution/steps/ProvideLogStepIT.groovy @@ -11,7 +11,7 @@ import org.jenkinsci.plugins.workflow.job.WorkflowRun import org.jenkinsci.plugins.workflow.steps.StepConfigTester import org.jvnet.hudson.test.JenkinsRule -class ProvideReportLogStepIT extends IntegrationTestBase { +class ProvideLogStepIT extends IntegrationTestBase { def setup() { ETInstallation.DescriptorImpl etDescriptor = jenkins.jenkins .getDescriptorByType(ETInstallation.DescriptorImpl.class) @@ -21,9 +21,9 @@ class ProvideReportLogStepIT extends IntegrationTestBase { def 'Default config round trip'() { given: - ProvideReportLogsStep before = new ProvideReportLogsStep() + ProvideLogsStep before = new ProvideLogsStep() when: - ProvideReportLogsStep after = new StepConfigTester(jenkins).configRoundTrip(before) + ProvideLogsStep after = new StepConfigTester(jenkins).configRoundTrip(before) then: jenkins.assertEqualDataBoundBeans(before, after) } @@ -31,7 +31,7 @@ class ProvideReportLogStepIT extends IntegrationTestBase { given: SnippetizerTester st = new SnippetizerTester(jenkins) when: - ProvideReportLogsStep step = new ProvideReportLogsStep() + ProvideLogsStep step = new ProvideLogsStep() then: st.assertRoundTrip(step, "ttProvideReportLogs()") } @@ -39,9 +39,9 @@ class ProvideReportLogStepIT extends IntegrationTestBase { def 'Run pipeline'() { given: WorkflowJob job = jenkins.createProject(WorkflowJob.class, 'pipeline') - job.setDefinition(new CpsFlowDefinition("node {ttProvideReportLogs()}", true)) + job.setDefinition(new CpsFlowDefinition("node {ttProvideLogs()}", true)) expect: WorkflowRun run = jenkins.assertBuildStatus(Result.FAILURE, job.scheduleBuild2(0).get()) - jenkins.assertLogContains("Providing ecu.test report logs to jenkins.", run) + jenkins.assertLogContains("Providing ecu.test logs to jenkins.", run) } }