diff --git a/pom.xml b/pom.xml index 0f38a12f..1834c8b8 100644 --- a/pom.xml +++ b/pom.xml @@ -22,6 +22,7 @@ ${jenkins.baseline}.3 jenkinsci/${project.artifactId}-plugin true + false diff --git a/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/BindingStepTest.java b/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/BindingStepTest.java index 748f2393..f75db561 100644 --- a/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/BindingStepTest.java +++ b/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/BindingStepTest.java @@ -51,9 +51,9 @@ import java.nio.charset.StandardCharsets; import java.nio.file.NoSuchFileException; import java.util.Collections; +import java.util.Objects; import java.util.Set; import java.util.TreeSet; -import java.util.stream.Collectors; import jenkins.security.QueueItemAuthenticator; import jenkins.security.QueueItemAuthenticatorConfiguration; @@ -86,27 +86,31 @@ import org.jenkinsci.plugins.workflow.steps.StepExecution; import org.jenkinsci.plugins.workflow.steps.SynchronousStepExecution; import org.jenkinsci.plugins.workflow.test.steps.SemaphoreStep; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.jvnet.hudson.test.BuildWatcher; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; -import org.jvnet.hudson.test.JenkinsSessionRule; import org.jvnet.hudson.test.TestExtension; +import org.jvnet.hudson.test.junit.jupiter.BuildWatcherExtension; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; import org.kohsuke.stapler.DataBoundConstructor; import org.springframework.security.core.Authentication; -public class BindingStepTest { +class BindingStepTest { - @ClassRule public static BuildWatcher buildWatcher = new BuildWatcher(); - @Rule public JenkinsSessionRule rr = new JenkinsSessionRule(); + @SuppressWarnings("unused") + @RegisterExtension + private static final BuildWatcherExtension BUILD_WATCHER = new BuildWatcherExtension(); + @RegisterExtension + private final JenkinsSessionExtension extension = new JenkinsSessionExtension(); - @SuppressWarnings("rawtypes") - @Test public void configRoundTrip() throws Throwable { - rr.then(r -> { + @Test + void configRoundTrip() throws Throwable { + extension.then(r -> { UsernamePasswordCredentialsImpl c = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, "creds", "sample", "bob", "s3cr3t"); CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), c); BindingStep s = new StepConfigTester(r).configRoundTrip(new BindingStep(Collections.singletonList(new UsernamePasswordBinding("userpass", "creds")))); @@ -117,14 +121,27 @@ public class BindingStepTest { "withCredentials([[$class: 'ZipFileBinding', credentialsId: 'secrets', variable: 'file']]) {\n // some block\n}"); }); } + public static class ZipStep extends Step { - @DataBoundConstructor public ZipStep() {} - @Override public StepExecution start(StepContext context) throws Exception { + + @DataBoundConstructor + public ZipStep() {} + + @Override + public StepExecution start(StepContext context) throws Exception { return new Execution(context); } - @TestExtension("configRoundTrip") public static class DescriptorImpl extends StepDescriptor { - @Override public String getFunctionName() {return "zip";} - @Override public Set> getRequiredContext() { + + @TestExtension("configRoundTrip") + public static class DescriptorImpl extends StepDescriptor { + + @Override + public String getFunctionName() { + return "zip"; + } + + @Override + public Set> getRequiredContext() { return Set.of(); } } @@ -132,15 +149,20 @@ static class Execution extends SynchronousStepExecution { Execution(StepContext context) { super(context); } - @Override protected Void run() {return null;} + + @Override + protected Void run() { + return null; + } } } - @Test public void basics() throws Throwable { + @Test + void basics() throws Throwable { final String credentialsId = "creds"; final String username = "bob"; final String password = "s$$cr3t"; - rr.then(r -> { + extension.then(r -> { UsernamePasswordCredentialsImpl c = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, credentialsId, "sample", username, password); CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), c); WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p"); @@ -159,7 +181,7 @@ static class Execution extends SynchronousStepExecution { SemaphoreStep.waitForStart("basics/1", b); r.assertLogContains(Functions.isWindows() ? "Masking supported pattern matches of %PASSWORD%" : "Masking supported pattern matches of $PASSWORD", b); }); - rr.then(r -> { + extension.then(r -> { WorkflowJob p = r.jenkins.getItemByFullName("p", WorkflowJob.class); assertNotNull(p); WorkflowRun b = p.getBuildByNumber(1); @@ -178,11 +200,11 @@ static class Execution extends SynchronousStepExecution { @Issue("JENKINS-42999") @Test - public void limitedRequiredContext() throws Throwable { + void limitedRequiredContext() throws Throwable { final String credentialsId = "creds"; final String username = "bob"; final String password = "s3cr3t"; - rr.then(r -> { + extension.then(r -> { UsernamePasswordCredentialsImpl c = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, credentialsId, "sample", username, password); CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), c); WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p"); @@ -194,7 +216,7 @@ public void limitedRequiredContext() throws Throwable { WorkflowRun b = p.scheduleBuild2(0).waitForStart(); SemaphoreStep.waitForStart("basics/1", b); }); - rr.then(r -> { + extension.then(r -> { WorkflowJob p = r.jenkins.getItemByFullName("p", WorkflowJob.class); assertNotNull(p); WorkflowRun b = p.getBuildByNumber(1); @@ -210,11 +232,11 @@ public void limitedRequiredContext() throws Throwable { @Issue("JENKINS-42999") @Test - public void widerRequiredContext() throws Throwable { + void widerRequiredContext() throws Throwable { final String credentialsId = "creds"; final String credsFile = "credsFile"; final String credsContent = "s3cr3t"; - rr.then(r -> { + extension.then(r -> { FileCredentialsImpl c = new FileCredentialsImpl(CredentialsScope.GLOBAL, credentialsId, "sample", credsFile, SecretBytes.fromBytes(credsContent.getBytes())); CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), c); WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p"); @@ -229,16 +251,18 @@ public void widerRequiredContext() throws Throwable { }); } - @Test public void incorrectType() throws Throwable { - rr.then(r -> { + @Test + void incorrectType() throws Throwable { + extension.then(r -> { StringCredentialsImpl c = new StringCredentialsImpl(CredentialsScope.GLOBAL, "creds", "sample", Secret.fromString("s3cr3t")); CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), c); WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p"); - p.setDefinition(new CpsFlowDefinition("" - + "node {\n" - + " withCredentials([usernamePassword(usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD', credentialsId: 'creds')]) {\n" - + " }\n" - + "}", true)); + p.setDefinition(new CpsFlowDefinition(""" + \ + node { + withCredentials([usernamePassword(usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD', credentialsId: 'creds')]) { + } + }""", true)); WorkflowRun b = r.assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0).get()); // make sure error message contains information about the actual type and the expected type @@ -249,24 +273,26 @@ public void widerRequiredContext() throws Throwable { }); } - @Test public void cleanupAfterRestart() throws Throwable { + @Test + void cleanupAfterRestart() throws Throwable { final String secret = "s3cr3t"; - rr.then(r -> { + extension.then(r -> { FileCredentialsImpl c = new FileCredentialsImpl(CredentialsScope.GLOBAL, "creds", "sample", "secret.txt", SecretBytes.fromBytes(secret.getBytes())); CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), c); r.createSlave("myslave", null, null); WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p"); - p.setDefinition(new CpsFlowDefinition("" - + "node('myslave') {" - + " withCredentials([file(variable: 'SECRET', credentialsId: 'creds')]) {\n" - + " semaphore 'cleanupAfterRestart'\n" - + " if (isUnix()) {sh 'cp \"$SECRET\" key'} else {bat 'copy \"%SECRET%\" key'}\n" - + " }\n" - + "}", true)); + p.setDefinition(new CpsFlowDefinition(""" + \ + node('myslave') {\ + withCredentials([file(variable: 'SECRET', credentialsId: 'creds')]) { + semaphore 'cleanupAfterRestart' + if (isUnix()) {sh 'cp "$SECRET" key'} else {bat 'copy "%SECRET%" key'} + } + }""", true)); WorkflowRun b = p.scheduleBuild2(0).waitForStart(); SemaphoreStep.waitForStart("cleanupAfterRestart/1", b); }); - rr.then(r -> { + extension.then(r -> { WorkflowJob p = r.jenkins.getItemByFullName("p", WorkflowJob.class); assertNotNull(p); WorkflowRun b = p.getBuildByNumber(1); @@ -287,8 +313,9 @@ public void widerRequiredContext() throws Throwable { } @Issue("JENKINS-27389") - @Test public void grabEnv() throws Throwable { - rr.then(r -> { + @Test + void grabEnv() throws Throwable { + extension.then(r -> { String credentialsId = "creds"; String secret = "s3cr3t"; CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), new StringCredentialsImpl(CredentialsScope.GLOBAL, credentialsId, "sample", Secret.fromString(secret))); @@ -309,8 +336,9 @@ public void widerRequiredContext() throws Throwable { } @Issue("JENKINS-27486") - @Test public void masking() throws Throwable { - rr.then(r -> { + @Test + void masking() throws Throwable { + extension.then(r -> { String credentialsId = "creds"; String secret = "s3cr3t"; CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), new StringCredentialsImpl(CredentialsScope.GLOBAL, credentialsId, "sample", Secret.fromString(secret))); @@ -329,8 +357,9 @@ public void widerRequiredContext() throws Throwable { } @Issue("JENKINS-72412") - @Test public void maskingOfOneCharSecretShouldNotMangleOutput() throws Throwable { - rr.then(r -> { + @Test + void maskingOfOneCharSecretShouldNotMangleOutput() throws Throwable { + extension.then(r -> { String credentialsId = "creds"; String secret = "a"; CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), new StringCredentialsImpl(CredentialsScope.GLOBAL, credentialsId, "sample", Secret.fromString(secret))); @@ -349,8 +378,8 @@ public void widerRequiredContext() throws Throwable { @Issue("JENKINS-30326") @Test - public void testGlobalBindingWithAuthorization() throws Throwable { - rr.then(r -> { + void testGlobalBindingWithAuthorization() throws Throwable { + extension.then(r -> { // configure security r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); r.jenkins.setAuthorizationStrategy(new FullControlOnceLoggedInAuthorizationStrategy()); @@ -379,8 +408,11 @@ public void testGlobalBindingWithAuthorization() throws Throwable { r.assertLogContains("Running as dummy", b); }); } + private static final class DummyAuthenticator extends QueueItemAuthenticator { - @Override public Authentication authenticate2(Queue.Task task) { + + @Override + public Authentication authenticate2(Queue.Task task) { if (task instanceof WorkflowJob) { return User.getById("dummy", true).impersonate2(); } else { @@ -391,8 +423,8 @@ private static final class DummyAuthenticator extends QueueItemAuthenticator { @Issue("JENKINS-38831") @Test - public void testTrackingOfCredential() throws Throwable { - rr.then(r -> { + void testTrackingOfCredential() throws Throwable { + extension.then(r -> { String credentialsId = "creds"; String secret = "s3cr3t"; StringCredentialsImpl credentials = new StringCredentialsImpl(CredentialsScope.GLOBAL, credentialsId, "sample", Secret.fromString(secret)); @@ -424,8 +456,9 @@ public void testTrackingOfCredential() throws Throwable { } @Issue("JENKINS-41760") - @Test public void emptyOrBlankCreds() throws Throwable { - rr.then(r -> { + @Test + void emptyOrBlankCreds() throws Throwable { + extension.then(r -> { WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition("node {withCredentials([]) {echo 'normal output'}}", true)); r.assertLogContains("normal output", r.buildAndAssertSuccess(p)); @@ -437,8 +470,8 @@ public void testTrackingOfCredential() throws Throwable { @Issue("JENKINS-64631") @Test - public void usernameUnmaskedInStepArguments() throws Throwable { - rr.then(r -> { + void usernameUnmaskedInStepArguments() throws Throwable { + extension.then(r -> { String credentialsId = "my-credentials"; String username = "alice"; // UsernamePasswordCredentialsImpl.isUsernameSecret defaults to false for new credentials. @@ -459,8 +492,9 @@ public void usernameUnmaskedInStepArguments() throws Throwable { } @Issue("https://github.com/jenkinsci/credentials-plugin/pull/293") - @Test public void forRun() throws Throwable { - rr.then(r -> { + @Test + void forRun() throws Throwable { + extension.then(r -> { CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), new SpecialCredentials(CredentialsScope.GLOBAL, "test", null)); WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition("withCredentials([string(variable: 'SECRET', credentialsId: 'test')]) {echo(/got: ${SECRET.toUpperCase()}/)}", true)); @@ -469,8 +503,9 @@ public void usernameUnmaskedInStepArguments() throws Throwable { } @Issue("SECURITY-3499") - @Test public void maskingExceptionInError() throws Throwable { - rr.then(r -> { + @Test + void maskingExceptionInError() throws Throwable { + extension.then(r -> { CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), new StringCredentialsImpl(CredentialsScope.GLOBAL, "creds", "sample", Secret.fromString("s3cr3t"))); var p = r.jenkins.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition( @@ -487,8 +522,9 @@ public void usernameUnmaskedInStepArguments() throws Throwable { } @Issue("SECURITY-3499") - @Test public void maskingExceptionInNestedError() throws Throwable { - rr.then(r -> { + @Test + void maskingExceptionInNestedError() throws Throwable { + extension.then(r -> { CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), new StringCredentialsImpl(CredentialsScope.GLOBAL, "creds", "sample", Secret.fromString("s3cr3t"))); var p = r.jenkins.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition( @@ -511,8 +547,9 @@ public void usernameUnmaskedInStepArguments() throws Throwable { } @Issue("SECURITY-3499") - @Test public void maskingExceptionInSuppressedError() throws Throwable { - rr.then(r -> { + @Test + void maskingExceptionInSuppressedError() throws Throwable { + extension.then(r -> { CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), new StringCredentialsImpl(CredentialsScope.GLOBAL, "creds", "sample", Secret.fromString("s3cr3t"))); var p = r.jenkins.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition( @@ -532,8 +569,9 @@ public void usernameUnmaskedInStepArguments() throws Throwable { } @Issue("SECURITY-3499") - @Test public void maskingExceptionForIncorrectArgs() throws Throwable { - rr.then(r -> { + @Test + void maskingExceptionForIncorrectArgs() throws Throwable { + extension.then(r -> { CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), new StringCredentialsImpl(CredentialsScope.GLOBAL, "creds", "sample", Secret.fromString("s3cr3t"))); var p = r.jenkins.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition( @@ -551,8 +589,9 @@ public void usernameUnmaskedInStepArguments() throws Throwable { } @Issue("JENKINS-75914") - @Test public void emptyOrBlankCredsOnExceptions() throws Throwable { - rr.then(r -> { + @Test + void emptyOrBlankCredsOnExceptions() throws Throwable { + extension.then(r -> { CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), new StringCredentialsImpl(CredentialsScope.GLOBAL, "creds", "sample", Secret.fromString(""))); var p = r.jenkins.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition( @@ -570,26 +609,31 @@ public void usernameUnmaskedInStepArguments() throws Throwable { private void assertErrorActionsDoNotContainString(WorkflowRun b, String needle) { var errorActionStackTraces = new DepthFirstScanner().allNodes(b.getExecution()).stream() .map(n -> n.getPersistentAction(ErrorAction.class)) - .filter(ea -> ea != null) - .map(ea -> ea.getError()) + .filter(Objects::nonNull) + .map(ErrorAction::getError) .map(t -> { var writer = new StringWriter(); t.printStackTrace(new PrintWriter(writer)); return writer.toString(); }) - .collect(Collectors.toList()); + .toList(); assertThat(errorActionStackTraces, not(hasItem(containsString(needle)))); } private static final class SpecialCredentials extends BaseStandardCredentials implements StringCredentials { private Run build; + SpecialCredentials(CredentialsScope scope, String id, String description) { super(scope, id, description); } - @Override public Secret getSecret() { + + @Override + public Secret getSecret() { return Secret.fromString(build != null ? build.getExternalizableId() : "unknown"); } - @Override public Credentials forRun(Run context) { + + @Override + public Credentials forRun(Run context) { SpecialCredentials clone = new SpecialCredentials(getScope(), getId(), getDescription()); clone.build = context; return clone; @@ -601,6 +645,7 @@ private static Set grep(File dir, String text) throws IOException { grep(dir, text, "", matches); return matches; } + private static void grep(File dir, String text, String prefix, Set matches) throws IOException { File[] kids = dir.listFiles(); if (kids == null) { diff --git a/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/BuildWrapperOrderCredentialsBindingTest.java b/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/BuildWrapperOrderCredentialsBindingTest.java index 7fa780f0..6d357e1e 100644 --- a/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/BuildWrapperOrderCredentialsBindingTest.java +++ b/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/BuildWrapperOrderCredentialsBindingTest.java @@ -43,32 +43,41 @@ import hudson.util.Secret; import net.sf.json.JSONObject; import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.kohsuke.stapler.StaplerRequest2; import java.io.IOException; import java.util.Collections; import java.util.Map; -public class BuildWrapperOrderCredentialsBindingTest { +@WithJenkins +class BuildWrapperOrderCredentialsBindingTest { + + private JenkinsRule r; - @Rule public JenkinsRule r = new JenkinsRule(); + private static final String CREDENTIALS_ID = "creds_1"; + private static final String PASSWORD = "p4ss"; + private static final String BINDING_KEY = "PASS_1"; - static String credentialsId = "creds_1"; - static String password = "p4ss"; - static String bindingKey = "PASS_1"; + @BeforeEach + void beforeEach(JenkinsRule rule) { + r = rule; + } @Issue("JENKINS-37871") - @Test public void secretBuildWrapperRunsBeforeNormalWrapper() throws Exception { - StringCredentialsImpl firstCreds = new StringCredentialsImpl(CredentialsScope.GLOBAL, credentialsId, "sample1", Secret.fromString(password)); + @Test + void secretBuildWrapperRunsBeforeNormalWrapper() throws Exception { + StringCredentialsImpl firstCreds = new StringCredentialsImpl(CredentialsScope.GLOBAL, CREDENTIALS_ID, "sample1", Secret.fromString(PASSWORD)); CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), firstCreds); - SecretBuildWrapper wrapper = new SecretBuildWrapper(Collections.singletonList(new StringBinding(bindingKey, credentialsId))); + SecretBuildWrapper wrapper = new SecretBuildWrapper(Collections.singletonList(new StringBinding(BINDING_KEY, CREDENTIALS_ID))); FreeStyleProject f = r.createFreeStyleProject("buildWrapperOrder"); @@ -92,7 +101,7 @@ public Environment setUp(AbstractBuild build, Launcher launcher, BuildListener l // Lookup secret provided by SecretBuildWrapper. // This only works if this BuildWrapper is executed AFTER the SecretBuildWrapper so the binding is already done. for (Map.Entry entry : env.entrySet()) { - if (entry.getKey().equals(bindingKey) && entry.getValue().equals(password)) { + if (entry.getKey().equals(BINDING_KEY) && entry.getValue().equals(PASSWORD)) { listener.getLogger().format("Secret found!"); break; } diff --git a/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/CertificateMultiBindingTest.java b/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/CertificateMultiBindingTest.java index c6d41227..0df86485 100644 --- a/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/CertificateMultiBindingTest.java +++ b/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/CertificateMultiBindingTest.java @@ -29,8 +29,8 @@ import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import java.io.File; import java.io.IOException; @@ -46,12 +46,11 @@ import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.jvnet.hudson.test.BuildWatcher; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; + import org.jvnet.hudson.test.JenkinsRule; import com.cloudbees.plugins.credentials.CredentialsProvider; @@ -68,24 +67,28 @@ import hudson.model.Item; import hudson.tasks.BatchFile; import hudson.tasks.Shell; +import org.jvnet.hudson.test.junit.jupiter.BuildWatcherExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; -public class CertificateMultiBindingTest { +@WithJenkins +class CertificateMultiBindingTest { - @ClassRule - public static BuildWatcher buildWatcher = new BuildWatcher(); + @SuppressWarnings("unused") + @RegisterExtension + private static final BuildWatcherExtension BUILD_WATCHER = new BuildWatcherExtension(); - @Rule - public JenkinsRule r = new JenkinsRule(); + private JenkinsRule r; - @Rule - public TemporaryFolder tmp = new TemporaryFolder(); + @TempDir + private File tmp; - File certificate; + private File certificate; - @Before - public void setUp() throws IOException { + @BeforeEach + void beforeEach(JenkinsRule rule) throws Exception { + r = rule; /* do the dance to get a simple zip file into jenkins */ - certificate = tmp.newFile("a.certificate"); + certificate = newFile(tmp, "a.certificate"); final URL resource = this.getClass().getResource("certificate.p12"); assertThat(resource, is(not(nullValue()))); FileUtils.copyURLToFile(resource, certificate); @@ -93,8 +96,8 @@ public void setUp() throws IOException { // TODO configRoundtrip to test form, null hygiene on @DataBoundSetter - @Test - public void basics() throws Exception { + @Test + void basics() throws Exception { String alias = "androiddebugkey"; String password = "android"; StandardCertificateCredentials c = new CertificateCredentialsImpl(CredentialsScope.GLOBAL, null, alias, @@ -108,22 +111,24 @@ public void basics() throws Exception { .> singletonList(binding))); if (Functions.isWindows()) { p.getBuildersList().add(new BatchFile( - "echo | set /p=\"%alias%/%password%/\" > secrets.txt\r\n" - + "IF EXIST \"%keystore%\" (\r\n" - + "echo | set /p=\"exists\" >> secrets.txt\r\n" - + ") ELSE (\r\n" - + "echo | set /p=\"missing\" >> secrets.txt\r\n" - + ")\r\n" - + "exit 0")); + """ + echo | set /p="%alias%/%password%/" > secrets.txt\r + IF EXIST "%keystore%" (\r + echo | set /p="exists" >> secrets.txt\r + ) ELSE (\r + echo | set /p="missing" >> secrets.txt\r + )\r + exit 0""")); } else { p.getBuildersList().add(new Shell( - "printf $alias/$password/ > secrets.txt\n" - + "if [ -f \"$keystore\" ]\n" - + "then\n" - + "printf exists >> secrets.txt\n" - + "else\n" - + "printf missing >> secrets.txt\n" - + "fi")); + """ + printf $alias/$password/ > secrets.txt + if [ -f "$keystore" ] + then + printf exists >> secrets.txt + else + printf missing >> secrets.txt + fi""")); } r.configRoundtrip((Item) p); SecretBuildWrapper wrapper = p.getBuildWrappersList().get(SecretBuildWrapper.class); @@ -142,8 +147,8 @@ public void basics() throws Exception { assertThat(b.getSensitiveBuildVariables(), containsInAnyOrder("keystore", "password", "alias")); } - @Test - public void basicsPipeline() throws Exception { + @Test + void basicsPipeline() throws Exception { // create the Credentials String alias = "androiddebugkey"; String password = "android"; @@ -186,4 +191,10 @@ private FilePath copyTestResourceIntoWorkspace(FilePath workspace, String fileNa } } + private static File newFile(File parent, String child) throws IOException { + File result = new File(parent, child); + result.createNewFile(); + return result; + } + } diff --git a/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/SSHUserPrivateKeyBindingTest.java b/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/SSHUserPrivateKeyBindingTest.java index 59b75a8a..8d7a3015 100644 --- a/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/SSHUserPrivateKeyBindingTest.java +++ b/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/SSHUserPrivateKeyBindingTest.java @@ -32,34 +32,34 @@ import hudson.Functions; import hudson.security.ACL; import hudson.util.Secret; + import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.cps.SnippetizerTester; import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; import org.jenkinsci.plugins.workflow.steps.StepConfigTester; import org.jenkinsci.plugins.workflow.test.steps.SemaphoreStep; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.junit.runners.model.Statement; -import org.jvnet.hudson.test.RestartableJenkinsRule; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import java.io.Serializable; import java.util.Collections; import java.util.List; -import org.junit.ClassRule; -import org.jvnet.hudson.test.BuildWatcher; +import org.jvnet.hudson.test.junit.jupiter.BuildWatcherExtension; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; -public class SSHUserPrivateKeyBindingTest { +class SSHUserPrivateKeyBindingTest { - @Rule public RestartableJenkinsRule story = new RestartableJenkinsRule(); - @ClassRule public static BuildWatcher bw = new BuildWatcher(); - @Rule public TemporaryFolder tmp = new TemporaryFolder(); + @RegisterExtension + private final JenkinsSessionExtension extension = new JenkinsSessionExtension(); + @SuppressWarnings("unused") + @RegisterExtension + private static final BuildWatcherExtension BUILD_WATCHER = new BuildWatcherExtension(); private static class DummyPrivateKey extends BaseCredentials implements SSHUserPrivateKey, Serializable { @@ -122,46 +122,51 @@ public CredentialsScope getScope() { } } - @Test public void configRoundTrip() { - story.then(r -> { - SnippetizerTester st = new SnippetizerTester(r); + @Test + void configRoundTrip() throws Throwable { + extension.then(j -> { + SnippetizerTester st = new SnippetizerTester(j); SSHUserPrivateKey c = new DummyPrivateKey("creds", "bob", "secret", "the-key"); - CredentialsProvider.lookupStores(story.j.jenkins).iterator().next().addCredentials(Domain.global(), c); + CredentialsProvider.lookupStores(j.jenkins).iterator().next().addCredentials(Domain.global(), c); SSHUserPrivateKeyBinding binding = new SSHUserPrivateKeyBinding("keyFile", "creds"); - BindingStep s = new StepConfigTester(story.j).configRoundTrip(new BindingStep(Collections.singletonList(binding))); + BindingStep s = new StepConfigTester(j).configRoundTrip(new BindingStep(Collections.singletonList(binding))); st.assertRoundTrip(s, "withCredentials([sshUserPrivateKey(credentialsId: 'creds', keyFileVariable: 'keyFile')]) {\n // some block\n}"); - r.assertEqualDataBoundBeans(s.getBindings(), Collections.singletonList(binding)); + j.assertEqualDataBoundBeans(s.getBindings(), Collections.singletonList(binding)); binding.setPassphraseVariable("passphrase"); binding.setUsernameVariable("user"); - s = new StepConfigTester(story.j).configRoundTrip(new BindingStep(Collections.singletonList(binding))); + s = new StepConfigTester(j).configRoundTrip(new BindingStep(Collections.singletonList(binding))); st.assertRoundTrip(s, "withCredentials([sshUserPrivateKey(credentialsId: 'creds', keyFileVariable: 'keyFile', passphraseVariable: 'passphrase', usernameVariable: 'user')]) {\n // some block\n}"); - r.assertEqualDataBoundBeans(s.getBindings(), Collections.singletonList(binding)); + j.assertEqualDataBoundBeans(s.getBindings(), Collections.singletonList(binding)); }); } - @Test public void basics() { + @Test + void basics() throws Throwable { final String credentialsId = "creds"; final String username = "bob"; final String passphrase = "s3cr3t"; final String keyContent = "the-key"; - story.addStep(new Statement() { - @Override public void evaluate() throws Throwable { + extension.then(j -> { SSHUserPrivateKey c = new DummyPrivateKey(credentialsId, username, passphrase, keyContent); - CredentialsProvider.lookupStores(story.j.jenkins).iterator().next().addCredentials(Domain.global(), c); - WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "p"); + CredentialsProvider.lookupStores(j.jenkins).iterator().next().addCredentials(Domain.global(), c); + WorkflowJob p = j.jenkins.createProject(WorkflowJob.class, "p"); String script; if (Functions.isWindows()) { script = - " bat '''\n" - + " echo %THEUSER%:%THEPASS% > out.txt\n" - + " type \"%THEKEY%\" > key.txt" - + " '''\n"; + """ + bat ''' + echo %THEUSER%:%THEPASS% > out.txt + type "%THEKEY%" > key.txt\ + ''' + """; } else { script = - " sh '''\n" - + " echo $THEUSER:$THEPASS > out.txt\n" - + " cat \"$THEKEY\" > key.txt" - + " '''\n"; + """ + sh ''' + echo $THEUSER:$THEPASS > out.txt + cat "$THEKEY" > key.txt\ + ''' + """; } p.setDefinition(new CpsFlowDefinition("" + "node {\n" @@ -173,54 +178,57 @@ public CredentialsScope getScope() { WorkflowRun b = p.scheduleBuild2(0).waitForStart(); SemaphoreStep.waitForStart("basics/1", b); } - }); - story.addStep(new Statement() { - @Override public void evaluate() throws Throwable { - WorkflowJob p = story.j.jenkins.getItemByFullName("p", WorkflowJob.class); + ); + extension.then(j -> { + WorkflowJob p = j.jenkins.getItemByFullName("p", WorkflowJob.class); assertNotNull(p); WorkflowRun b = p.getBuildByNumber(1); assertNotNull(b); SemaphoreStep.success("basics/1", null); - story.j.waitForCompletion(b); - story.j.assertBuildStatusSuccess(b); - story.j.assertLogNotContains(username, b); - story.j.assertLogNotContains(passphrase, b); - FilePath out = story.j.jenkins.getWorkspaceFor(p).child("out.txt"); + j.waitForCompletion(b); + j.assertBuildStatusSuccess(b); + j.assertLogNotContains(username, b); + j.assertLogNotContains(passphrase, b); + FilePath out = j.jenkins.getWorkspaceFor(p).child("out.txt"); assertTrue(out.exists()); assertEquals(username + ":" + passphrase, out.readToString().trim()); - FilePath key = story.j.jenkins.getWorkspaceFor(p).child("key.txt"); + FilePath key = j.jenkins.getWorkspaceFor(p).child("key.txt"); assertTrue(key.exists()); assertEquals(keyContent, key.readToString().trim()); - ((DummyPrivateKey) CredentialsProvider.lookupCredentialsInItemGroup(SSHUserPrivateKey.class, story.j.jenkins, ACL.SYSTEM2, Collections.emptyList()).get(0)).usernameSecret = false; + ((DummyPrivateKey) CredentialsProvider.lookupCredentialsInItemGroup(SSHUserPrivateKey.class, j.jenkins, ACL.SYSTEM2, Collections.emptyList()).get(0)).usernameSecret = false; SemaphoreStep.success("basics/2", null); - b = story.j.buildAndAssertSuccess(p); - story.j.assertLogContains(username, b); - story.j.assertLogNotContains(passphrase, b); + b = j.buildAndAssertSuccess(p); + j.assertLogContains(username, b); + j.assertLogNotContains(passphrase, b); } - }); + ); } - @Test public void noUsernameOrPassphrase() { + @Test + void noUsernameOrPassphrase() throws Throwable { final String credentialsId = "creds"; final String keyContent = "the-key"; - story.addStep(new Statement() { - @Override public void evaluate() throws Throwable { + extension.then(j -> { SSHUserPrivateKey c = new DummyPrivateKey(credentialsId, "", "", keyContent); - CredentialsProvider.lookupStores(story.j.jenkins).iterator().next().addCredentials(Domain.global(), c); - WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "p"); + CredentialsProvider.lookupStores(j.jenkins).iterator().next().addCredentials(Domain.global(), c); + WorkflowJob p = j.jenkins.createProject(WorkflowJob.class, "p"); String script; if (Functions.isWindows()) { script = - " bat '''\n" - + " type \"%THEKEY%\" > key.txt" - + " '''\n"; + """ + bat ''' + type "%THEKEY%" > key.txt\ + ''' + """; } else { script = - " sh '''\n" - + " cat \"$THEKEY\" > key.txt" - + " '''\n"; + """ + sh ''' + cat "$THEKEY" > key.txt\ + ''' + """; } p.setDefinition(new CpsFlowDefinition("" + "node {\n" @@ -232,21 +240,20 @@ public CredentialsScope getScope() { WorkflowRun b = p.scheduleBuild2(0).waitForStart(); SemaphoreStep.waitForStart("basics/1", b); } - }); - story.addStep(new Statement() { - @Override public void evaluate() throws Throwable { - WorkflowJob p = story.j.jenkins.getItemByFullName("p", WorkflowJob.class); + ); + extension.then(j -> { + WorkflowJob p = j.jenkins.getItemByFullName("p", WorkflowJob.class); assertNotNull(p); WorkflowRun b = p.getBuildByNumber(1); assertNotNull(b); SemaphoreStep.success("basics/1", null); - story.j.waitForCompletion(b); - story.j.assertBuildStatusSuccess(b); + j.waitForCompletion(b); + j.assertBuildStatusSuccess(b); - FilePath key = story.j.jenkins.getWorkspaceFor(p).child("key.txt"); + FilePath key = j.jenkins.getWorkspaceFor(p).child("key.txt"); assertTrue(key.exists()); assertEquals(keyContent, key.readToString().trim()); } - }); + ); } } diff --git a/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/SecretBuildWrapperTest.java b/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/SecretBuildWrapperTest.java index a8f51565..b28b67ec 100644 --- a/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/SecretBuildWrapperTest.java +++ b/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/SecretBuildWrapperTest.java @@ -41,24 +41,36 @@ import hudson.tasks.Shell; import hudson.util.Secret; import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import org.junit.ClassRule; -import org.jvnet.hudson.test.BuildWatcher; -public class SecretBuildWrapperTest { +import org.jvnet.hudson.test.junit.jupiter.BuildWatcherExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; + +@WithJenkins +class SecretBuildWrapperTest { - @ClassRule public static BuildWatcher buildWatcher = new BuildWatcher(); - @Rule public JenkinsRule r = new JenkinsRule(); + @SuppressWarnings("unused") + @RegisterExtension + private static final BuildWatcherExtension BUILD_WATCHER = new BuildWatcherExtension(); + private JenkinsRule r; + + @BeforeEach + void beforeEach(JenkinsRule rule) { + r = rule; + } @Issue("JENKINS-24805") - @Test public void maskingFreeStyleSecrets() throws Exception { + @Test + void maskingFreeStyleSecrets() throws Exception { String firstCredentialsId = "creds_1"; String firstPassword = "p4$$"; StringCredentialsImpl firstCreds = new StringCredentialsImpl(CredentialsScope.GLOBAL, firstCredentialsId, "sample1", Secret.fromString(firstPassword)); @@ -90,7 +102,8 @@ public class SecretBuildWrapperTest { } @Issue("JENKINS-24805") - @Test public void emptySecretsList() throws Exception { + @Test + void emptySecretsList() throws Exception { SecretBuildWrapper wrapper = new SecretBuildWrapper(new ArrayList<>()); FreeStyleProject f = r.createFreeStyleProject(); @@ -106,7 +119,8 @@ public class SecretBuildWrapperTest { } @Issue("JENKINS-41760") - @Test public void emptySecret() throws Exception { + @Test + void emptySecret() throws Exception { CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), new StringCredentialsImpl(CredentialsScope.GLOBAL, "creds", null, Secret.fromString(""))); FreeStyleProject p = r.createFreeStyleProject(); p.getBuildWrappersList().add(new SecretBuildWrapper(Collections.singletonList(new StringBinding("SECRET", "creds")))); @@ -115,7 +129,8 @@ public class SecretBuildWrapperTest { } @Issue("SECURITY-1374") - @Test public void maskingPostBuild() throws Exception { + @Test + void maskingPostBuild() throws Exception { String credentialsId = "creds_1"; String password = "p4$$"; StringCredentialsImpl firstCreds = new StringCredentialsImpl(CredentialsScope.GLOBAL, credentialsId, "sample1", Secret.fromString(password)); @@ -138,14 +153,14 @@ public class SecretBuildWrapperTest { static class PasswordPublisher extends Recorder { - private String password; + private final String password; public PasswordPublisher(String password) { this.password = password; } - public @Override - boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) { + @Override + public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) { listener.getLogger().println("Sneak it in during the postbuild: " + password + " :done."); return true; } diff --git a/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/UsernamePasswordBindingTest.java b/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/UsernamePasswordBindingTest.java index 682ac43a..eca438e8 100644 --- a/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/UsernamePasswordBindingTest.java +++ b/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/UsernamePasswordBindingTest.java @@ -42,7 +42,6 @@ import hudson.model.FreeStyleProject; import hudson.model.ParametersAction; import hudson.model.ParametersDefinitionProperty; -import hudson.remoting.Future; import hudson.tasks.BatchFile; import hudson.tasks.Shell; import java.util.Collections; @@ -50,9 +49,11 @@ import jenkins.model.Jenkins; import org.jenkinsci.plugins.credentialsbinding.Binding; import org.jenkinsci.plugins.credentialsbinding.MultiBinding; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.xmlunit.matchers.CompareMatcher; import static org.hamcrest.MatcherAssert.assertThat; @@ -60,15 +61,21 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@WithJenkins +class UsernamePasswordBindingTest { -public class UsernamePasswordBindingTest { + private JenkinsRule r; - @Rule public JenkinsRule r = new JenkinsRule(); - private CredentialsStore store = null; + @BeforeEach + void beforeEach(JenkinsRule rule) { + r = rule; + } - @Test public void basics() throws Exception { + @Test + void basics() throws Exception { String username = "bob"; String password = "s3cr3t"; UsernamePasswordCredentialsImpl c = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, null, "sample", username, password); @@ -92,7 +99,9 @@ public class UsernamePasswordBindingTest { } @Test - public void theSecretBuildWrapperTracksUsage() throws Exception { + void theSecretBuildWrapperTracksUsage() throws Exception { + CredentialsStore store = null; + SystemCredentialsProvider.getInstance().setDomainCredentialsMap( Collections.singletonMap(Domain.global(), Collections.emptyList())); for (CredentialsStore s : CredentialsProvider.lookupStores(Jenkins.get())) { @@ -127,7 +136,7 @@ public void theSecretBuildWrapperTracksUsage() throws Exception { false ))); - r.assertBuildStatusSuccess((Future) job.scheduleBuild2(0, + r.assertBuildStatusSuccess(job.scheduleBuild2(0, new ParametersAction(new CredentialsParameterValue("SECRET", "secret-id", "The secret", true)))); fingerprint = CredentialsProvider.getFingerprintOf(credentials); @@ -141,7 +150,7 @@ public void theSecretBuildWrapperTracksUsage() throws Exception { // check that the wrapper works as expected job.getBuildWrappersList().add(new SecretBuildWrapper(Collections.>singletonList(new UsernamePasswordBinding("AUTH", credentials.getId())))); - r.assertBuildStatusSuccess((Future) job.scheduleBuild2(0, new ParametersAction(new CredentialsParameterValue("SECRET", "secret-id", "The secret", true)))); + r.assertBuildStatusSuccess(job.scheduleBuild2(0, new ParametersAction(new CredentialsParameterValue("SECRET", "secret-id", "The secret", true)))); fingerprint = CredentialsProvider.getFingerprintOf(credentials); assertThat(fingerprint, notNullValue()); diff --git a/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/UsernamePasswordMultiBindingTest.java b/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/UsernamePasswordMultiBindingTest.java index 8ebf35f6..4ecff1a8 100644 --- a/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/UsernamePasswordMultiBindingTest.java +++ b/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/UsernamePasswordMultiBindingTest.java @@ -41,23 +41,34 @@ import java.util.TreeSet; import org.jenkinsci.plugins.credentialsbinding.MultiBinding; -import org.junit.Test; -import org.junit.ClassRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -import org.junit.Rule; -import org.jvnet.hudson.test.BuildWatcher; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.BuildWatcherExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; -public class UsernamePasswordMultiBindingTest { +@WithJenkins +class UsernamePasswordMultiBindingTest { - @Rule public JenkinsRule r = new JenkinsRule(); - @ClassRule public static BuildWatcher bw = new BuildWatcher(); + @SuppressWarnings("unused") + @RegisterExtension + private static final BuildWatcherExtension BUILD_WATCHER = new BuildWatcherExtension(); - @Test public void basics() throws Exception { + private JenkinsRule r; + + @BeforeEach + void beforeEach(JenkinsRule rule) { + r = rule; + } + + @Test + void basics() throws Exception { String username = "bob"; String password = "s3cr3t"; UsernamePasswordCredentialsImpl c = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, null, "sample", username, password); diff --git a/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/ZipFileBindingTest.java b/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/ZipFileBindingTest.java index 331c3ad9..21bc4525 100644 --- a/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/ZipFileBindingTest.java +++ b/src/test/java/org/jenkinsci/plugins/credentialsbinding/impl/ZipFileBindingTest.java @@ -32,29 +32,36 @@ import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; + +@WithJenkins +class ZipFileBindingTest { -public class ZipFileBindingTest { + private JenkinsRule r; - @Rule - public JenkinsRule j = new JenkinsRule(); + @BeforeEach + void beforeEach(JenkinsRule rule) { + r = rule; + } @Issue("JENKINS-30941") @Test - public void cleanUpSucceeds() throws Exception { + void cleanUpSucceeds() throws Exception { /* Issue was just present on Linux not windows - but the test will run on both */ final String credentialsId = "zipfile"; FileCredentialsImpl fc = new FileCredentialsImpl(CredentialsScope.GLOBAL, credentialsId, "Just a zip file", "a.zip", SecretBytes.fromBytes(IOUtils.toByteArray(ZipFileBindingTest.class.getResource("a.zip")))); - CredentialsProvider.lookupStores(j.jenkins).iterator().next().addCredentials(Domain.global(), fc); + CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), fc); final String contents = "Test of ZipFileBinding\n"; - WorkflowJob p = j.jenkins.createProject(WorkflowJob.class, "p"); + WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition("" + "node {\n" + " withCredentials([[$class: 'ZipFileBinding', credentialsId: '"+ credentialsId +"', variable: 'ziploc']]) {\n" @@ -64,7 +71,7 @@ public void cleanUpSucceeds() throws Exception { , true)); WorkflowRun run = p.scheduleBuild2(0).get(); - j.assertBuildStatusSuccess(run); - j.assertLogContains(contents, run); + r.assertBuildStatusSuccess(run); + r.assertLogContains(contents, run); } } diff --git a/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/AlmquistShellSecretPatternFactoryTest.java b/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/AlmquistShellSecretPatternFactoryTest.java index 3aa373bb..0c8c39ff 100644 --- a/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/AlmquistShellSecretPatternFactoryTest.java +++ b/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/AlmquistShellSecretPatternFactoryTest.java @@ -30,50 +30,59 @@ import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.experimental.theories.DataPoint; -import org.junit.experimental.theories.DataPoints; -import org.junit.experimental.theories.Theories; -import org.junit.experimental.theories.Theory; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.UUID; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.startsWith; -import static org.jenkinsci.plugins.credentialsbinding.test.Executables.executable; -import static org.junit.Assume.assumeThat; +import static org.jenkinsci.plugins.credentialsbinding.test.Executables.isExecutable; +import static org.junit.jupiter.api.Assumptions.assumeFalse; +import static org.junit.jupiter.api.Assumptions.assumeTrue; -@RunWith(Theories.class) -public class AlmquistShellSecretPatternFactoryTest { +@WithJenkins +class AlmquistShellSecretPatternFactoryTest { // ' is escaped as '"'"', '' as '"''"', ''' as '"'''"' - public static final @DataPoint String MULTIPLE_QUOTES = "ab'cd''ef'''gh"; + private static final String MULTIPLE_QUOTES = "ab'cd''ef'''gh"; // "starting" and "ending" single quotes are escaped as "middle" single quotes - public static final @DataPoint String SURROUNDED_BY_QUOTES = "'abc'"; - public static final @DataPoint String SURROUNDED_BY_QUOTES_AND_MIDDLE = "'ab'cd'"; - public static final @DataPoint String SIMPLE_CASE_1 = "abc"; - public static final @DataPoint String SIMPLE_CASE_2 = "ab'cd"; - public static final @DataPoint String SIMPLE_CASE_3 = "ab''cd"; - public static final @DataPoint String SIMPLE_CASE_4 = "ab'c'd"; - public static final @DataPoint String LEADING_QUOTE = "'a\"b\"c d"; - public static final @DataPoint String TRAILING_QUOTE = "a\"b\"c d'"; - public static final @DataPoint String SAMPLE_PASSWORD = "}#T14'GAz&H!{$U_"; - public static final @DataPoint String ANOTHER_SAMPLE_PASSWORD = "a'b\"c\\d(e)#"; - public static final @DataPoint String ONE_MORE = "'\"'(foo)'\"'"; - public static final @DataPoint String FULL_ASCII = "!\"#$%&'()*+,-./ 0123456789:;<=>? @ABCDEFGHIJKLMNO PQRSTUVWXYZ[\\]^_ `abcdefghijklmno pqrstuvwxyz{|}~"; - - @DataPoints - public static List generatePasswords() { + private static final String SURROUNDED_BY_QUOTES = "'abc'"; + private static final String SURROUNDED_BY_QUOTES_AND_MIDDLE = "'ab'cd'"; + private static final String SIMPLE_CASE_1 = "abc"; + private static final String SIMPLE_CASE_2 = "ab'cd"; + private static final String SIMPLE_CASE_3 = "ab''cd"; + private static final String SIMPLE_CASE_4 = "ab'c'd"; + private static final String LEADING_QUOTE = "'a\"b\"c d"; + private static final String TRAILING_QUOTE = "a\"b\"c d'"; + private static final String SAMPLE_PASSWORD = "}#T14'GAz&H!{$U_"; + private static final String ANOTHER_SAMPLE_PASSWORD = "a'b\"c\\d(e)#"; + private static final String ONE_MORE = "'\"'(foo)'\"'"; + private static final String FULL_ASCII = "!\"#$%&'()*+,-./ 0123456789:;<=>? @ABCDEFGHIJKLMNO PQRSTUVWXYZ[\\]^_ `abcdefghijklmno pqrstuvwxyz{|}~"; + + static List generatePasswords() { Random random = new Random(100); - List passwords = new ArrayList<>(10); + List passwords = new ArrayList<>(); + + passwords.add(MULTIPLE_QUOTES); + passwords.add(SURROUNDED_BY_QUOTES); + passwords.add(SURROUNDED_BY_QUOTES_AND_MIDDLE); + passwords.add(SIMPLE_CASE_1); + passwords.add(SIMPLE_CASE_2); + passwords.add(SIMPLE_CASE_3); + passwords.add(SIMPLE_CASE_4); + passwords.add(LEADING_QUOTE); + passwords.add(TRAILING_QUOTE); + passwords.add(SAMPLE_PASSWORD); + passwords.add(ANOTHER_SAMPLE_PASSWORD); + passwords.add(ONE_MORE); + passwords.add(FULL_ASCII); + for (int i = 0; i < 10; i++) { int length = random.nextInt(24) + 8; StringBuilder sb = new StringBuilder(length); @@ -88,24 +97,25 @@ public static List generatePasswords() { return passwords; } - @ClassRule public static JenkinsRule j = new JenkinsRule(); + private static JenkinsRule r; private WorkflowJob project; private String credentialsId; - @BeforeClass - public static void assumeAsh() { + @BeforeAll + static void beforeAll(JenkinsRule rule) { + r = rule; // ash = Almquist shell, default one used in Alpine - assumeThat("ash", is(executable())); + assumeTrue(isExecutable("ash")); // due to https://github.com/jenkinsci/durable-task-plugin/blob/e75123eda986f20a390d92cc892c3d206e60aefb/src/main/java/org/jenkinsci/plugins/durabletask/BourneShellScript.java#L149 // on Windows - assumeThat("nohup", is(executable())); + assumeTrue(isExecutable("nohup")); } - @Before - public void setUp() throws Exception { - j.jenkins.getDescriptorByType(Shell.DescriptorImpl.class).setShell(Executables.getPathToExecutable("ash")); - project = j.createProject(WorkflowJob.class); + @BeforeEach + void beforeEach() throws Exception { + r.jenkins.getDescriptorByType(Shell.DescriptorImpl.class).setShell(Executables.getPathToExecutable("ash")); + project = r.createProject(WorkflowJob.class); credentialsId = UUID.randomUUID().toString(); project.setDefinition(new CpsFlowDefinition( @@ -120,20 +130,21 @@ public void setUp() throws Exception { "}", true)); } - @Theory - public void credentialsAreMaskedInLogs(String credentials) throws Exception { - assumeThat(credentials, not(startsWith("****"))); + @ParameterizedTest + @MethodSource("generatePasswords") + void credentialsAreMaskedInLogs(String credentials) throws Exception { + assumeFalse(credentials.startsWith("****")); - CredentialsTestUtil.setStringCredentials(j.jenkins, credentialsId, credentials); + CredentialsTestUtil.setStringCredentials(r.jenkins, credentialsId, credentials); WorkflowRun run = runProject(); - j.assertLogContains("begin0 **** end0", run); - j.assertLogContains("begin2 **** end2", run); - j.assertLogNotContains(credentials, run); + r.assertLogContains("begin0 **** end0", run); + r.assertLogContains("begin2 **** end2", run); + r.assertLogNotContains(credentials, run); } private WorkflowRun runProject() throws Exception { - return j.buildAndAssertSuccess(project); + return r.buildAndAssertSuccess(project); } } diff --git a/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/Base64SecretPatternFactoryTest.java b/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/Base64SecretPatternFactoryTest.java index 1e48690a..dfe82cd0 100644 --- a/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/Base64SecretPatternFactoryTest.java +++ b/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/Base64SecretPatternFactoryTest.java @@ -1,43 +1,53 @@ package org.jenkinsci.plugins.credentialsbinding.masking; -import static org.hamcrest.Matchers.is; -import static org.jenkinsci.plugins.credentialsbinding.test.Executables.executable; -import static org.junit.Assume.assumeThat; +import static org.jenkinsci.plugins.credentialsbinding.test.Executables.isExecutable; +import static org.junit.jupiter.api.Assumptions.assumeTrue; import hudson.Functions; import org.jenkinsci.plugins.credentialsbinding.test.CredentialsTestUtil; import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; + +@WithJenkins +class Base64SecretPatternFactoryTest { -public class Base64SecretPatternFactoryTest { + private static final String SAMPLE_PASSWORD = "}#T14'GAz&H!{$U_"; - @Rule - public JenkinsRule j = new JenkinsRule(); + private JenkinsRule r; - public static final String SAMPLE_PASSWORD = "}#T14'GAz&H!{$U_"; + @BeforeEach + void beforeEach(JenkinsRule rule) { + r = rule; + } @Test - public void base64SecretsAreMaskedInLogs() throws Exception { - WorkflowJob project = j.createProject(WorkflowJob.class); - String credentialsId = CredentialsTestUtil.registerUsernamePasswordCredentials(j.jenkins, "user", SAMPLE_PASSWORD); + void base64SecretsAreMaskedInLogs() throws Exception { + WorkflowJob project = r.createProject(WorkflowJob.class); + String credentialsId = CredentialsTestUtil.registerUsernamePasswordCredentials(r.jenkins, "user", SAMPLE_PASSWORD); String script; if (Functions.isWindows()) { - assumeThat("powershell", is(executable())); + assumeTrue(isExecutable("powershell")); script = - " powershell '''\n" - + " $secret = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes(\"$env:PASSWORD\"))\n" - + " echo $secret\n" - + " '''\n"; + """ + powershell ''' + $secret = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("$env:PASSWORD")) + echo $secret + ''' + """; } else { script = - " sh '''\n" - + " echo -n $PASSWORD | base64\n" - + " '''\n"; + """ + sh ''' + echo -n $PASSWORD | base64 + ''' + """; } project.setDefinition(new CpsFlowDefinition( @@ -47,9 +57,9 @@ public void base64SecretsAreMaskedInLogs() throws Exception { + " }\n" + "}", true)); - WorkflowRun run = j.assertBuildStatusSuccess(project.scheduleBuild2(0)); + WorkflowRun run = r.assertBuildStatusSuccess(project.scheduleBuild2(0)); - j.assertLogContains("****", run); - j.assertLogNotContains(SAMPLE_PASSWORD, run); + r.assertLogContains("****", run); + r.assertLogNotContains(SAMPLE_PASSWORD, run); } } \ No newline at end of file diff --git a/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/BashSecretPatternFactory2Test.java b/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/BashSecretPatternFactory2Test.java index 708298f4..7e6ee6bf 100644 --- a/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/BashSecretPatternFactory2Test.java +++ b/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/BashSecretPatternFactory2Test.java @@ -30,36 +30,38 @@ import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + import org.jvnet.hudson.test.For; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; -import static org.hamcrest.Matchers.is; -import static org.jenkinsci.plugins.credentialsbinding.test.Executables.executable; -import static org.junit.Assume.assumeThat; +import static org.jenkinsci.plugins.credentialsbinding.test.Executables.isExecutable; +import static org.junit.jupiter.api.Assumptions.assumeTrue; @For(BashSecretPatternFactory.class) -public class BashSecretPatternFactory2Test { +@WithJenkins +class BashSecretPatternFactory2Test { - public @Rule JenkinsRule j = new JenkinsRule(); + private JenkinsRule r; - @Before - public void setUp() { - assumeThat("bash", is(executable())); + @BeforeEach + void beforeEach(JenkinsRule rule) { + r = rule; + assumeTrue(isExecutable("bash")); // due to https://github.com/jenkinsci/durable-task-plugin/blob/e75123eda986f20a390d92cc892c3d206e60aefb/src/main/java/org/jenkinsci/plugins/durabletask/BourneShellScript.java#L149 // on Windows - assumeThat("nohup", is(executable())); - j.jenkins.getDescriptorByType(Shell.DescriptorImpl.class).setShell(Executables.getPathToExecutable("bash")); + assumeTrue(isExecutable("nohup")); + r.jenkins.getDescriptorByType(Shell.DescriptorImpl.class).setShell(Executables.getPathToExecutable("bash")); } - @Test // DO NOT DO THIS IN PRODUCTION; IT IS QUOTED WRONG - public void testSecretsWithBackslashesStillMaskedWhenUsedWithoutProperQuoting() throws Exception { - WorkflowJob project = j.createProject(WorkflowJob.class); + @Test + void testSecretsWithBackslashesStillMaskedWhenUsedWithoutProperQuoting() throws Exception { + WorkflowJob project = r.createProject(WorkflowJob.class); String password = "foo\\bar\\"; - String credentialsId = CredentialsTestUtil.registerStringCredentials(j.jenkins, password); + String credentialsId = CredentialsTestUtil.registerStringCredentials(r.jenkins, password); project.setDefinition(new CpsFlowDefinition( "node {\n" + " withCredentials([string(credentialsId: '" + credentialsId + "', variable: 'CREDENTIALS')]) {\n" + @@ -68,11 +70,11 @@ public void testSecretsWithBackslashesStillMaskedWhenUsedWithoutProperQuoting() " }\n" + "}", true)); - WorkflowRun run = j.assertBuildStatusSuccess(project.scheduleBuild2(0)); + WorkflowRun run = r.assertBuildStatusSuccess(project.scheduleBuild2(0)); - j.assertLogContains(": ****", run); - j.assertLogNotContains(password, run); - j.assertLogNotContains("foo", run); - j.assertLogNotContains("bar", run); + r.assertLogContains(": ****", run); + r.assertLogNotContains(password, run); + r.assertLogNotContains("foo", run); + r.assertLogNotContains("bar", run); } } diff --git a/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/BashSecretPatternFactoryTest.java b/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/BashSecretPatternFactoryTest.java index 051d1161..724efb2c 100644 --- a/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/BashSecretPatternFactoryTest.java +++ b/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/BashSecretPatternFactoryTest.java @@ -30,38 +30,37 @@ import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.experimental.theories.DataPoint; -import org.junit.experimental.theories.DataPoints; -import org.junit.experimental.theories.Theories; -import org.junit.experimental.theories.Theory; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.UUID; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.startsWith; -import static org.jenkinsci.plugins.credentialsbinding.test.Executables.executable; -import static org.junit.Assume.assumeThat; +import static org.jenkinsci.plugins.credentialsbinding.test.Executables.isExecutable; +import static org.junit.jupiter.api.Assumptions.assumeFalse; +import static org.junit.jupiter.api.Assumptions.assumeTrue; -@RunWith(Theories.class) -public class BashSecretPatternFactoryTest { +@WithJenkins +class BashSecretPatternFactoryTest { - public static final @DataPoint String SAMPLE_PASSWORD = "}#T14'GAz&H!{$U_"; - public static final @DataPoint String ANOTHER_SAMPLE_PASSWORD = "a'b\"c\\d(e)#"; - public static final @DataPoint String ONE_MORE = "'\"'(foo)'\"'"; + private static final String SAMPLE_PASSWORD = "}#T14'GAz&H!{$U_"; + private static final String ANOTHER_SAMPLE_PASSWORD = "a'b\"c\\d(e)#"; + private static final String ONE_MORE = "'\"'(foo)'\"'"; - @DataPoints - public static List generatePasswords() { + static List generatePasswords() { Random random = new Random(100); - List passwords = new ArrayList<>(10); + List passwords = new ArrayList<>(); + + passwords.add(SAMPLE_PASSWORD); + passwords.add(ANOTHER_SAMPLE_PASSWORD); + passwords.add(ONE_MORE); + for (int i = 0; i < 10; i++) { int length = random.nextInt(24) + 8; StringBuilder sb = new StringBuilder(length); @@ -76,23 +75,24 @@ public static List generatePasswords() { return passwords; } - @ClassRule public static JenkinsRule j = new JenkinsRule(); + private static JenkinsRule r; private WorkflowJob project; private String credentialsId; - @BeforeClass - public static void assumeBash() { - assumeThat("bash", is(executable())); + @BeforeAll + static void beforeAll(JenkinsRule rule) { + r = rule; + assumeTrue(isExecutable("bash")); // due to https://github.com/jenkinsci/durable-task-plugin/blob/e75123eda986f20a390d92cc892c3d206e60aefb/src/main/java/org/jenkinsci/plugins/durabletask/BourneShellScript.java#L149 // on Windows - assumeThat("nohup", is(executable())); + assumeTrue(isExecutable("nohup")); } - @Before - public void setUp() throws Exception { - j.jenkins.getDescriptorByType(Shell.DescriptorImpl.class).setShell(Executables.getPathToExecutable("bash")); - project = j.createProject(WorkflowJob.class); + @BeforeEach + void beforeEach() throws Exception { + r.jenkins.getDescriptorByType(Shell.DescriptorImpl.class).setShell(Executables.getPathToExecutable("bash")); + project = r.createProject(WorkflowJob.class); credentialsId = UUID.randomUUID().toString(); project.setDefinition(new CpsFlowDefinition( "node {\n" + @@ -103,20 +103,21 @@ public void setUp() throws Exception { "}", true)); } - @Theory - public void credentialsAreMaskedInLogs(String credentials) throws Exception { - assumeThat(credentials, not(startsWith("****"))); + @ParameterizedTest + @MethodSource("generatePasswords") + void credentialsAreMaskedInLogs(String credentials) throws Exception { + assumeFalse(credentials.startsWith("****")); - CredentialsTestUtil.setStringCredentials(j.jenkins, credentialsId, credentials); + CredentialsTestUtil.setStringCredentials(r.jenkins, credentialsId, credentials); WorkflowRun run = runProject(); - j.assertLogContains(": ****", run); - j.assertLogContains(": '< **** >'", run); - j.assertLogNotContains(credentials, run); + r.assertLogContains(": ****", run); + r.assertLogContains(": '< **** >'", run); + r.assertLogNotContains(credentials, run); } private WorkflowRun runProject() throws Exception { - return j.assertBuildStatusSuccess(project.scheduleBuild2(0)); + return r.assertBuildStatusSuccess(project.scheduleBuild2(0)); } } diff --git a/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/BatchSecretPatternFactoryTest.java b/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/BatchSecretPatternFactoryTest.java index 754e72cc..042b3aae 100644 --- a/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/BatchSecretPatternFactoryTest.java +++ b/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/BatchSecretPatternFactoryTest.java @@ -30,18 +30,20 @@ import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import java.io.IOException; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assume.assumeTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; -public class BatchSecretPatternFactoryTest { +@WithJenkins +class BatchSecretPatternFactoryTest { private static final String SIMPLE = "abcABC123"; private static final String SAMPLE_PASSWORD = "}#T14'GAz&H!{$U_"; @@ -58,119 +60,119 @@ public class BatchSecretPatternFactoryTest { private static final String ALL_ASCII = "!\"#$%&'()*+,-./ 0123456789:;<=>? @ABCDEFGHIJKLMNO PQRSTUVWXYZ[\\]^_ `abcdefghijklmno pqrstuvwxyz{|}~"; - @Rule - public JenkinsRule j = new JenkinsRule(); + private JenkinsRule r; private WorkflowJob project; private String credentialPlainText; private String credentialId; - @Before - public void assumeWindowsForBatch() { + @BeforeEach + void beforeEach(JenkinsRule rule) { + r = rule; assumeTrue(Functions.isWindows()); } private void registerCredentials(String password) throws IOException { this.credentialPlainText = password; - this.credentialId = CredentialsTestUtil.registerStringCredentials(j.jenkins, password); + this.credentialId = CredentialsTestUtil.registerStringCredentials(r.jenkins, password); } private WorkflowRun runProject() throws Exception { - return j.assertBuildStatusSuccess(project.scheduleBuild2(0)); + return r.assertBuildStatusSuccess(project.scheduleBuild2(0)); } @Test - public void simple_noQuote() throws Exception { + void simple_noQuote() throws Exception { registerCredentials(SIMPLE); assertDirectNoPlainTextButStars(runDirectNoQuote()); } @Test - public void simple_singleQuote() throws Exception { + void simple_singleQuote() throws Exception { registerCredentials(SIMPLE); assertDirectNoPlainTextButStars(runDirectSingleQuote()); } @Test - public void simple_doubleQuote() throws Exception { + void simple_doubleQuote() throws Exception { registerCredentials(SIMPLE); assertDirectNoPlainTextButStars(runDirectDoubleQuote()); } @Test - public void simple_delayed() throws Exception { + void simple_delayed() throws Exception { registerCredentials(SIMPLE); assertDelayedNoPlainTextButStars(runDelayedAllQuotes()); } @Test - public void nonDangerous_noQuote() throws Exception { + void nonDangerous_noQuote() throws Exception { registerCredentials(NON_DANGEROUS); assertDirectNoPlainTextButStars(runDirectNoQuote()); } @Test - public void nonDangerous_singleQuote() throws Exception { + void nonDangerous_singleQuote() throws Exception { registerCredentials(NON_DANGEROUS); assertDirectNoPlainTextButStars(runDirectSingleQuote()); } @Test - public void nonDangerous_doubleQuote() throws Exception { + void nonDangerous_doubleQuote() throws Exception { registerCredentials(NON_DANGEROUS); assertDirectNoPlainTextButStars(runDirectDoubleQuote()); } @Test - public void nonDangerous_delayed() throws Exception { + void nonDangerous_delayed() throws Exception { registerCredentials(NON_DANGEROUS); assertDelayedNoPlainTextButStars(runDelayedAllQuotes()); } // we do NOT support dangerous characters in direct expansion mode @Test - public void allAscii_direct_noQuote() throws Exception { + void allAscii_direct_noQuote() throws Exception { registerCredentials(ALL_ASCII); WorkflowRun run = runDirectNoQuote(); - j.assertLogNotContains(credentialPlainText, run); + r.assertLogNotContains(credentialPlainText, run); // EFGHIJK is a part of the credentials that should be masked assertStringPresentInOrder(run, "before1", "EFGHIJK", "after1"); - j.assertLogNotContains("before1 **** after1", run); + r.assertLogNotContains("before1 **** after1", run); } // we do NOT support dangerous characters in direct expansion mode @Test - public void allAscii_direct_singleQuote() throws Exception { + void allAscii_direct_singleQuote() throws Exception { registerCredentials(ALL_ASCII); WorkflowRun run = runDirectSingleQuote(); - j.assertLogNotContains(credentialPlainText, run); + r.assertLogNotContains(credentialPlainText, run); // EFGHIJK is a part of the credentials that should be masked assertStringPresentInOrder(run, "before1", "EFGHIJK", "after1"); - j.assertLogNotContains("before1 **** after1", run); + r.assertLogNotContains("before1 **** after1", run); } // we do NOT support dangerous characters in direct expansion mode @Test - public void allAscii_direct_doubleQuote() throws Exception { + void allAscii_direct_doubleQuote() throws Exception { registerCredentials(ALL_ASCII); runDirectDoubleQuote_andFail(); } @Test - public void allAscii_delayed() throws Exception { + void allAscii_delayed() throws Exception { registerCredentials(ALL_ASCII); assertDelayedNoPlainTextButStars(runDelayedAllQuotes()); } // we do NOT support dangerous characters in direct expansion mode @Test - public void samplePassword_noQuote() throws Exception { + void samplePassword_noQuote() throws Exception { registerCredentials(SAMPLE_PASSWORD); runDirectNoQuote_andFail(); @@ -178,80 +180,80 @@ public void samplePassword_noQuote() throws Exception { // we do NOT support dangerous characters in direct expansion mode @Test - public void samplePassword_singleQuote() throws Exception { + void samplePassword_singleQuote() throws Exception { registerCredentials(SAMPLE_PASSWORD); runDirectSingleQuote_andFail(); } @Test - public void samplePassword_doubleQuote() throws Exception { + void samplePassword_doubleQuote() throws Exception { registerCredentials(SAMPLE_PASSWORD); assertDirectNoPlainTextButStars(runDirectDoubleQuote()); } @Test - public void samplePassword_delayed() throws Exception { + void samplePassword_delayed() throws Exception { registerCredentials(SAMPLE_PASSWORD); assertDelayedNoPlainTextButStars(runDelayedAllQuotes()); } @Test - public void escape_noQuote() throws Exception { + void escape_noQuote() throws Exception { registerCredentials(ESCAPE); WorkflowRun run = runDirectNoQuote(); - j.assertLogNotContains(credentialPlainText, run); - j.assertLogContains("before1 **** after1", run); - j.assertLogContains("before2 **** after2", run); + r.assertLogNotContains(credentialPlainText, run); + r.assertLogContains("before1 **** after1", run); + r.assertLogContains("before2 **** after2", run); } @Test - public void escape_singleQuote() throws Exception { + void escape_singleQuote() throws Exception { registerCredentials(ESCAPE); WorkflowRun run = runDirectSingleQuote(); - j.assertLogNotContains(credentialPlainText, run); - j.assertLogContains("before1 **** after1", run); - j.assertLogContains("before2 **** after2", run); + r.assertLogNotContains(credentialPlainText, run); + r.assertLogContains("before1 **** after1", run); + r.assertLogContains("before2 **** after2", run); } @Test - public void escape_doubleQuote() throws Exception { + void escape_doubleQuote() throws Exception { registerCredentials(ESCAPE); assertDirectNoPlainTextButStars(runDirectDoubleQuote()); } @Test - public void escape_delayed() throws Exception { + void escape_delayed() throws Exception { registerCredentials(ESCAPE); assertDelayedNoPlainTextButStars(runDelayedAllQuotes()); } // special cases @Test - public void dangerousOutOfDouble_doubleQuote() throws Exception { + void dangerousOutOfDouble_doubleQuote() throws Exception { registerCredentials(NON_DANGEROUS_IN_DOUBLE); assertDirectNoPlainTextButStars(runDirectDoubleQuote()); } @Test - public void needsQuoting_doubleQuote() throws Exception { + void needsQuoting_doubleQuote() throws Exception { registerCredentials(NEEDS_QUOTING); assertDirectNoPlainTextButStars(runDirectDoubleQuote()); } private void assertDirectNoPlainTextButStars(WorkflowRun run) throws Exception { - j.assertLogNotContains(credentialPlainText, run); - j.assertLogContains("before1 **** after1", run); - j.assertLogContains("before2 **** after2", run); + r.assertLogNotContains(credentialPlainText, run); + r.assertLogContains("before1 **** after1", run); + r.assertLogContains("before2 **** after2", run); } private void assertDelayedNoPlainTextButStars(WorkflowRun run) throws Exception { - j.assertLogNotContains(credentialPlainText, run); - j.assertLogContains("before1 **** after1", run); - j.assertLogContains("before2 **** after2", run); - j.assertLogContains("before3 **** after3", run); + r.assertLogNotContains(credentialPlainText, run); + r.assertLogContains("before1 **** after1", run); + r.assertLogContains("before2 **** after2", run); + r.assertLogContains("before3 **** after3", run); } private WorkflowRun runDirectNoQuote() throws Exception { @@ -261,7 +263,7 @@ private WorkflowRun runDirectNoQuote() throws Exception { private void runDirectNoQuote_andFail() throws Exception { setupNoQuoteProject(); - j.assertBuildStatus(Result.FAILURE, project.scheduleBuild2(0)); + r.assertBuildStatus(Result.FAILURE, project.scheduleBuild2(0)); } private void setupNoQuoteProject() throws Exception { @@ -287,7 +289,7 @@ private WorkflowRun runDirectSingleQuote() throws Exception { private void runDirectSingleQuote_andFail() throws Exception { setupSingleQuoteProject(); - j.assertBuildStatus(Result.FAILURE, project.scheduleBuild2(0)); + r.assertBuildStatus(Result.FAILURE, project.scheduleBuild2(0)); } private void setupSingleQuoteProject() throws Exception { @@ -313,7 +315,7 @@ private WorkflowRun runDirectDoubleQuote() throws Exception { private void runDirectDoubleQuote_andFail() throws Exception { setupDoubleQuoteProject(); - j.assertBuildStatus(Result.FAILURE, project.scheduleBuild2(0)); + r.assertBuildStatus(Result.FAILURE, project.scheduleBuild2(0)); } private void setupDoubleQuoteProject() throws Exception { @@ -360,7 +362,7 @@ private void assertStringPresentInOrder(WorkflowRun run, String... values) throw } private void setupProject(String pipeline) throws Exception { - project = j.createProject(WorkflowJob.class); + project = r.createProject(WorkflowJob.class); project.setDefinition(new CpsFlowDefinition(pipeline, true)); } } diff --git a/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/BourneShellSecretPatternFactoryTest.java b/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/BourneShellSecretPatternFactoryTest.java index a6c1c0dc..b3d8b1b7 100644 --- a/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/BourneShellSecretPatternFactoryTest.java +++ b/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/BourneShellSecretPatternFactoryTest.java @@ -28,37 +28,35 @@ import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.experimental.theories.DataPoint; -import org.junit.experimental.theories.DataPoints; -import org.junit.experimental.theories.Theories; -import org.junit.experimental.theories.Theory; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.UUID; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.startsWith; -import static org.jenkinsci.plugins.credentialsbinding.test.Executables.executable; -import static org.junit.Assume.assumeThat; +import static org.jenkinsci.plugins.credentialsbinding.test.Executables.isExecutable; +import static org.junit.jupiter.api.Assumptions.assumeFalse; +import static org.junit.jupiter.api.Assumptions.assumeTrue; -@RunWith(Theories.class) -public class BourneShellSecretPatternFactoryTest { +@WithJenkins +class BourneShellSecretPatternFactoryTest { - public static final @DataPoint String SAMPLE_PASSWORD = "}#T14'GAz&H!{$U_"; - public static final @DataPoint String ANOTHER_SAMPLE_PASSWORD = "a'b\"c\\d(e)#"; + private static final String SAMPLE_PASSWORD = "}#T14'GAz&H!{$U_"; + private static final String ANOTHER_SAMPLE_PASSWORD = "a'b\"c\\d(e)#"; - @DataPoints - public static List generatePasswords() { + static List generatePasswords() { Random random = new Random(100); - List passwords = new ArrayList<>(10); + List passwords = new ArrayList<>(); + + passwords.add(SAMPLE_PASSWORD); + passwords.add(ANOTHER_SAMPLE_PASSWORD); + for (int i = 0; i < 10; i++) { int length = random.nextInt(24) + 8; StringBuilder sb = new StringBuilder(length); @@ -71,22 +69,23 @@ public static List generatePasswords() { return passwords; } - @Rule public JenkinsRule j = new JenkinsRule(); + private JenkinsRule r; private WorkflowJob project; private String credentialsId; - @BeforeClass - public static void assumeBash() { - assumeThat("sh", is(executable())); + @BeforeAll + static void beforeAll() { + assumeTrue(isExecutable("sh")); // due to https://github.com/jenkinsci/durable-task-plugin/blob/e75123eda986f20a390d92cc892c3d206e60aefb/src/main/java/org/jenkinsci/plugins/durabletask/BourneShellScript.java#L149 // on Windows - assumeThat("nohup", is(executable())); + assumeTrue(isExecutable("nohup")); } - @Before - public void setUp() throws Exception { - project = j.createProject(WorkflowJob.class); + @BeforeEach + void beforeEach(JenkinsRule rule) throws Exception { + r = rule; + project = r.createProject(WorkflowJob.class); credentialsId = UUID.randomUUID().toString(); project.setDefinition(new CpsFlowDefinition( "node {\n" + @@ -97,20 +96,21 @@ public void setUp() throws Exception { "}", true)); } - @Theory - public void credentialsAreMaskedInLogs(String credentials) throws Exception { - assumeThat(credentials, not(startsWith("****"))); + @ParameterizedTest + @MethodSource("generatePasswords") + void credentialsAreMaskedInLogs(String credentials) throws Exception { + assumeFalse(credentials.startsWith("****")); - CredentialsTestUtil.setStringCredentials(j.jenkins, credentialsId, credentials); + CredentialsTestUtil.setStringCredentials(r.jenkins, credentialsId, credentials); WorkflowRun run = runProject(); - j.assertLogContains(": ****", run); - j.assertLogContains("< **** >", run); - j.assertLogNotContains(credentials, run); + r.assertLogContains(": ****", run); + r.assertLogContains("< **** >", run); + r.assertLogNotContains(credentials, run); } private WorkflowRun runProject() throws Exception { - return j.assertBuildStatusSuccess(project.scheduleBuild2(0)); + return r.assertBuildStatusSuccess(project.scheduleBuild2(0)); } } diff --git a/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/DollarSecretPatternFactoryTest.java b/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/DollarSecretPatternFactoryTest.java index 2657ebf1..605a144b 100644 --- a/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/DollarSecretPatternFactoryTest.java +++ b/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/DollarSecretPatternFactoryTest.java @@ -15,21 +15,28 @@ import org.jenkinsci.plugins.credentialsbinding.impl.SecretBuildWrapper; import org.jenkinsci.plugins.credentialsbinding.impl.StringBinding; import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import java.util.Arrays; -public class DollarSecretPatternFactoryTest { +@WithJenkins +class DollarSecretPatternFactoryTest { + + private JenkinsRule r; - @Rule - public JenkinsRule r = new JenkinsRule(); + @BeforeEach + void beforeEach(JenkinsRule rule) { + r = rule; + } @Issue("JENKINS-24805") @Test - public void maskingFreeStyleSecrets() throws Exception { + void maskingFreeStyleSecrets() throws Exception { String firstCredentialsId = "creds_1"; String firstPassword = "a$build"; StringCredentialsImpl firstCreds = new StringCredentialsImpl(CredentialsScope.GLOBAL, firstCredentialsId, "sample1", Secret.fromString(firstPassword)); diff --git a/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/PowerShellMaskerProviderTest.java b/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/PowerShellMaskerProviderTest.java index 4f65c41b..6d7f7e72 100644 --- a/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/PowerShellMaskerProviderTest.java +++ b/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/PowerShellMaskerProviderTest.java @@ -28,71 +28,72 @@ import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import java.io.IOException; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.jenkinsci.plugins.credentialsbinding.test.Executables.executable; -import static org.junit.Assume.assumeThat; +import static org.jenkinsci.plugins.credentialsbinding.test.Executables.isExecutable; +import static org.junit.jupiter.api.Assumptions.assumeTrue; -public class PowerShellMaskerProviderTest { +@WithJenkins +class PowerShellMaskerProviderTest { private static final String SIMPLE = "abcABC123"; private static final String SAMPLE_PASSWORD = "}#T14'GAz&H!{$U_"; private static final String ALL_ASCII = "!\"#$%&'()*+,-./ 0123456789:;<=>? @ABCDEFGHIJKLMNO PQRSTUVWXYZ[\\]^_ `abcdefghijklmno pqrstuvwxyz{|}~"; - @Rule - public JenkinsRule j = new JenkinsRule(); + private JenkinsRule r; private WorkflowJob project; private String credentialPlainText; private String credentialId; - @Before - public void assumeWindowsForBatch() { + @BeforeEach + void beforeEach(JenkinsRule rule) { + r = rule; // TODO: pwsh is also a valid executable name // https://github.com/jenkinsci/durable-task-plugin/pull/88 - assumeThat("powershell", is(executable())); + assumeTrue(isExecutable("powershell")); } private void registerCredentials(String password) throws IOException { this.credentialPlainText = password; - this.credentialId = CredentialsTestUtil.registerStringCredentials(j.jenkins, password); + this.credentialId = CredentialsTestUtil.registerStringCredentials(r.jenkins, password); } @Test - public void simple() throws Exception { + void simple() throws Exception { registerCredentials(SIMPLE); assertDirectNoPlainTextButStars(runPowerShellInterpretation()); } - + @Test - public void allAscii() throws Exception { + void allAscii() throws Exception { registerCredentials(ALL_ASCII); assertDirectNoPlainTextButStars(runPowerShellInterpretation()); } - + @Test - public void samplePassword() throws Exception { + void samplePassword() throws Exception { registerCredentials(SAMPLE_PASSWORD); assertDirectNoPlainTextButStars(runPowerShellInterpretation()); } private void assertDirectNoPlainTextButStars(WorkflowRun run) throws Exception { - j.assertLogNotContains(credentialPlainText, run); + r.assertLogNotContains(credentialPlainText, run); // powershell x y z => output in 3 different lines assertStringPresentInOrder(run, "before1", "****", "after1"); - j.assertLogContains("before2 **** after2", run); + r.assertLogContains("before2 **** after2", run); } - private void assertStringPresentInOrder(WorkflowRun run, String... values) throws Exception { + private static void assertStringPresentInOrder(WorkflowRun run, String... values) throws Exception { String fullLog = run.getLog(); int currentIndex = 0; for (String currentValue : values) { @@ -119,11 +120,11 @@ private WorkflowRun runPowerShellInterpretation() throws Exception { " }\n" + "}" ); - return j.assertBuildStatusSuccess(project.scheduleBuild2(0)); + return r.assertBuildStatusSuccess(project.scheduleBuild2(0)); } private void setupProject(String pipeline) throws Exception { - project = j.createProject(WorkflowJob.class); + project = r.createProject(WorkflowJob.class); project.setDefinition(new CpsFlowDefinition(pipeline, true)); } } diff --git a/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/SecretPatternsTest.java b/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/SecretPatternsTest.java index 007e4680..89979eac 100644 --- a/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/SecretPatternsTest.java +++ b/src/test/java/org/jenkinsci/plugins/credentialsbinding/masking/SecretPatternsTest.java @@ -34,25 +34,43 @@ import org.jenkinsci.plugins.workflow.job.WorkflowRun; import org.jenkinsci.plugins.workflow.log.TaskListenerDecorator; import org.jenkinsci.plugins.workflow.steps.durable_task.DurableTaskStep; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.jvnet.hudson.test.BuildWatcher; -import org.jvnet.hudson.test.FlagRule; -import org.jvnet.hudson.test.InboundAgentRule; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; +import org.jvnet.hudson.test.junit.jupiter.BuildWatcherExtension; +import org.jvnet.hudson.test.junit.jupiter.InboundAgentExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; + +@WithJenkins +class SecretPatternsTest { -public final class SecretPatternsTest { + @SuppressWarnings("unused") + @RegisterExtension + private static final BuildWatcherExtension BUILD_WATCHER = new BuildWatcherExtension(); + private JenkinsRule r; + @RegisterExtension + private final InboundAgentExtension agents = new InboundAgentExtension(); + private boolean useWatching; + + @BeforeEach + void beforeEach(JenkinsRule rule) { + r = rule; + useWatching = DurableTaskStep.USE_WATCHING; + } - @ClassRule public static BuildWatcher watcher = new BuildWatcher(); - @Rule public JenkinsRule r = new JenkinsRule(); - @Rule public InboundAgentRule agents = new InboundAgentRule(); - @Rule public FlagRule useWatching = new FlagRule<>(() -> DurableTaskStep.USE_WATCHING, v -> DurableTaskStep.USE_WATCHING = v); + @AfterEach + void afterEach() { + DurableTaskStep.USE_WATCHING = useWatching; + } @Issue("SECURITY-3075") - @Test public void secretPatternFactoriesRetrievedFromAgent() throws Exception { + @Test + void secretPatternFactoriesRetrievedFromAgent() throws Exception { DurableTaskStep.USE_WATCHING = true; WorkflowJob p = r.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition("node('remote') {def msg = 'echo do not look at s3cr3t please'; if (isUnix()) {sh msg} else {bat msg}}", true)); @@ -69,12 +87,18 @@ public final class SecretPatternsTest { } public static final class BadMasker extends TaskListenerDecorator { - @Override public OutputStream decorate(OutputStream logger) throws IOException, InterruptedException { + + @Override + public OutputStream decorate(OutputStream logger) throws IOException, InterruptedException { Pattern pattern = SecretPatterns.getAggregateSecretPattern(Set.of("s3cr3t")); return new SecretPatterns.MaskingOutputStream(logger, () -> pattern, "UTF-8"); } - @TestExtension("secretPatternFactoriesRetrievedFromAgent") public static final class Factory implements TaskListenerDecorator.Factory { - @Override public TaskListenerDecorator of(FlowExecutionOwner owner) { + + @TestExtension("secretPatternFactoriesRetrievedFromAgent") + public static final class Factory implements TaskListenerDecorator.Factory { + + @Override + public TaskListenerDecorator of(FlowExecutionOwner owner) { return new BadMasker(); } } diff --git a/src/test/java/org/jenkinsci/plugins/credentialsbinding/test/Base64PatternTest.java b/src/test/java/org/jenkinsci/plugins/credentialsbinding/test/Base64PatternTest.java index 8348f3f6..2cae4e0e 100644 --- a/src/test/java/org/jenkinsci/plugins/credentialsbinding/test/Base64PatternTest.java +++ b/src/test/java/org/jenkinsci/plugins/credentialsbinding/test/Base64PatternTest.java @@ -1,16 +1,19 @@ package org.jenkinsci.plugins.credentialsbinding.test; import org.jenkinsci.plugins.credentialsbinding.masking.Base64SecretPatternFactory; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.nio.charset.StandardCharsets; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Base64; import java.util.Collection; -public class Base64PatternTest { +class Base64PatternTest { + @Test - public void checkSecretDetected() { + void checkSecretDetected() { assertBase64PatternFound("abcde", "abcde"); assertBase64PatternFound("abcde", "1abcde"); assertBase64PatternFound("abcde", "12abcde"); @@ -64,7 +67,7 @@ public void checkSecretDetected() { } @Test - public void checkSecretNotDetected() { + void checkSecretNotDetected() { assertBase64PatternNotFound("ab1cde", "abcde"); assertBase64PatternNotFound("ab1cde", "1abcde"); assertBase64PatternNotFound("ab1cde", "12abcde"); @@ -117,15 +120,15 @@ public void checkSecretNotDetected() { assertBase64PatternNotFound("b1cd", "123abcde123"); } - private void assertBase64PatternFound(String secret, String plainText) { - Assert.assertTrue("Pattern " + plainText + " not detected as containing " + secret, isPatternContainingSecret(secret, plainText)); + private static void assertBase64PatternFound(String secret, String plainText) { + assertTrue(isPatternContainingSecret(secret, plainText), "Pattern " + plainText + " not detected as containing " + secret); } - private void assertBase64PatternNotFound(String secret, String plainText) { - Assert.assertFalse("Pattern " + plainText + " was detected as containing " + secret, isPatternContainingSecret(secret, plainText)); + private static void assertBase64PatternNotFound(String secret, String plainText) { + assertFalse(isPatternContainingSecret(secret, plainText), "Pattern " + plainText + " was detected as containing " + secret); } - public boolean isPatternContainingSecret(String secret, String plainText) { + private static boolean isPatternContainingSecret(String secret, String plainText) { Base64SecretPatternFactory factory = new Base64SecretPatternFactory(); Collection allPatterns = factory.getBase64Forms(secret); diff --git a/src/test/java/org/jenkinsci/plugins/credentialsbinding/test/Executables.java b/src/test/java/org/jenkinsci/plugins/credentialsbinding/test/Executables.java index 34ddbfd8..15c1b1bd 100644 --- a/src/test/java/org/jenkinsci/plugins/credentialsbinding/test/Executables.java +++ b/src/test/java/org/jenkinsci/plugins/credentialsbinding/test/Executables.java @@ -28,18 +28,17 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Functions; import org.apache.commons.io.IOUtils; -import org.hamcrest.CustomTypeSafeMatcher; -import org.hamcrest.Matcher; import java.io.IOException; import java.nio.charset.Charset; import java.util.List; public class Executables { + private static final String LOCATOR = Functions.isWindows() ? "where.exe" : "which"; - public static @CheckForNull - String getPathToExecutable(@NonNull String executable) { + @CheckForNull + public static String getPathToExecutable(@NonNull String executable) { try { Process process = new ProcessBuilder(LOCATOR, executable).start(); List output = IOUtils.readLines(process.getInputStream(), Charset.defaultCharset()); @@ -52,16 +51,11 @@ String getPathToExecutable(@NonNull String executable) { } } - public static Matcher executable() { - return new CustomTypeSafeMatcher("executable") { - @Override - protected boolean matchesSafely(String item) { - try { - return new ProcessBuilder(LOCATOR, item).start().waitFor() == 0; - } catch (InterruptedException | IOException e) { - return false; - } - } - }; + public static boolean isExecutable(@NonNull String item) { + try { + return new ProcessBuilder(LOCATOR, item).start().waitFor() == 0; + } catch (InterruptedException | IOException e) { + return false; + } } }