/** * Same as {@link #record(String, Level)} but calls {@link Class#getName()} for you first. */ public LoggerRule record(Class<?> clazz, Level level) { return record(clazz.getName(), level); }
/** * Same as {@link #record(Logger, Level)} but calls {@link Logger#getLogger(String)} for you first. */ public LoggerRule record(String name, Level level) { return record(Logger.getLogger(name), level); }
/** * Same as {@link #record(String, Level)} but calls {@link Class#getPackage()} and getName() for you first. */ public LoggerRule recordPackage(Class<?> clazz, Level level) { return record(clazz.getPackage().getName(), level); }
@Test public void listener() throws Exception { logging.record( CpsFlowExecution.class, Level.WARNING).capture(200); String script = "node { \n" // + " echo \"hello\"\n" // + " " + "}"; WorkflowJob j = r.createProject( WorkflowJob.class, "listener" ); j.setDefinition( new CpsFlowDefinition( script, true ) ); Run run = r.buildAndAssertSuccess( j ); List<String> logs = logging.getMessages(); long found = logs.stream().filter( s -> s.contains( LOG_MESSAGE ) ).count(); Assert.assertTrue( "cannot find listener exception message", found > 0 ); }
@Override public void evaluate() throws Throwable { logger.record(CpsFlowExecution.TIMING_LOGGER, Level.FINE).capture(100); WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition("semaphore 'wait'", true)); WorkflowRun b = p.scheduleBuild2(0).waitForStart(); SemaphoreStep.waitForStart("wait/1", b); } });
@Issue("JENKINS-46088") @Test public void matcherTypeAssignment() throws Exception { logging.record(CpsTransformer.class, Level.FINEST); WorkflowJob p = jenkins.jenkins.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition("@NonCPS\n" + "def nonCPSMatcherMethod(String x) {\n" + " java.util.regex.Matcher m = x =~ /bla/\n" + " return m.matches()\n" + "}\n" + "def cpsMatcherMethod(String x) {\n" + " java.util.regex.Matcher m = x =~ /bla/\n" + " return m.matches()\n" + "}\n" + "assert !nonCPSMatcherMethod('foo')\n" + "assert !cpsMatcherMethod('foo')\n", true)); jenkins.buildAndAssertSuccess(p); }
@Test public void stop() throws Exception { WorkflowJob p = r.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition("slowBlock {semaphore 'wait'}", true)); logging.record(CpsStepContext.class, Level.WARNING).capture(100);
@Issue("SECURITY-567") @Test public void methodPointers() throws Exception { logging.record(CpsTransformer.class, Level.FINEST); WorkflowJob job = jenkins.jenkins.createProject(WorkflowJob.class, "p"); job.setDefinition(new CpsFlowDefinition("println((Jenkins.&getInstance)())", true)); WorkflowRun b = job.scheduleBuild2(0).get(); jenkins.assertBuildStatus(Result.FAILURE, b); jenkins.assertLogContains("org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use staticMethod jenkins.model.Jenkins getInstance", b); }
@Issue("JENKINS-46088") @Test public void rhsOfDeclarationSandboxedInCPS() throws Exception { logging.record(CpsTransformer.class, Level.FINEST); WorkflowJob job = jenkins.jenkins.createProject(WorkflowJob.class, "p"); job.setDefinition(new CpsFlowDefinition("jenkins.model.Jenkins x = jenkins.model.Jenkins.getInstance()\n", true)); WorkflowRun b = job.scheduleBuild2(0).get(); jenkins.assertBuildStatus(Result.FAILURE, b); jenkins.assertLogContains("org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use staticMethod jenkins.model.Jenkins getInstance", b); }
@Issue("JENKINS-46088") @Test public void rhsOfDeclarationTransformedInNonCPS() throws Exception { logging.record(CpsTransformer.class, Level.FINEST); WorkflowJob job = jenkins.jenkins.createProject(WorkflowJob.class, "p"); job.setDefinition(new CpsFlowDefinition("@NonCPS\n" + "def willFail() {\n" + " jenkins.model.Jenkins x = jenkins.model.Jenkins.getInstance()\n" + "}\n" + "willFail()\n", true)); WorkflowRun b = job.scheduleBuild2(0).get(); jenkins.assertBuildStatus(Result.FAILURE, b); jenkins.assertLogContains("org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use staticMethod jenkins.model.Jenkins getInstance", b); }
@Test public void staticInitializerSandbox() throws Exception { logging.record(CpsTransformer.class, Level.FINEST); WorkflowJob job = jenkins.jenkins.createProject(WorkflowJob.class, "p"); job.setDefinition(new CpsFlowDefinition("class X {static {Jenkins.instance.systemMessage = 'pwned'}}; new X()", true)); WorkflowRun b = job.scheduleBuild2(0).get(); assertNull(jenkins.jenkins.getSystemMessage()); jenkins.assertBuildStatus(Result.FAILURE, b); jenkins.assertLogContains("org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use staticMethod jenkins.model.Jenkins getInstance", b); }
@Issue("SECURITY-551") @Test public void constructorSandbox() throws Exception { logging.record(CpsTransformer.class, Level.FINEST); WorkflowJob job = jenkins.jenkins.createProject(WorkflowJob.class, "p"); job.setDefinition(new CpsFlowDefinition("class X {X() {Jenkins.instance.systemMessage = 'pwned'}}; new X()", true)); WorkflowRun b = job.scheduleBuild2(0).get(); assertNull(jenkins.jenkins.getSystemMessage()); jenkins.assertBuildStatus(Result.FAILURE, b); jenkins.assertLogContains("org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use staticMethod jenkins.model.Jenkins getInstance", b); }
@Issue("SECURITY-551") @Test public void initializerSandbox() throws Exception { logging.record(CpsTransformer.class, Level.FINEST); WorkflowJob job = jenkins.jenkins.createProject(WorkflowJob.class, "p"); job.setDefinition(new CpsFlowDefinition("class X {{Jenkins.instance.systemMessage = 'pwned'}}; new X()", true)); WorkflowRun b = job.scheduleBuild2(0).get(); assertNull(jenkins.jenkins.getSystemMessage()); jenkins.assertBuildStatus(Result.FAILURE, b); jenkins.assertLogContains("org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use staticMethod jenkins.model.Jenkins getInstance", b); }
@Issue("SECURITY-551") @Test public void fieldInitializerSandbox() throws Exception { logging.record(CpsTransformer.class, Level.FINEST); WorkflowJob job = jenkins.jenkins.createProject(WorkflowJob.class, "p"); job.setDefinition(new CpsFlowDefinition("class X {def x = {Jenkins.instance.systemMessage = 'pwned'}()}; new X()", true)); WorkflowRun b = job.scheduleBuild2(0).get(); assertNull(jenkins.jenkins.getSystemMessage()); jenkins.assertBuildStatus(Result.FAILURE, b); jenkins.assertLogContains("org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use staticMethod jenkins.model.Jenkins getInstance", b); }
@Test public void traitsSandbox() throws Exception { logging.record(CpsTransformer.class, Level.FINEST); WorkflowJob job = jenkins.jenkins.createProject(WorkflowJob.class, "p"); job.setDefinition(new CpsFlowDefinition("trait T {void m() {Jenkins.instance.systemMessage = 'pwned'}}; class X implements T {}; new X().m()", true)); WorkflowRun b = job.scheduleBuild2(0).get(); assertNull(jenkins.jenkins.getSystemMessage()); jenkins.assertBuildStatus(Result.FAILURE, b); /* TODO instead it fails in some cryptic spot while trying to translate the body of the trait jenkins.assertLogContains("org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use staticMethod jenkins.model.Jenkins getInstance", b); */ job.setDefinition(new CpsFlowDefinition("trait T {void m() {Jenkins.instance.systemMessage = 'pwned'}}; T t = new TreeSet() as T; t.m()", true)); b = job.scheduleBuild2(0).get(); assertNull(jenkins.jenkins.getSystemMessage()); jenkins.assertBuildStatus(Result.FAILURE, b); // TODO this one fails with a NullPointerException }
@Issue("SECURITY-566") @Test public void typeCoercion() throws Exception { logging.record(CpsTransformer.class, Level.FINEST); WorkflowJob job = jenkins.jenkins.createProject(WorkflowJob.class, "p"); job.setDefinition(new CpsFlowDefinition("interface I {Object getInstance()}; println((Jenkins as I).instance)", true)); WorkflowRun b = job.scheduleBuild2(0).get(); assertNull(jenkins.jenkins.getSystemMessage()); jenkins.assertBuildStatus(Result.FAILURE, b); jenkins.assertLogContains("org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use staticMethod jenkins.model.Jenkins getInstance", b); // Not really the same but just checking: job.setDefinition(new CpsFlowDefinition("interface I {Object getInstance()}; I i = {Jenkins.instance}; println(i.instance)", true)); b = job.scheduleBuild2(0).get(); assertNull(jenkins.jenkins.getSystemMessage()); jenkins.assertBuildStatus(Result.FAILURE, b); jenkins.assertLogContains("org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use staticMethod jenkins.model.Jenkins getInstance", b); }
@Override public void evaluate() throws Throwable { logger.record(CpsFlowExecution.class, Level.WARNING).capture(100); DumbSlave s = story.j.createOnlineSlave(); s.setLabelString("remote quick");
@Issue({"JENKINS-42563", "SECURITY-582"}) @Test public void superCallsSandboxed() throws Exception { logging.record(CpsTransformer.class, Level.FINEST); WorkflowJob job = jenkins.jenkins.createProject(WorkflowJob.class, "p"); job.setDefinition(new CpsFlowDefinition("class X extends groovy.json.JsonSlurper {def parse(url) {super.parse(new URL(url))}}; echo(/got ${new X().parse(\"${JENKINS_URL}api/json\")}/)", true)); WorkflowRun r = jenkins.assertBuildStatus(Result.FAILURE, job.scheduleBuild2(0).get()); jenkins.assertLogContains("org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.json.JsonSlurper parse java.net.URL", r); job.setDefinition(new CpsFlowDefinition("class X extends groovy.json.JsonSlurper {def m(url) {super.parse(new URL(url))}}; echo(/got ${new X().m(\"${JENKINS_URL}api/json\")}/)", true)); r = jenkins.assertBuildStatus(Result.FAILURE, job.scheduleBuild2(0).get()); jenkins.assertLogContains("org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.json.JsonSlurper parse java.net.URL", r); job.setDefinition(new CpsFlowDefinition("class X extends File {X(String f) {super(f)}}; echo(/got ${new X('x')}/)", true)); r = jenkins.assertBuildStatus(Result.FAILURE, job.scheduleBuild2(0).get()); jenkins.assertLogContains("org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use new java.io.File java.lang.String", r); }
@Issue("SECURITY-580") @Test public void positionalConstructors() throws Exception { logging.record(CpsTransformer.class, Level.FINEST); WorkflowJob p = jenkins.jenkins.createProject(WorkflowJob.class, "p"); // Control cases: p.setDefinition(new CpsFlowDefinition("def u = ['http://nowhere.net/'] as URL; echo(/$u/)", true)); jenkins.buildAndAssertSuccess(p); p.setDefinition(new CpsFlowDefinition("URL u = ['http://nowhere.net/']; echo(/$u/)", true)); jenkins.buildAndAssertSuccess(p); p.setDefinition(new CpsFlowDefinition("def f = new File('/tmp'); echo(/$f/)", true)); jenkins.assertLogContains("org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use new java.io.File java.lang.String", jenkins.assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0))); // Test cases: p.setDefinition(new CpsFlowDefinition("def f = ['/tmp'] as File; echo(/$f/)", true)); jenkins.assertLogContains("org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use new java.io.File java.lang.String", jenkins.assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0))); p.setDefinition(new CpsFlowDefinition("File f = ['/tmp']; echo(/$f/)", true)); jenkins.assertLogContains("org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use new java.io.File java.lang.String", jenkins.assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0))); }