1
0
mirror of https://github.com/firstBitMarksistskaya/jenkins-lib.git synced 2024-11-28 09:33:03 +02:00

Переезд на градль-рельсы с тестами и объектами

This commit is contained in:
Nikita Gryzlov 2020-03-26 17:04:42 +03:00
parent 39acf5efb0
commit fa208d78ef
No known key found for this signature in database
GPG Key ID: C1EAE411FEF0BF2F
14 changed files with 334 additions and 15 deletions

2
.gitignore vendored
View File

@ -1,3 +1,5 @@
.idea/
.gradle/
build/
*.iml

View File

@ -2,19 +2,60 @@ import com.mkobit.jenkins.pipelines.http.AnonymousAuthentication
plugins {
java
groovy
jacoco
id("com.mkobit.jenkins.pipelines.shared-library") version "0.10.1"
id("com.github.ben-manes.versions") version "0.21.0"
id("com.github.ben-manes.versions") version "0.28.0"
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
}
val junitVersion = "5.6.1"
val spockVersion = "1.3-groovy-2.4"
val groovyVersion = "2.4.19"
val slf4jVersion = "1.8.0-beta4"
dependencies {
val spock = "org.spockframework:spock-core:1.2-groovy-2.4"
testImplementation(spock)
testImplementation("org.assertj:assertj-core:3.12.2")
integrationTestImplementation(spock)
implementation("org.codehaus.groovy", "groovy-all", groovyVersion)
testImplementation("org.junit.jupiter", "junit-jupiter-api", junitVersion)
testRuntimeOnly("org.junit.jupiter", "junit-jupiter-engine", junitVersion)
testImplementation("org.assertj", "assertj-core", "3.15.0")
testImplementation("org.mockito", "mockito-core", "3.3.3")
testImplementation("org.spockframework", "spock-core", spockVersion)
integrationTestImplementation("org.spockframework", "spock-core", spockVersion)
integrationTestImplementation("org.codehaus.groovy", "groovy-all", groovyVersion)
integrationTestImplementation("org.slf4j", "slf4j-api", slf4jVersion)
integrationTestImplementation("org.slf4j", "slf4j-simple", slf4jVersion)
}
tasks.test {
useJUnitPlatform()
testLogging {
events("passed", "skipped", "failed")
}
reports {
html.isEnabled = true
}
}
tasks.check {
dependsOn(tasks.jacocoTestReport)
dependsOn(tasks.integrationTest)
}
tasks.jacocoTestReport {
reports {
xml.isEnabled = true
xml.destination = File("$buildDir/reports/jacoco/test/jacoco.xml")
}
}
jenkinsIntegration {
@ -28,9 +69,9 @@ sharedLibrary {
coreVersion.set(jenkinsIntegration.downloadDirectory.file("core-version.txt").map { it.asFile.readText().trim() })
// TODO: retrieve downloaded plugin resource
pluginDependencies {
dependency("org.jenkins-ci.plugins", "pipeline-build-step", "2.9")
dependency("org.6wind.jenkins", "lockable-resources", "2.5")
val declarativePluginsVersion = "1.3.9"
dependency("org.jenkins-ci.plugins", "pipeline-build-step", "2.12")
dependency("org.6wind.jenkins", "lockable-resources", "2.7")
val declarativePluginsVersion = "1.6.0"
dependency("org.jenkinsci.plugins", "pipeline-model-api", declarativePluginsVersion)
dependency("org.jenkinsci.plugins", "pipeline-model-declarative-agent", "1.1.1")
dependency("org.jenkinsci.plugins", "pipeline-model-definition", declarativePluginsVersion)

View File

@ -1 +1 @@
2.164.3
2.228

View File

@ -0,0 +1,11 @@
package ru.pulsar.jenkins.library
interface IStepExecutor {
boolean isUnix()
int sh(String script, boolean returnStatus, String encoding)
int bat(String script, boolean returnStatus, String encoding)
}

View File

@ -0,0 +1,25 @@
package ru.pulsar.jenkins.library
class StepExecutor implements IStepExecutor {
private steps
StepExecutor(steps) {
this.steps = steps
}
@Override
boolean isUnix() {
return steps.isUnix()
}
@Override
int sh(String script, boolean returnStatus, String encoding) {
steps.sh script: script, returnStatus: returnStatus, encoding: encoding
}
@Override
int bat(String script, boolean returnStatus, String encoding) {
steps.bat script: script, returnStatus: returnStatus, encoding: encoding
}
}

View File

@ -0,0 +1,8 @@
package ru.pulsar.jenkins.library.configuration
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
class JobConfiguration {
}

View File

@ -0,0 +1,17 @@
package ru.pulsar.jenkins.library.ioc
class ContextRegistry implements Serializable {
private static IContext context
static void registerContext(IContext context) {
ContextRegistry.context = context
}
static void registerDefaultContext(Object steps) {
context = new DefaultContext(steps)
}
static IContext getContext() {
return context
}
}

View File

@ -0,0 +1,17 @@
package ru.pulsar.jenkins.library.ioc
import ru.pulsar.jenkins.library.IStepExecutor
import ru.pulsar.jenkins.library.StepExecutor
class DefaultContext implements IContext, Serializable {
private steps
DefaultContext(steps) {
this.steps = steps
}
@Override
IStepExecutor getStepExecutor() {
return new StepExecutor(this.steps)
}
}

View File

@ -0,0 +1,7 @@
package ru.pulsar.jenkins.library.ioc
import ru.pulsar.jenkins.library.IStepExecutor
interface IContext {
IStepExecutor getStepExecutor()
}

View File

@ -0,0 +1,34 @@
package ru.pulsar.jenkins.library.steps
import ru.pulsar.jenkins.library.IStepExecutor
import ru.pulsar.jenkins.library.ioc.ContextRegistry
class Cmd implements Serializable {
private String script;
private boolean returnStatus
private String encoding = 'UTF-8'
Cmd(String script, boolean returnStatus = false) {
this.script = script
this.returnStatus = returnStatus
};
int run() {
IStepExecutor steps = ContextRegistry.getContext().getStepExecutor()
int returnValue
if (steps.isUnix()) {
returnValue = steps.sh("$script", returnStatus, encoding)
} else {
returnValue = steps.bat("chcp 65001 > nul \n$script", returnStatus, encoding)
}
if (!returnStatus && returnValue != 0) {
throw new Error("Returned status code <$returnValue> is not equal to 0.");
}
return returnValue
}
}

View File

@ -0,0 +1,25 @@
import com.mkobit.jenkins.pipelines.codegen.LocalLibraryRetriever
import org.jenkinsci.plugins.workflow.libs.GlobalLibraries
import org.jenkinsci.plugins.workflow.libs.LibraryConfiguration
import org.jenkinsci.plugins.workflow.libs.LibraryRetriever
import org.jvnet.hudson.test.JenkinsRule
final class RuleBootstrapper {
private RuleBootstrapper() {
}
/**
* This demonstrates how you can can configure the {@link JenkinsRule} to use the local source code
* as a {@link LibraryConfiguration}. In this example we are making it implicitly loaded.
*/
static void setup(JenkinsRule rule) {
rule.timeout = 30
final LibraryRetriever retriever = new LocalLibraryRetriever()
final LibraryConfiguration localLibrary =
new LibraryConfiguration('testLibrary', retriever)
localLibrary.implicit = true
localLibrary.defaultVersion = 'unused'
localLibrary.allowVersionOverride = false
GlobalLibraries.get().libraries = [localLibrary]
}
}

View File

@ -0,0 +1,39 @@
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition
import org.jenkinsci.plugins.workflow.job.WorkflowJob
import org.jenkinsci.plugins.workflow.job.WorkflowRun
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.jvnet.hudson.test.JenkinsRule
class cmdTest {
@Rule
public JenkinsRule rule = new JenkinsRule()
@Before
void configureGlobalGitLibraries() {
RuleBootstrapper.setup(rule)
}
@Test
void "cmd should echo something"() {
def pipeline = '''
pipeline {
agent any
stages {
stage('test') {
steps {
cmd("echo helloWorld")
}
}
}
}
'''.stripIndent()
final CpsFlowDefinition flow = new CpsFlowDefinition(pipeline, true)
final WorkflowJob workflowJob = rule.createProject(WorkflowJob, 'project')
workflowJob.definition = flow
rule.assertLogContains('helloWorld', rule.buildAndAssertSuccess(workflowJob))
}
}

View File

@ -0,0 +1,91 @@
package ru.pulsar.jenkins.library.steps;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import ru.pulsar.jenkins.library.IStepExecutor;
import ru.pulsar.jenkins.library.ioc.ContextRegistry;
import ru.pulsar.jenkins.library.ioc.IContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.contains;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
class CmdTest {
private IStepExecutor steps;
@BeforeEach
void setUp() {
IContext context = mock(IContext.class);
steps = mock(IStepExecutor.class);
when(context.getStepExecutor()).thenReturn(steps);
ContextRegistry.registerContext(context);
}
@Test
void runOk() {
// given
final String script = "echo hello";
Cmd cmd = new Cmd(script);
// when
int run = cmd.run();
// then
verify(steps).isUnix();
verify(steps).bat(contains(script), eq(false), anyString());
assertThat(run).isEqualTo(0);
}
@Test
void runFailNoReturn() {
// given
final String script = "false";
Cmd cmd = new Cmd(script);
when(steps.bat(anyString(), anyBoolean(), anyString())).thenReturn(1);
when(steps.sh(anyString(), anyBoolean(), anyString())).thenReturn(1);
// when
Throwable thrown = catchThrowable(cmd::run);
assertThat(thrown).hasMessageContaining("<1>");
// then
verify(steps).isUnix();
assertThat(steps).satisfiesAnyOf(
steps -> verify(steps).bat(contains(script), eq(false), anyString()),
steps -> verify(steps).sh(contains(script), eq(false), anyString())
);
}
@Test
void runPassAndReturn() {
// given
final String script = "false";
Cmd cmd = new Cmd(script, true);
when(steps.bat(anyString(), anyBoolean(), anyString())).thenReturn(1);
when(steps.sh(anyString(), anyBoolean(), anyString())).thenReturn(1);
// when
int run = cmd.run();
// then
verify(steps).isUnix();
assertThat(steps).satisfiesAnyOf(
steps -> verify(steps).bat(contains(script), eq(true), anyString()),
steps -> verify(steps).sh(contains(script), eq(true), anyString())
);
assertThat(run).isEqualTo(1);
}
}

View File

@ -1,7 +1,9 @@
def call(String script, boolean returnStatus = false) {
if (isUnix()) {
sh script: "$script", returnStatus: returnStatus, encoding: "UTF-8"
} else {
bat script: "chcp 65001 > nul \n$script", returnStatus: returnStatus, encoding: "UTF-8"
}
import ru.pulsar.jenkins.library.steps.Cmd
import ru.pulsar.jenkins.library.ioc.ContextRegistry
int call(String script, boolean returnStatus = false) {
ContextRegistry.registerDefaultContext(this)
def cmd = new Cmd(script, returnStatus)
cmd.run()
}