forked from v1v/jenkinslint-plugin
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from jenkinsci/groovy_system_exit
[JENKINS-38617] System exit when running system groovy.
- Loading branch information
Showing
4 changed files
with
182 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
src/main/java/org/jenkins/ci/plugins/jenkinslint/check/GroovySystemExitChecker.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package org.jenkins.ci.plugins.jenkinslint.check; | ||
|
||
import hudson.matrix.MatrixProject; | ||
import hudson.maven.MavenModuleSet; | ||
import hudson.model.Item; | ||
import hudson.model.Project; | ||
import hudson.tasks.Builder; | ||
import jenkins.model.Jenkins; | ||
import org.jenkins.ci.plugins.jenkinslint.model.AbstractCheck; | ||
|
||
import java.util.List; | ||
import java.util.logging.Level; | ||
|
||
/** | ||
* @author Victor Martinez | ||
*/ | ||
public class GroovySystemExitChecker extends AbstractCheck { | ||
|
||
public GroovySystemExitChecker() { | ||
super(); | ||
this.setDescription("System groovy scripts run in same JVM as Jenkins master, so there's no surprise that System.exit() kills your Jenkins master. " + | ||
"Throwing an exception is definitely better approach how to announce some problem in the script. Further details: " + | ||
"<a href=https://issues.jenkins-ci.org/browse/JENKINS-14023>JENKINS-14023</a>."); | ||
this.setSeverity("High"); | ||
} | ||
|
||
public boolean executeCheck(Item item) { | ||
boolean found = false; | ||
if (Jenkins.getInstance().pluginManager.getPlugin("groovy") != null) { | ||
|
||
if (Jenkins.getInstance().pluginManager.getPlugin("maven-plugin")!=null) { | ||
if (item instanceof MavenModuleSet) { | ||
found = isSystemExit(((MavenModuleSet) item).getPrebuilders()); | ||
} | ||
} | ||
if (item instanceof Project) { | ||
found = isSystemExit(((Project) item).getBuilders()); | ||
} | ||
if (item instanceof MatrixProject) { | ||
found = isSystemExit(((MatrixProject) item).getBuilders()); | ||
} | ||
|
||
} else { | ||
LOG.log(Level.INFO, "Groovy is not installed"); | ||
} | ||
return found; | ||
} | ||
|
||
private boolean isSystemExit (List<Builder> builders) { | ||
boolean status = false; | ||
if (builders != null && builders.size() > 0 ) { | ||
for (Builder builder : builders) { | ||
if (builder.getClass().getName().endsWith("SystemGroovy")) { | ||
try { | ||
Object scriptSource = builder.getClass().getMethod("getScriptSource",null).invoke(builder); | ||
if (scriptSource.getClass().getName().endsWith("StringScriptSource")) { | ||
Object command = scriptSource.getClass().getMethod("getCommand",null).invoke(scriptSource); | ||
if (command instanceof String) { | ||
// TODO: Parse to search for non comments, otherwise some false positives! | ||
status = (command != null && ((String) command).toLowerCase().contains("system.exit")); | ||
LOG.log(Level.FINE, "isSystemExit " + status); | ||
} | ||
} | ||
} catch (Exception e) { | ||
LOG.log(Level.WARNING, "Exception " + e.getMessage(), e.getCause()); | ||
status = false; | ||
} | ||
} | ||
} | ||
} | ||
return status; | ||
} | ||
|
||
} |
99 changes: 99 additions & 0 deletions
99
src/test/java/org/jenkins/ci/plugins/jenkinslint/check/GroovySystemExitCheckerTestCase.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
package org.jenkins.ci.plugins.jenkinslint.check; | ||
|
||
import hudson.matrix.MatrixProject; | ||
import hudson.maven.MavenModuleSet; | ||
import hudson.model.FreeStyleProject; | ||
import hudson.plugins.groovy.ScriptSource; | ||
import hudson.plugins.groovy.StringScriptSource; | ||
import org.junit.Rule; | ||
import org.junit.Test; | ||
import org.jvnet.hudson.test.JenkinsRule; | ||
|
||
import static org.junit.Assert.assertFalse; | ||
import static org.junit.Assert.assertTrue; | ||
|
||
/** | ||
* GroovySystemExitChecker Test Case. | ||
* | ||
* @author Victor Martinez | ||
*/ | ||
public class GroovySystemExitCheckerTestCase { | ||
private GroovySystemExitChecker checker = new GroovySystemExitChecker(); | ||
|
||
@Rule public JenkinsRule j = new JenkinsRule(); | ||
@Test public void testDefaultJob() throws Exception { | ||
FreeStyleProject project = j.createFreeStyleProject(); | ||
assertFalse(checker.executeCheck(project)); | ||
} | ||
@Test public void testEmptyJobName() throws Exception { | ||
FreeStyleProject project = j.createFreeStyleProject(""); | ||
assertFalse(checker.executeCheck(project)); | ||
} | ||
@Test public void testMavenJobName() throws Exception { | ||
MavenModuleSet project = j.createMavenProject(); | ||
assertFalse(checker.executeCheck(project)); | ||
} | ||
//@Issue("JENKINS-29444") | ||
@Test public void testMatrixProject() throws Exception { | ||
MatrixProject project = j.createMatrixProject(); | ||
assertFalse(checker.executeCheck(project)); | ||
} | ||
@Test public void testMatrixProjectWithSystemGroovy() throws Exception { | ||
MatrixProject project = j.createMatrixProject("WithoutSystem"); | ||
project.getBuildersList().add(new hudson.plugins.groovy.SystemGroovy(new StringScriptSource("println 'hi'"),null,null)); | ||
assertFalse(checker.executeCheck(project)); | ||
project.delete(); | ||
project = j.createMatrixProject("WithSystem"); | ||
project.getBuildersList().add(new hudson.plugins.groovy.SystemGroovy(new StringScriptSource("System.exit(0)"),null,null)); | ||
project.save(); | ||
assertTrue(checker.executeCheck(project)); | ||
} | ||
@Test public void testJobWithSystemGroovy() throws Exception { | ||
FreeStyleProject project = j.createFreeStyleProject("WithoutSystem"); | ||
project.getBuildersList().add(new hudson.plugins.groovy.SystemGroovy(new StringScriptSource("println 'hi'"),null,null)); | ||
assertFalse(checker.executeCheck(project)); | ||
project.delete(); | ||
project = j.createFreeStyleProject("WithSystem"); | ||
project.getBuildersList().add(new hudson.plugins.groovy.SystemGroovy(new StringScriptSource("System.exit(0)"),null,null)); | ||
project.save(); | ||
assertTrue(checker.executeCheck(project)); | ||
} | ||
@Test public void testControlComment() throws Exception { | ||
FreeStyleProject project = j.createFreeStyleProject(); | ||
assertFalse(checker.isIgnored(project.getDescription())); | ||
project.setDescription("#lint:ignore:" + checker.getClass().getSimpleName()); | ||
assertTrue(checker.isIgnored(project.getDescription())); | ||
project.delete(); | ||
MavenModuleSet mavenProject = j.createMavenProject(); | ||
assertFalse(checker.isIgnored(mavenProject.getDescription())); | ||
mavenProject.setDescription("#lint:ignore:" + checker.getClass().getSimpleName()); | ||
assertTrue(checker.isIgnored(mavenProject.getDescription())); | ||
} | ||
//@Issue("JENKINS-29427") | ||
@Test public void testAnotherBuilders() throws Exception { | ||
FreeStyleProject project = j.createFreeStyleProject("MsBuildBuilder"); | ||
project.getBuildersList().add(new hudson.plugins.msbuild.MsBuildBuilder("", "", "", true, true, true)); | ||
assertFalse(checker.executeCheck(project)); | ||
project.delete(); | ||
project = j.createFreeStyleProject("Ant"); | ||
project.getBuildersList().add(new hudson.tasks.Ant("","","","","")); | ||
assertFalse(checker.executeCheck(project)); | ||
project.delete(); | ||
} | ||
//@Issue("JENKINS-38616") | ||
@Test public void testMavenModuleJob() throws Exception { | ||
MavenModuleSet project = j.createMavenProject(); | ||
assertFalse(checker.executeCheck(project)); | ||
} | ||
//@Issue("JENKINS-38616") | ||
@Test public void testMavenModuleJobbWithGroovy() throws Exception { | ||
MavenModuleSet project = j.createMavenProject("WithoutSystem"); | ||
project.getPrebuilders().add(new hudson.plugins.groovy.SystemGroovy(new StringScriptSource("println 'hi'"),null,null)); | ||
project.save(); | ||
assertFalse(checker.executeCheck(project)); | ||
project.delete(); | ||
project = j.createMavenProject("WithSystem"); | ||
project.getPrebuilders().add(new hudson.plugins.groovy.SystemGroovy(new StringScriptSource("System.exit(0)"),null,null)); | ||
assertTrue(checker.executeCheck(project)); | ||
} | ||
} |