-
Notifications
You must be signed in to change notification settings - Fork 394
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
Params not accessible in SharedLibrary classes #478
Comments
We're hitting a similar issue that we believe has the same root cause. We're are trying to write a test that includes the pullRequest global variable form the pipeline-github-plugin. We are mocking it out with the following call binding.setVariable('pullRequest', new PullRequestMock()) This works as expected when executing the following test pipeline {
stages {
stage('test pullRequest global variable') {
steps {
script {
pullRequest.comment("foobar")
}
}
}
}
} And also works as expected from the first level of our library pipeline {
stages {
stage('test pullRequest global variable') {
steps {
script {
jenkinslibrary.commentOnPullRequest("foobar")
}
}
}
}
} Where there exists a def commentOnPullRequest(String comment) {
pullRequest.comment(comment)
} However, if we try to access that global variable inside another groovy class - for example def commentOnPullRequest(String comment) {
def prUtils = new com.jenkinslibrary.pullRequestUtils()
prUtils.comment(comment)
} def comment(String comment) {
pullRequest.comment(comment)
} The execution fails with the following error groovy.lang.MissingPropertyException: No such property: pullRequest for class: com.jenkinslibrary.pullRequestUtils
at app//groovy.lang.MetaClassImpl.invokeStaticMissingProperty(MetaClassImpl.java:1019)
at app//groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:2862)
at app//groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:3854) It looks like the global variable is not available inside the groovy classes, similar to params above. Mocking methods from plugins works as expected, just not global variables. This code runs fine in our actual jenkins pipelines, i.e. we can access the global pullRequest variable from inside the class. WorkaroundWe are currently working around issue by adding a simple method that returns the pullRequest object inside our class, and mocking that as part of the test def pullRequestDetails() {
return pullRequest
} and then in the test file helper.registerAllowedMethod('pullRequestDetails', [], { return new PullRequestMock() }) Which allows us to access the object |
@MichaelJKar does the above workaround work for you? Can this issue be closed? |
@nre-ableton We'd prefer not to use the workaround forever if possible. It's okay for this situation, but it requires you to set the same mock in two places if you want to use the |
Indeed, the work around is not a good solution long term, and could cause issues as it forces changes in actual code just to make the tests work. It is also something a developer would waste time debugging if they do not know it is an issue of the testing framework. |
On closer inspection, what if you pass the script context to the library? That is: Jenkinsfile: #!groovy
@Library('lib')
import LibClass
pipeline {
stages {
stage('Test stage') {
steps {
out = new LibClass(script: this).getX()
echo "Printing ${out}"
}
}
}
}
class LibClass {
Object script
def getX() {
return script.params.X
}
} |
This is issue is an interesting one. Based on @MichaelJKar reproduction steps I built a fix for this case. Sadly I do not know enough in order to say if this change can have some side effects in another (yet untested) cases. |
Jenkins and plugins versions report
Environment
What Operating System are you using (both controller, and any agents involved in the problem)?
Windows
Reproduction steps
Jenkinsfile:
Test Class:
The shared library
lib
only contains one fileLibClass.groovy
with the following content:Expected Results
Actual Results
Loading shared library lib with version master
groovy.lang.MissingPropertyException: No such property: params for class: LibClass
Anything else?
When replacing the content of
getX()
withreturn env.X
, the test runs successfully and the output matches the expected output given above.I don't know why this differentiation between
env
andparams
exists in the testing framework, since these two maps are essentially equivalent concepts in Jenkins itself. If theenv
map is available in a class within the shared library, thenparams
should also be available.Note: I already commented on this problem in #402, but since the problem is not 100% the same, I opened a new ticket.
The text was updated successfully, but these errors were encountered: