jenkinsci / JenkinsPipelineUnit

Framework for unit testing Jenkins pipelines
MIT License
1.54k stars 390 forks source link

checkout scm sometimes fails? #258

Closed its-your-favorite closed 4 years ago

its-your-favorite commented 4 years ago

I'm using a simplified version of the script you present in README.MD. I see this error groovy.lang.MissingPropertyException: No such property: scm for class: hello3

I wonder though, how this code could possibly work (even as presented in the example). As I understand it, "scm" is a dynamic variable that refers to the commit that kicked off the build. I don't understand how this could work when there is no branch/PR to be checked out when we're operating in a local unit-testing scenario.

Am I supposed to mock/disable the git-scm call to get that example to work?

nre-ableton commented 4 years ago

Can you please give some more context? Specifically, it would be interesting to see your test class and possibly the build.gradle file.

its-your-favorite commented 4 years ago
@Library("commons") _

def execute() {
    node() {
        String revision = stage('Checkout') {
            checkout scm // this doesn't work yet and I don't know why
            //https://github.com/jenkinsci/JenkinsPipelineUnit/issues/258
            return "123"
        }
        echo revision
    }
}

return this
plugins {
    id 'groovy'
}

repositories {
    mavenCentral()
    maven { url 'https://repo.jenkins-ci.org/releases/' }
}

dependencies {
    testImplementation 'junit:junit:4.12'
    testImplementation "com.lesfurets:jenkins-pipeline-unit:1.3"
    implementation('org.codehaus.groovy:groovy-all:2.4.6')

    implementation('com.cloudbees:groovy-cps:1.12')

    implementation('commons-io:commons-io:2.5')
    implementation('org.apache.ivy:ivy:2.4.0')
    implementation('org.apache.commons:commons-lang3:3.5')
}

sourceSets {
    main {
        groovy {
            srcDirs = ['src']
        }
    }

    test {
        groovy {
            srcDirs = ['test']
        }
    }
}

test {
    testLogging.showStandardStreams = true //Show stdout during tests
    testLogging {
        events "passed", "skipped", "failed"
    }
}
nre-ableton commented 4 years ago

Ok, this is a good start. Can we also see your test cases, and how the pipeline is being loaded?

its-your-favorite commented 4 years ago
import static com.lesfurets.jenkins.unit.global.lib.LibraryConfiguration.library
import static com.lesfurets.jenkins.unit.global.lib.ProjectSource.projectSource

import org.junit.Before
import org.junit.Test

import com.lesfurets.jenkins.unit.BasePipelineTest
import com.lesfurets.jenkins.unit.declarative.*
/**
 * This is an example test.
 *
 */

class TestJenkinsPipeline extends BasePipelineTest {

    String sharedLibs = ''

    @Override
    @Before
    void setUp() throws Exception {
        scriptRoots += 'resources'

        def library = library().name('commons')
                .defaultVersion('<notNeeded>')
                .allowOverride(true)
                .implicit(false)
                .targetPath('<notNeeded>')
                .retriever(projectSource())
                .build()
        helper.registerSharedLibrary(library)
        super.setUp()
    }

    @Test
    void testHelloWithLibrary() throws Exception {

        def script = loadScript("hello3.groovy")  //lives in resources/hello3.groovy
        script.execute()

        /*
        helper.callStack.stream()
                .collect { c -> c.methodName + "->" + callArgsToString(c) }
                .forEach { c -> println("One call stack Element: " + c) }
                */

        assertJobStatusSuccess()

    }

}
nre-ableton commented 4 years ago

Ok, thanks. I am not immediately sure why this does not work, and I'll try to play around with the code a bit.

If any other maintainers know what is wrong, feel free to jump in!

stchar commented 4 years ago

scm should be defined as a map in bindings

   @Test
    void testHelloWithLibrary() throws Exception {
        binding.setVariable('scm',[foo:'bar'])
        def script = loadScript("hello3.groovy")  //lives in resources/hello3.groovy
        script.execute()
     ...
nre-ableton commented 4 years ago

Hmm, I see. Why is this binding not set in the setUp() method of BasePipelineTest?

stchar commented 4 years ago

I believe scm is a part of multibranch plugin, which was not so popular by the time this framework had had been created. I can submit a PR with this mock

nre-ableton commented 4 years ago

@stchar I happen to have that project open in my IDE now, so I'll make a PR: https://github.com/jenkinsci/JenkinsPipelineUnit/pull/259