diff --git a/src/ru/pulsar/jenkins/library/IStepExecutor.groovy b/src/ru/pulsar/jenkins/library/IStepExecutor.groovy index 0619e0c..b8d0c50 100644 --- a/src/ru/pulsar/jenkins/library/IStepExecutor.groovy +++ b/src/ru/pulsar/jenkins/library/IStepExecutor.groovy @@ -7,6 +7,9 @@ import jenkins.plugins.http_request.ResponseContentSupplier import org.jenkinsci.plugins.pipeline.utility.steps.fs.FileWrapper import org.jenkinsci.plugins.workflow.support.actions.EnvironmentAction import org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper +import ru.pulsar.jenkins.library.configuration.JobConfiguration +import ru.pulsar.jenkins.library.configuration.StepCoverageOptions +import ru.pulsar.jenkins.library.steps.Coverable interface IStepExecutor { @@ -20,6 +23,7 @@ interface IStepExecutor { FileWrapper[] findFiles(String glob) + @SuppressWarnings('unused') FileWrapper[] findFiles(String glob, String excludes) String readFile(String file) @@ -66,6 +70,8 @@ interface IStepExecutor { def withEnv(List strings, Closure body) + def withCoverage(JobConfiguration config, Coverable stage, StepCoverageOptions options, Closure body) + def lock(String resource, Closure body) def archiveArtifacts(String path) @@ -80,14 +86,17 @@ interface IStepExecutor { def zip(String dir, String zipFile) + @SuppressWarnings('unused') def zip(String dir, String zipFile, String glob) def unzip(String dir, String zipFile) + @SuppressWarnings('unused') def unzip(String dir, String zipFile, quiet) def catchError(Closure body) + @SuppressWarnings('unused') ResponseContentSupplier httpRequest(String url, String outputFile, String responseHandle, boolean wrapAsMultipart) ResponseContentSupplier httpRequest(String url, HttpMode httpMode, MimeType contentType, String requestBody, String validResponseCodes, boolean consoleLogResponseBody) diff --git a/src/ru/pulsar/jenkins/library/StepExecutor.groovy b/src/ru/pulsar/jenkins/library/StepExecutor.groovy index 6a22d7f..81c29a5 100644 --- a/src/ru/pulsar/jenkins/library/StepExecutor.groovy +++ b/src/ru/pulsar/jenkins/library/StepExecutor.groovy @@ -7,6 +7,9 @@ import jenkins.plugins.http_request.ResponseContentSupplier import org.jenkinsci.plugins.pipeline.utility.steps.fs.FileWrapper import org.jenkinsci.plugins.workflow.support.actions.EnvironmentAction import org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper +import ru.pulsar.jenkins.library.configuration.JobConfiguration +import ru.pulsar.jenkins.library.configuration.StepCoverageOptions +import ru.pulsar.jenkins.library.steps.Coverable import ru.yandex.qatools.allure.jenkins.config.ResultsConfig class StepExecutor implements IStepExecutor { @@ -149,6 +152,11 @@ class StepExecutor implements IStepExecutor { } } + @Override + def withCoverage(JobConfiguration config, Coverable stage, StepCoverageOptions options, Closure body) { + steps.withCoverage(config, stage, options, body) + } + @Override def lock(String resource, Closure body) { steps.lock(resource: resource) { diff --git a/src/ru/pulsar/jenkins/library/steps/Bdd.groovy b/src/ru/pulsar/jenkins/library/steps/Bdd.groovy index e773787..057bbad 100644 --- a/src/ru/pulsar/jenkins/library/steps/Bdd.groovy +++ b/src/ru/pulsar/jenkins/library/steps/Bdd.groovy @@ -3,8 +3,6 @@ package ru.pulsar.jenkins.library.steps import ru.pulsar.jenkins.library.IStepExecutor import ru.pulsar.jenkins.library.configuration.JobConfiguration import ru.pulsar.jenkins.library.ioc.ContextRegistry -import ru.pulsar.jenkins.library.utils.CoverageUtils -import ru.pulsar.jenkins.library.utils.FileUtils import ru.pulsar.jenkins.library.utils.Logger import ru.pulsar.jenkins.library.utils.VRunner @@ -32,9 +30,6 @@ class Bdd implements Serializable, Coverable { } def options = config.bddOptions - def env = steps.env() - def srcDir = config.srcDir - def workspaceDir = FileUtils.getFilePath("$env.WORKSPACE") List logosConfig = ["LOGOS_CONFIG=$config.logosConfig"] steps.withEnv(logosConfig) { @@ -42,13 +37,7 @@ class Bdd implements Serializable, Coverable { steps.createDir('build/out') List returnStatuses = [] - def coverageOpts = config.coverageOptions - def coverageContext = CoverageUtils.prepareContext(config, options) - - steps.lock(coverageContext.lockableResource) { - if (options.coverage) { - CoverageContext.startCoverage(steps, coverageOpts, coverageContext, workspaceDir, srcDir, this) - } + steps.withCoverage(config, this, options) { config.bddOptions.vrunnerSteps.each { Logger.println("Шаг запуска сценариев командой ${it}") @@ -64,18 +53,11 @@ class Bdd implements Serializable, Coverable { } else { Logger.println("Тестирование сценариев завершилось успешно") } - - if (options.coverage) { - CoverageUtils.stopCoverage(steps, coverageOpts, coverageContext) - } } } steps.stash(ALLURE_STASH, 'build/out/allure/**', true) steps.stash('bdd-cucumber', 'build/out/cucumber/**', true) - if (options.coverage) { - steps.stash(COVERAGE_STASH_NAME, COVERAGE_STASH_PATH, true) - } } @@ -83,6 +65,11 @@ class Bdd implements Serializable, Coverable { return COVERAGE_STASH_PATH } + @Override + String getCoverageStashName() { + return COVERAGE_STASH_NAME + } + String getCoveragePidsPath() { return COVERAGE_PIDS_PATH } diff --git a/src/ru/pulsar/jenkins/library/steps/Coverable.groovy b/src/ru/pulsar/jenkins/library/steps/Coverable.groovy index 54271bb..0dbfdd9 100644 --- a/src/ru/pulsar/jenkins/library/steps/Coverable.groovy +++ b/src/ru/pulsar/jenkins/library/steps/Coverable.groovy @@ -3,6 +3,7 @@ package ru.pulsar.jenkins.library.steps interface Coverable { String getCoverageStashPath(); + String getCoverageStashName(); String getCoveragePidsPath(); } \ No newline at end of file diff --git a/src/ru/pulsar/jenkins/library/steps/CoverageContext.groovy b/src/ru/pulsar/jenkins/library/steps/CoverageContext.groovy index 36d4728..5d7d9ee 100644 --- a/src/ru/pulsar/jenkins/library/steps/CoverageContext.groovy +++ b/src/ru/pulsar/jenkins/library/steps/CoverageContext.groovy @@ -5,14 +5,16 @@ import ru.pulsar.jenkins.library.configuration.GlobalCoverageOptions class CoverageContext { String lockableResource + String srcDir GlobalCoverageOptions coverageOptions int port ArrayList pids ArrayList dbgsPids ArrayList coverage41CPids - CoverageContext(String lockableResource, GlobalCoverageOptions coverageOptions, int port, ArrayList dbgsPids, ArrayList coverage41CPids) { + CoverageContext(String lockableResource, String srcDir, GlobalCoverageOptions coverageOptions, int port, ArrayList dbgsPids, ArrayList coverage41CPids) { this.lockableResource = lockableResource + this.srcDir = srcDir this.coverageOptions = coverageOptions this.port = port this.pids = dbgsPids + coverage41CPids diff --git a/src/ru/pulsar/jenkins/library/steps/SmokeTest.groovy b/src/ru/pulsar/jenkins/library/steps/SmokeTest.groovy index 3bed18a..f2f8613 100644 --- a/src/ru/pulsar/jenkins/library/steps/SmokeTest.groovy +++ b/src/ru/pulsar/jenkins/library/steps/SmokeTest.groovy @@ -4,7 +4,6 @@ import hudson.FilePath import ru.pulsar.jenkins.library.IStepExecutor import ru.pulsar.jenkins.library.configuration.JobConfiguration import ru.pulsar.jenkins.library.ioc.ContextRegistry -import ru.pulsar.jenkins.library.utils.CoverageUtils import ru.pulsar.jenkins.library.utils.FileUtils import ru.pulsar.jenkins.library.utils.Logger import ru.pulsar.jenkins.library.utils.StringJoiner @@ -41,9 +40,6 @@ class SmokeTest implements Serializable, Coverable { def options = config.smokeTestOptions def env = steps.env() - def srcDir = config.srcDir - def workspaceDir = FileUtils.getFilePath("$env.WORKSPACE") - String vrunnerPath = VRunner.getVRunnerPath() String command = "$vrunnerPath xunit --ibconnection \"/F./build/ib\"" @@ -107,43 +103,32 @@ class SmokeTest implements Serializable, Coverable { command += " $testsPath" } - def coverageOpts = config.coverageOptions - def coverageContext = CoverageUtils.prepareContext(config, options) + steps.withEnv(logosConfig) { - steps.lock(coverageContext.lockableResource) { - if (options.coverage) { - CoverageContext.startCoverage(steps, coverageOpts, coverageContext, workspaceDir, srcDir, this) - } - - steps.withEnv(logosConfig) { + steps.withCoverage(config, this, options) { VRunner.exec(command, true) } - if (options.coverage) { - CoverageUtils.stopCoverage(steps, coverageOpts, coverageContext) + if (options.publishToAllureReport) { + steps.stash(ALLURE_STASH, "$allureReportDir/**", true) + steps.archiveArtifacts("$allureReportDir/**") + } + + if (options.publishToJUnitReport) { + steps.junit("$junitReportDir/*.xml", true) + steps.archiveArtifacts("$junitReportDir/**") } } - - if (options.publishToAllureReport) { - steps.stash(ALLURE_STASH, "$allureReportDir/**", true) - steps.archiveArtifacts("$allureReportDir/**") - } - - if (options.publishToJUnitReport) { - steps.junit("$junitReportDir/*.xml", true) - steps.archiveArtifacts("$junitReportDir/**") - } - - if (options.coverage) { - steps.stash(COVERAGE_STASH_NAME, COVERAGE_STASH_PATH, true) - } - } String getCoverageStashPath() { return COVERAGE_STASH_PATH } + String getCoverageStashName() { + return COVERAGE_STASH_NAME + } + String getCoveragePidsPath() { return COVERAGE_PIDS_PATH } diff --git a/src/ru/pulsar/jenkins/library/steps/WithCoverage.groovy b/src/ru/pulsar/jenkins/library/steps/WithCoverage.groovy new file mode 100644 index 0000000..c7f8312 --- /dev/null +++ b/src/ru/pulsar/jenkins/library/steps/WithCoverage.groovy @@ -0,0 +1,47 @@ +package ru.pulsar.jenkins.library.steps + +import ru.pulsar.jenkins.library.IStepExecutor +import ru.pulsar.jenkins.library.configuration.JobConfiguration +import ru.pulsar.jenkins.library.configuration.StepCoverageOptions +import ru.pulsar.jenkins.library.ioc.ContextRegistry +import ru.pulsar.jenkins.library.utils.CoverageUtils + +class WithCoverage implements Serializable { + + private final JobConfiguration config + private final Coverable stage + private final StepCoverageOptions coverageOptions + private final Closure body + + WithCoverage(JobConfiguration config, Coverable stage, StepCoverageOptions coverageOptions, Closure body) { + this.config = config + this.stage = stage + this.coverageOptions = coverageOptions + this.body = body + } + + def run() { + + def context = CoverageUtils.prepareContext(config, coverageOptions) + + IStepExecutor steps = ContextRegistry.getContext().getStepExecutor() + + //noinspection GroovyMissingReturnStatement + steps.lock(context.lockableResource) { + if (coverageOptions.coverage) { + CoverageUtils.startCoverage(steps, config, context, stage) + } + + body() + + if (coverageOptions.coverage) { + CoverageUtils.stopCoverage(steps, config, context) + } + } + + if (coverageOptions.coverage) { + steps.stash(stage.getCoverageStashName(), stage.getCoverageStashPath(), true) + } + + } +} diff --git a/src/ru/pulsar/jenkins/library/steps/Yaxunit.groovy b/src/ru/pulsar/jenkins/library/steps/Yaxunit.groovy index 2be4ffb..e6f657a 100644 --- a/src/ru/pulsar/jenkins/library/steps/Yaxunit.groovy +++ b/src/ru/pulsar/jenkins/library/steps/Yaxunit.groovy @@ -4,7 +4,6 @@ import hudson.FilePath import ru.pulsar.jenkins.library.IStepExecutor import ru.pulsar.jenkins.library.configuration.JobConfiguration import ru.pulsar.jenkins.library.ioc.ContextRegistry -import ru.pulsar.jenkins.library.utils.CoverageUtils import ru.pulsar.jenkins.library.utils.FileUtils import ru.pulsar.jenkins.library.utils.Logger import ru.pulsar.jenkins.library.utils.VRunner @@ -42,9 +41,6 @@ class Yaxunit implements Serializable, Coverable { def options = config.yaxunitOptions def env = steps.env() - def srcDir = config.srcDir - def workspaceDir = FileUtils.getFilePath("$env.WORKSPACE") - String vrunnerPath = VRunner.getVRunnerPath() String ibConnection = ' --ibconnection "/F./build/ib"' @@ -69,48 +65,34 @@ class Yaxunit implements Serializable, Coverable { } - def coverageOpts = config.coverageOptions - def coverageContext = CoverageUtils.prepareContext(config, options) + steps.withEnv(logosConfig) { - steps.lock(coverageContext.lockableResource) { - if (options.coverage) { - CoverageContext.startCoverage(steps, coverageOpts, coverageContext, workspaceDir, srcDir, this) - } - - // Выполняем команды - steps.withEnv(logosConfig) { + steps.withCoverage(config, this, options) { VRunner.exec(runTestsCommand, true) } - if (options.coverage) { - CoverageUtils.stopCoverage(steps, coverageOpts, coverageContext) + // Сохраняем результаты + String junitReport = "./build/out/yaxunit/junit.xml" + FilePath pathToJUnitReport = FileUtils.getFilePath("$env.WORKSPACE/$junitReport") + String junitReportDir = FileUtils.getLocalPath(pathToJUnitReport.getParent()) + + if (options.publishToJUnitReport) { + steps.junit("$junitReportDir/*.xml", true) + steps.archiveArtifacts("$junitReportDir/**") } - } - // Сохраняем результаты - String junitReport = "./build/out/yaxunit/junit.xml" - FilePath pathToJUnitReport = FileUtils.getFilePath("$env.WORKSPACE/$junitReport") - String junitReportDir = FileUtils.getLocalPath(pathToJUnitReport.getParent()) + if (options.publishToAllureReport) { + String allureReport = "./build/out/allure/yaxunit/junit.xml" + FilePath pathToAllureReport = FileUtils.getFilePath("$env.WORKSPACE/$allureReport") + String allureReportDir = FileUtils.getLocalPath(pathToAllureReport.getParent()) - if (options.publishToJUnitReport) { - steps.junit("$junitReportDir/*.xml", true) - steps.archiveArtifacts("$junitReportDir/**") - } + pathToJUnitReport.copyTo(pathToAllureReport) - if (options.publishToAllureReport) { - String allureReport = "./build/out/allure/yaxunit/junit.xml" - FilePath pathToAllureReport = FileUtils.getFilePath("$env.WORKSPACE/$allureReport") - String allureReportDir = FileUtils.getLocalPath(pathToAllureReport.getParent()) + steps.stash(YAXUNIT_ALLURE_STASH, "$allureReportDir/**", true) + } - pathToJUnitReport.copyTo(pathToAllureReport) + steps.archiveArtifacts("build/out/yaxunit/junit.xml") - steps.stash(YAXUNIT_ALLURE_STASH, "$allureReportDir/**", true) - } - - steps.archiveArtifacts("build/out/yaxunit/junit.xml") - - if (options.coverage) { - steps.stash(COVERAGE_STASH_NAME, COVERAGE_STASH_PATH, true) } } @@ -118,9 +100,12 @@ class Yaxunit implements Serializable, Coverable { return COVERAGE_STASH_PATH } + @Override + String getCoverageStashName() { + return COVERAGE_STASH_NAME + } + String getCoveragePidsPath() { return COVERAGE_PIDS_PATH } - - } diff --git a/src/ru/pulsar/jenkins/library/utils/CoverageUtils.groovy b/src/ru/pulsar/jenkins/library/utils/CoverageUtils.groovy index 71624cf..99ab436 100644 --- a/src/ru/pulsar/jenkins/library/utils/CoverageUtils.groovy +++ b/src/ru/pulsar/jenkins/library/utils/CoverageUtils.groovy @@ -1,9 +1,7 @@ package ru.pulsar.jenkins.library.utils -import hudson.FilePath import org.apache.commons.lang3.RandomStringUtils import ru.pulsar.jenkins.library.IStepExecutor -import ru.pulsar.jenkins.library.configuration.GlobalCoverageOptions import ru.pulsar.jenkins.library.configuration.JobConfiguration import ru.pulsar.jenkins.library.configuration.StepCoverageOptions import ru.pulsar.jenkins.library.ioc.ContextRegistry @@ -39,13 +37,20 @@ class CoverageUtils { lockableResource = "${env.NODE_NAME}_$port" } - return new CoverageContext(lockableResource, coverageOpts, port, currentDbgsPids, currentCoverage41CPids) + return new CoverageContext(lockableResource, config.srcDir, coverageOpts, port, currentDbgsPids, currentCoverage41CPids) } - static void startCoverage(IStepExecutor steps, GlobalCoverageOptions coverageOpts, CoverageContext coverageContext, FilePath workspaceDir, String srcDir, Coverable coverable) { + static void startCoverage(IStepExecutor steps, JobConfiguration config, CoverageContext coverageContext, Coverable stage) { + + def env = steps.env() + def srcDir = config.srcDir + def workspaceDir = FileUtils.getFilePath("$env.WORKSPACE") + + def coverageOpts = config.coverageOptions + steps.start("${coverageOpts.dbgsPath} --addr=127.0.0.1 --port=$coverageContext.port") - steps.start("${coverageOpts.coverage41CPath} start -i DefAlias -u http://127.0.0.1:$coverageContext.port -P $workspaceDir -s $srcDir -o ${coverable.getCoverageStashPath()}") + steps.start("${coverageOpts.coverage41CPath} start -i DefAlias -u http://127.0.0.1:$coverageContext.port -P $workspaceDir -s $srcDir -o ${stage.getCoverageStashPath()}") steps.cmd("${coverageOpts.coverage41CPath} check -i DefAlias -u http://127.0.0.1:$coverageContext.port") def newDbgsPids = getPIDs("dbgs") @@ -57,12 +62,15 @@ class CoverageUtils { newDbgsPids.addAll(newCoverage41CPids) def pids = newDbgsPids.join(" ") - steps.writeFile(coverable.getCoveragePidsPath(), pids, 'UTF-8') + steps.writeFile(stage.getCoveragePidsPath(), pids, 'UTF-8') Logger.println("Coverage PIDs for cleanup: $pids") } - static void stopCoverage(IStepExecutor steps, GlobalCoverageOptions coverageOpts, CoverageContext coverageContext) { + static void stopCoverage(IStepExecutor steps, JobConfiguration config, CoverageContext coverageContext) { + + def coverageOpts = config.coverageOptions + steps.cmd("${coverageOpts.coverage41CPath} stop -i DefAlias -u http://127.0.0.1:$coverageContext.port") } diff --git a/vars/withCoverage.groovy b/vars/withCoverage.groovy new file mode 100644 index 0000000..41ef8e1 --- /dev/null +++ b/vars/withCoverage.groovy @@ -0,0 +1,12 @@ +import ru.pulsar.jenkins.library.configuration.JobConfiguration +import ru.pulsar.jenkins.library.configuration.StepCoverageOptions +import ru.pulsar.jenkins.library.ioc.ContextRegistry +import ru.pulsar.jenkins.library.steps.Coverable +import ru.pulsar.jenkins.library.steps.WithCoverage + +def call(JobConfiguration config, Coverable stage, StepCoverageOptions options, Closure body) { + ContextRegistry.registerDefaultContext(this) + + WithCoverage withCoverage = new WithCoverage(config, stage, options, body) + return withCoverage.run() +} \ No newline at end of file