You've already forked jenkins-lib
forked from jenkins/jenkins-lib
Merge pull request #54 from firstBitSemenovskaya/tdd
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,6 +3,7 @@
|
||||
build/
|
||||
bin/
|
||||
lib/
|
||||
out/
|
||||
|
||||
*.iml
|
||||
.classpath
|
||||
|
@@ -112,7 +112,7 @@ pipeline1C()
|
||||
* `STORAGE_USER` - параметры авторизации в хранилище вида "username with password" (для `secrets` -> `storage`).
|
||||
* Все "шаги" по умолчанию выключены (`stages`).
|
||||
* Если в корне репозитория существует файл `packagedef`, то в шагах, работающих с информационной базой, будет выполнена попытка установки локальных зависимостей средствами `opm`.
|
||||
* Если после установки локальных зависимостей в каталоге `oscript_modules/bin` сушествует файл `vrunner`, то для выполнения команд работы с информационной базой будет использоваться он, а не глобально установленный `vrunner` из `PATH`.
|
||||
* Если после установки локальных зависимостей в каталоге `oscript_modules/bin` существует файл `vrunner`, то для выполнения команд работы с информационной базой будет использоваться он, а не глобально установленный `vrunner` из `PATH`.
|
||||
* Результаты в формате `allure` ожидаются в каталоге `build/out/allure` или его подкаталогах.
|
||||
* Инициализация:
|
||||
* Информационная база инициализируется только в том случае, если в сборочной линии включены шаги, работающие с базой (например, `bdd` или `syntaxCheck`).
|
||||
@@ -121,14 +121,16 @@ pipeline1C()
|
||||
* Первичный запуск информационной базы:
|
||||
* Если информационная база нужна для запуска в режиме "Предприятие" (например, для шагов `bdd` или `smoke`), то будет запущен шаг "Миграция ИБ".
|
||||
* После загрузки конфигурации в ИБ будет выполняться запуск ИБ с целью запуска обработчиков обновления из БСП (`initInfobase` -> `runMigration`).
|
||||
* Если в настройках шага инициализации не заполнен массив дополнительных шагов миграции (`initInfobase` -> `additionalInitializationSteps`), но в каталоге `tools` присутствуют файлы с именами, удовлетворяющими шаблону `vrunner.init*.json`, то автоматически выполняется запуск `vrunner vanessa` с передачей найденных файлов в качестве значения настроек (параметр `--settings`) в порядке лексиграфической сортировки имен файлов.
|
||||
* Если в настройках шага инициализации не заполнен массив дополнительных шагов миграции (`initInfobase` -> `additionalInitializationSteps`), но в каталоге `tools` присутствуют файлы с именами, удовлетворяющими шаблону `vrunner.init*.json`, то автоматически выполняется запуск `vrunner vanessa` с передачей найденных файлов в качестве значения настроек (параметр `--settings`) в порядке лексикографической сортировки имен файлов.
|
||||
* BDD:
|
||||
* Если в конфигурационном файле проекта не заполнена настройка `bdd` -> `vrunnerSteps`, то автоматически выполняется запуск `vrunner vanessa --settings tools/vrunner.json`.
|
||||
* Дымовые тесты
|
||||
* Если в конфигурационном файле проекта не заполнена настройка `smoke` -> `vrunnerSettings`, то автоматически выполняется запуск `vrunner vanessa --settings tools/vrunner.json`, а на выходе формируется только отчет в формате JUnit
|
||||
* Синтаксический контроль:
|
||||
* Если в репозитории существует файл `tools/vrunner.json`, то синтаксический контроль конфигурации с помощью конфигуратора будет выполняться с передачей файла в параметры запуска `vrunner syntax-check --settings tools/vrunner.json` (`syntaxCheck` -> `vrunnerSettings`).
|
||||
* Применяется группировка ошибок по метаданным (`syntaxCheck` -> `groupErrorsByMetadata`).
|
||||
* Выгрузка результатов в формат `jUnit` осуществляется в файл `./build/out/jUnit/syntax.xml` (`syntaxCheck` -> `pathToJUnitReport`).
|
||||
* Если в репозитории существует файл `./tools/syntax-check-exception-file.txt`, то команде запука синтаксического контроля конфигурации данный файл будет передаваться как файл с исключениями сообщений об ошибках (параметр `--exception-file`) (`syntaxCheck` -> `exceptionFile`).
|
||||
* Если в репозитории существует файл `./tools/syntax-check-exception-file.txt`, то команде запуска синтаксического контроля конфигурации данный файл будет передаваться как файл с исключениями сообщений об ошибках (параметр `--exception-file`) (`syntaxCheck` -> `exceptionFile`).
|
||||
* Конфигурационный файл по умолчанию уже содержит ряд "режимов проверки" для синтаксического контроля конфигурации (`syntaxCheck` -> `checkModes`).
|
||||
* Трансформация результатов валидации EDT:
|
||||
* По умолчанию из результатов анализа исключаются замечания, сработавшие на модулях с включенным запретом редактирования (желтый куб с замком) (параметры `resultsTransform` -> `removeSupport` и `resultsTransform` -> `supportLevel`).
|
||||
|
@@ -50,6 +50,11 @@
|
||||
],
|
||||
"vrunnerSettings": "./tools/vrunner.json"
|
||||
},
|
||||
"smoke": {
|
||||
"vrunnerSettings": "./tools/vrunner.json",
|
||||
"publishToAllureReport": false,
|
||||
"publishToJUnitReport": true
|
||||
},
|
||||
"resultsTransform": {
|
||||
"removeSupport": true,
|
||||
"supportLevel": 0
|
||||
|
@@ -151,6 +151,25 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"smoke" : {
|
||||
"type" : "object",
|
||||
"id" : "urn:jsonschema:ru:pulsar:jenkins:library:configuration:SmokeTestOptions",
|
||||
"description" : "Настройки дымового тестирования",
|
||||
"properties" : {
|
||||
"vrunnerSettings" : {
|
||||
"type" : "string",
|
||||
"description" : "Путь к конфигурационному файлу vanessa-runner.\n По умолчанию содержит значение \"./tools/vrunner.json\".\n "
|
||||
},
|
||||
"publishToAllureReport" : {
|
||||
"type" : "boolean",
|
||||
"description" : "Выполнять публикацию результатов в отчет Allure.\n По умолчанию выключено.\n "
|
||||
},
|
||||
"publishToJUnitReport" : {
|
||||
"type" : "boolean",
|
||||
"description" : "Выполнять публикацию результатов в отчет JUnit.\n По умолчанию включено.\n "
|
||||
}
|
||||
}
|
||||
},
|
||||
"resultsTransform" : {
|
||||
"type" : "object",
|
||||
"id" : "urn:jsonschema:ru:pulsar:jenkins:library:configuration:ResultsTransformOptions",
|
||||
|
@@ -17,6 +17,8 @@ interface IStepExecutor {
|
||||
|
||||
FileWrapper[] findFiles(String glob, String excludes)
|
||||
|
||||
String readFile(String file)
|
||||
|
||||
String readFile(String file, String encoding)
|
||||
|
||||
boolean fileExists(String file)
|
||||
@@ -73,5 +75,7 @@ interface IStepExecutor {
|
||||
|
||||
def allure(List<String> results)
|
||||
|
||||
def junit(String testResults, boolean allowEmptyResults)
|
||||
|
||||
def installLocalDependencies()
|
||||
}
|
@@ -33,7 +33,7 @@ class StepExecutor implements IStepExecutor {
|
||||
}
|
||||
|
||||
@Override
|
||||
String readFile(String file, String encoding) {
|
||||
String readFile(String file, String encoding = 'UTF-8') {
|
||||
steps.readFile encoding: encoding, file: file
|
||||
}
|
||||
|
||||
@@ -174,6 +174,11 @@ class StepExecutor implements IStepExecutor {
|
||||
])
|
||||
}
|
||||
|
||||
@Override
|
||||
def junit(String testResults, boolean allowEmptyResults) {
|
||||
steps.junit testResults: testResults, allowEmptyResults: allowEmptyResults
|
||||
}
|
||||
|
||||
@Override
|
||||
def installLocalDependencies() {
|
||||
steps.installLocalDependencies()
|
||||
|
@@ -59,6 +59,7 @@ class ConfigurationReader implements Serializable {
|
||||
"initInfobaseOptions",
|
||||
"bddOptions",
|
||||
"sonarQubeOptions",
|
||||
"smokeTestOptions",
|
||||
"syntaxCheckOptions",
|
||||
"resultsTransformOptions"
|
||||
).toSet()
|
||||
|
@@ -1,7 +1,6 @@
|
||||
package ru.pulsar.jenkins.library.configuration
|
||||
|
||||
import com.cloudbees.groovy.cps.NonCPS
|
||||
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyDescription
|
||||
@@ -45,6 +44,10 @@ class JobConfiguration implements Serializable {
|
||||
@JsonPropertyDescription("Настройки синтаксического контроля")
|
||||
SyntaxCheckOptions syntaxCheckOptions;
|
||||
|
||||
@JsonProperty("smoke")
|
||||
@JsonPropertyDescription("Настройки дымового тестирования")
|
||||
SmokeTestOptions smokeTestOptions;
|
||||
|
||||
@JsonProperty("resultsTransform")
|
||||
@JsonPropertyDescription("Настройки трансформации результатов анализа")
|
||||
ResultsTransformOptions resultsTransformOptions;
|
||||
@@ -67,6 +70,7 @@ class JobConfiguration implements Serializable {
|
||||
", bddOptions=" + bddOptions +
|
||||
", sonarQubeOptions=" + sonarQubeOptions +
|
||||
", syntaxCheckOptions=" + syntaxCheckOptions +
|
||||
", smokeTestOptions=" + smokeTestOptions +
|
||||
", resultsTransformOptions=" + resultsTransformOptions +
|
||||
", logosConfig=" + logosConfig +
|
||||
'}';
|
||||
|
@@ -0,0 +1,34 @@
|
||||
package ru.pulsar.jenkins.library.configuration
|
||||
|
||||
import com.cloudbees.groovy.cps.NonCPS
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyDescription
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
class SmokeTestOptions implements Serializable {
|
||||
|
||||
@JsonPropertyDescription("""Путь к конфигурационному файлу vanessa-runner.
|
||||
По умолчанию содержит значение "./tools/vrunner.json".
|
||||
""")
|
||||
String vrunnerSettings
|
||||
|
||||
@JsonPropertyDescription("""Выполнять публикацию результатов в отчет Allure.
|
||||
По умолчанию выключено.
|
||||
""")
|
||||
boolean publishToAllureReport
|
||||
|
||||
@JsonPropertyDescription("""Выполнять публикацию результатов в отчет JUnit.
|
||||
По умолчанию включено.
|
||||
""")
|
||||
boolean publishToJUnitReport
|
||||
|
||||
@Override
|
||||
@NonCPS
|
||||
String toString() {
|
||||
return "SmokeTestOptions{" +
|
||||
"vrunnerSettings=" + vrunnerSettings +
|
||||
", publishToAllureReport=" + publishToAllureReport +
|
||||
", publishToJUnitReport=" + publishToJUnitReport +
|
||||
'}'
|
||||
}
|
||||
}
|
@@ -23,6 +23,9 @@ class PublishAllure implements Serializable {
|
||||
|
||||
safeUnstash('init-allure')
|
||||
safeUnstash('bdd-allure')
|
||||
if (config.smokeTestOptions.publishToAllureReport) {
|
||||
safeUnstash(SmokeTest.SMOKE_ALLURE_STASH)
|
||||
}
|
||||
|
||||
def env = steps.env();
|
||||
|
||||
@@ -47,7 +50,7 @@ class PublishAllure implements Serializable {
|
||||
private void safeUnstash(String stashName) {
|
||||
try {
|
||||
steps.unstash(stashName)
|
||||
} catch (Exception ex) {
|
||||
} catch (Exception ignored) {
|
||||
Logger.println("Can't unstash $stashName")
|
||||
}
|
||||
}
|
||||
|
118
src/ru/pulsar/jenkins/library/steps/SmokeTest.groovy
Normal file
118
src/ru/pulsar/jenkins/library/steps/SmokeTest.groovy
Normal file
@@ -0,0 +1,118 @@
|
||||
package ru.pulsar.jenkins.library.steps
|
||||
|
||||
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.FileUtils
|
||||
import ru.pulsar.jenkins.library.utils.Logger
|
||||
import ru.pulsar.jenkins.library.utils.VRunner
|
||||
|
||||
class SmokeTest implements Serializable {
|
||||
|
||||
public static final String SMOKE_ALLURE_STASH = 'smoke-allure'
|
||||
|
||||
private final JobConfiguration config
|
||||
|
||||
SmokeTest(JobConfiguration config) {
|
||||
this.config = config
|
||||
}
|
||||
|
||||
def run() {
|
||||
IStepExecutor steps = ContextRegistry.getContext().getStepExecutor()
|
||||
|
||||
Logger.printLocation()
|
||||
|
||||
if (!config.stageFlags.smoke) {
|
||||
Logger.println("Smoke test step is disabled")
|
||||
return
|
||||
}
|
||||
|
||||
List<String> logosConfig = ["LOGOS_CONFIG=$config.logosConfig"]
|
||||
steps.withEnv(logosConfig) {
|
||||
steps.installLocalDependencies()
|
||||
}
|
||||
|
||||
def options = config.smokeTestOptions
|
||||
def env = steps.env()
|
||||
|
||||
String vrunnerPath = VRunner.getVRunnerPath()
|
||||
String command = "$vrunnerPath xunit --ibconnection \"/F./build/ib\""
|
||||
|
||||
String vrunnerSettings = options.vrunnerSettings
|
||||
if (steps.fileExists(vrunnerSettings)) {
|
||||
command += " --settings $vrunnerSettings"
|
||||
}
|
||||
|
||||
String xddTestRunnerPath = "./oscript_modules/add/xddTestRunner.epf"
|
||||
if (steps.fileExists(xddTestRunnerPath)) {
|
||||
command += " --pathxunit $xddTestRunnerPath"
|
||||
}
|
||||
|
||||
String xddConfigPath = "./tools/xUnitParams.json"
|
||||
if (steps.fileExists(xddConfigPath)) {
|
||||
command += " --xddConfig $xddConfigPath"
|
||||
}
|
||||
|
||||
String junitReport = "build/out/jUnit/smoke/smoke.xml"
|
||||
FilePath pathToJUnitReport = FileUtils.getFilePath("$env.WORKSPACE/$junitReport")
|
||||
String junitReportDir = FileUtils.getLocalPath(pathToJUnitReport.getParent())
|
||||
|
||||
String allureReport = "build/out/allure/smoke/allure.xml"
|
||||
FilePath pathToAllureReport = FileUtils.getFilePath("$env.WORKSPACE/$allureReport")
|
||||
String allureReportDir = FileUtils.getLocalPath(pathToAllureReport.getParent())
|
||||
|
||||
StringJoiner reportsConfigConstructor = new StringJoiner(";")
|
||||
|
||||
if (options.publishToJUnitReport) {
|
||||
steps.createDir(junitReportDir)
|
||||
|
||||
String junitReportCommand = "ГенераторОтчетаJUnitXML{$junitReport}"
|
||||
|
||||
reportsConfigConstructor.add(junitReportCommand)
|
||||
}
|
||||
|
||||
if (options.publishToAllureReport) {
|
||||
steps.createDir(allureReportDir)
|
||||
|
||||
String allureReportCommand = "ГенераторОтчетаAllureXMLВерсия2{$allureReport}"
|
||||
|
||||
reportsConfigConstructor.add(allureReportCommand)
|
||||
}
|
||||
|
||||
if (reportsConfigConstructor.length() > 0) {
|
||||
String reportsConfig = reportsConfigConstructor.toString()
|
||||
command += " --reportsxunit \"$reportsConfig\""
|
||||
}
|
||||
|
||||
if (steps.isUnix()) {
|
||||
command = command.replace(';', '\\;')
|
||||
}
|
||||
|
||||
if (!VRunner.configContainsSetting(vrunnerSettings, "testsPath")) {
|
||||
String testsPath = "oscript_modules/add/tests/smoke"
|
||||
if (!steps.fileExists(testsPath)) {
|
||||
testsPath = '$addRoot/tests/smoke'
|
||||
if (steps.isUnix()) {
|
||||
testsPath = '\\' + testsPath
|
||||
}
|
||||
}
|
||||
command += " $testsPath"
|
||||
}
|
||||
|
||||
steps.withEnv(logosConfig) {
|
||||
VRunner.exec(command)
|
||||
}
|
||||
|
||||
if (options.publishToAllureReport) {
|
||||
steps.stash(SMOKE_ALLURE_STASH, "$allureReportDir/**", true)
|
||||
steps.archiveArtifacts("$allureReportDir/**")
|
||||
}
|
||||
|
||||
if (options.publishToJUnitReport) {
|
||||
steps.junit("$junitReportDir/*.xml", true)
|
||||
steps.archiveArtifacts("$junitReportDir/**")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -27,4 +27,11 @@ class VRunner {
|
||||
return steps.cmd(command, returnStatus)
|
||||
} as int
|
||||
}
|
||||
|
||||
static boolean configContainsSetting(String configPath, String settingName) {
|
||||
IStepExecutor steps = ContextRegistry.getContext().getStepExecutor()
|
||||
|
||||
String fileContent = steps.readFile(configPath)
|
||||
return fileContent.contains("\"$settingName\"")
|
||||
}
|
||||
}
|
||||
|
@@ -28,7 +28,7 @@ class VersionParser implements Serializable {
|
||||
return ""
|
||||
}
|
||||
|
||||
def configurationText = steps.readFile(filePath, 'UTF-8');
|
||||
def configurationText = steps.readFile(filePath)
|
||||
return version(configurationText, regexp)
|
||||
}
|
||||
|
||||
|
@@ -44,6 +44,10 @@ class ConfigurationReaderTest {
|
||||
assertThat(jobConfiguration.getResultsTransformOptions().isRemoveSupport()).isFalse();
|
||||
assertThat(jobConfiguration.getResultsTransformOptions().getSupportLevel()).isZero();
|
||||
|
||||
assertThat(jobConfiguration.getSmokeTestOptions().getVrunnerSettings()).contains("./tools/vrunner-smoke.json");
|
||||
assertThat(jobConfiguration.getSmokeTestOptions().isPublishToAllureReport()).isFalse();
|
||||
assertThat(jobConfiguration.getSmokeTestOptions().isPublishToJUnitReport()).isTrue();
|
||||
|
||||
assertThat(jobConfiguration.getInitInfobaseOptions().getRunMigration()).isFalse();
|
||||
assertThat(jobConfiguration.getInitInfobaseOptions().getAdditionalInitializationSteps()).contains("vanessa --settings ./tools/vrunner.first.json");
|
||||
|
||||
|
@@ -34,6 +34,11 @@ public class TestUtils {
|
||||
return FileUtils.readFileToString(new File(file), encoding);
|
||||
});
|
||||
|
||||
when(steps.readFile(anyString())).thenAnswer(invocation -> {
|
||||
String file = invocation.getArgument(0);
|
||||
return FileUtils.readFileToString(new File(file), StandardCharsets.UTF_8);
|
||||
});
|
||||
|
||||
when(steps.fileExists(anyString())).thenAnswer(invocation -> {
|
||||
String file = invocation.getArgument(0);
|
||||
return new File(file).exists();
|
||||
|
@@ -18,5 +18,10 @@
|
||||
"resultsTransform": {
|
||||
"removeSupport": false
|
||||
},
|
||||
"smoke": {
|
||||
"vrunnerSettings": "./tools/vrunner-smoke.json",
|
||||
"publishToAllureReport": false,
|
||||
"publishToJUnitReport": true
|
||||
},
|
||||
"logosConfig": "logger.rootLogger=DEBUG"
|
||||
}
|
@@ -183,6 +183,8 @@ void call() {
|
||||
expression { config.stageFlags.smoke }
|
||||
}
|
||||
steps {
|
||||
unzipInfobase()
|
||||
|
||||
smoke config
|
||||
}
|
||||
}
|
||||
|
@@ -1,23 +1,12 @@
|
||||
import ru.pulsar.jenkins.library.configuration.JobConfiguration
|
||||
import ru.pulsar.jenkins.library.ioc.ContextRegistry
|
||||
import ru.pulsar.jenkins.library.steps.SmokeTest
|
||||
|
||||
def call(JobConfiguration config) {
|
||||
|
||||
ContextRegistry.registerDefaultContext(this)
|
||||
|
||||
// TODO: Вынести в отдельный класс по аналогии с SonarScanner
|
||||
|
||||
printLocation()
|
||||
|
||||
if (!config.stageFlags.smoke) {
|
||||
echo("Smoke tests step is disabled")
|
||||
return
|
||||
}
|
||||
|
||||
def options = config.syntaxCheckOptions
|
||||
|
||||
installLocalDependencies()
|
||||
|
||||
unzipInfobase()
|
||||
def smokeTest = new SmokeTest(config)
|
||||
smokeTest.run()
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user