Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Declarative input step] groovy.lang.MissingMethodException: No signature of method: deploymentPipeline.input() #366

Closed
doughgle opened this issue May 12, 2021 · 5 comments

Comments

@doughgle
Copy link

doughgle commented May 12, 2021

Firstly, thanks for the efforts in creating and supporting JenkinsPipelineUnit!

Secondly, need some help...
We're using JenkinsPipelineUnit to test a declarative Jenkins library pipeline (complete pipeline as a library function).
In the first iteration, we want to test whether the input step was invoked or not, based on branch when clauses i.e.

  • when branch is prd -> input step is invoked.
  • when branch is dev -> input step is not invoked.

After introducing a new stage with a declarative input step, we see the error:

groovy.lang.MissingMethodException: No signature of method: deploymentPipeline.input() is applicable for argument types: (deploymentPipeline$_call_closure1$_closure5$_closure9$_closure16) values: [deploymentPipeline$_call_closure1$_closure5$_closure9$_closure16@6b8ba6e3]

The library pipeline structure looks like this:

def call(Map config) {
    pipeline {
        stages {
            stage('Prompt for One Time Password') {
                when {
                    branch 'prd'
                }
                input {
                    message 'Password:'
                    parameters {
                        password(name: 'PASSWORD', defaultValue: '********', description: 'password')
                    }
                }
                steps {
                    // login...
                }
            }
        }
    }
}

I'm afraid we weren't able to find any examples in the docs or issue history.

Q: How should we handle declarative input steps in a test case?

Complete stacktrace:

groovy.lang.MissingMethodException: No signature of method: deploymentPipeline.input() is applicable for argument types: (deploymentPipeline$_call_closure1$_closure5$_closure9$_closure16) values: [deploymentPipeline$_call_closure1$_closure5$_closure9$_closure16@6b8ba6e3]
Possible solutions: inspect(), inject(groovy.lang.Closure), wait(), run(), run(), any()
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:83)
	at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:263)
	at com.lesfurets.jenkins.unit.PipelineTestHelper$_closure4.doCall(PipelineTestHelper.groovy:227)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod.invoke(ClosureMetaMethod.java:84)
	at groovy.lang.MetaClassImpl.invokeMissingMethod(MetaClassImpl.java:939)
	at groovy.lang.MetaClassImpl.invokeMissingMethod(MetaClassImpl.java:826)
	at groovy.lang.DelegatingMetaClass.invokeMissingMethod(DelegatingMetaClass.java:234)
	at groovy.lang.MetaClass$invokeMissingMethod$0.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
	at groovy.lang.MetaClass$invokeMissingMethod$0.call(Unknown Source)
	at com.lesfurets.jenkins.unit.PipelineTestHelper$_closure3.doCall(PipelineTestHelper.groovy:188)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod.invoke(ClosureMetaMethod.java:84)
	at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1123)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:810)
	at groovy.lang.GroovyObjectSupport.invokeMethod(GroovyObjectSupport.java:46)
	at groovy.lang.Script.invokeMethod(Script.java:80)
@doughgle doughgle changed the title groovy.lang.MissingMethodException: No signature of method for declarative input step [Declarative input step] groovy.lang.MissingMethodException: No signature of method: deploymentPipeline.input() May 18, 2021
@doughgle
Copy link
Author

@nre-ableton, @stchar,
Can you share any advice on how to test with declarative input step?

@nre-ableton
Copy link
Contributor

I'm pretty sure that you need to provide a mock for the input step. I'm wholly unfamiliar with declarative pipelines, though, so I have no idea how that would look like.

@doughgle
Copy link
Author

doughgle commented May 19, 2021

Thanks @nre-ableton!

These simple mocks were good enough for our context:

        helper.registerAllowedMethod("input", [Closure.class], null)
        helper.registerAllowedMethod("message", [String.class], null)

@nre-ableton
Copy link
Contributor

Glad to hear that you got it working! Poking around the code a bit, I guess we could add these mocks to DeclarativePipelineTest. However, at least you have a workaround for now.

@doughgle
Copy link
Author

@nre-ableton Agreed. The null callback may be overly simplistic for the generic case, but it works for us.
The message string gets printed by default, which is good enough for our assertions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants