diff --git a/pom.xml b/pom.xml index dc2dbd4129..c801218d67 100644 --- a/pom.xml +++ b/pom.xml @@ -51,6 +51,7 @@ Max Low false + false @@ -261,13 +262,7 @@ org.mockito - mockito-core - test - - - pl.pragmatists - JUnitParams - 1.1.1 + mockito-junit-jupiter test diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/AbstractGoldenFileTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/AbstractGoldenFileTest.java index b07385b128..749c25468f 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/AbstractGoldenFileTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/AbstractGoldenFileTest.java @@ -1,40 +1,39 @@ package org.csanchez.jenkins.plugins.kubernetes; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import edu.umd.cs.findbugs.annotations.NonNull; import io.fabric8.kubernetes.api.model.Pod; import io.fabric8.kubernetes.client.utils.Serialization; -import java.io.IOException; import java.nio.charset.StandardCharsets; import org.apache.commons.io.IOUtils; import org.csanchez.jenkins.plugins.kubernetes.pod.decorator.PodDecorator; -import org.junit.Before; +import org.junit.jupiter.api.BeforeEach; abstract class AbstractGoldenFileTest { protected KubernetesCloud cloud; protected PodDecorator decorator; - @Before - public void setUpCloud() { + @BeforeEach + void beforeEach() { decorator = newDecorator(); cloud = new KubernetesCloud("test"); } protected abstract PodDecorator newDecorator(); - protected void test(String name) throws IOException { + protected void test(String name) throws Exception { var beforeYAML = loadFileAsStream(name + "-before.yaml"); var before = Serialization.unmarshal(beforeYAML, Pod.class); - assertEquals(name + "-before.yaml is not normalized", Serialization.asYaml(before), beforeYAML); + assertEquals(Serialization.asYaml(before), beforeYAML, name + "-before.yaml is not normalized"); var afterYAML = loadFileAsStream(name + "-after.yaml"); var after = decorator.decorate(cloud, before); - assertEquals(name + "-after.yaml processed", Serialization.asYaml(after), afterYAML); + assertEquals(Serialization.asYaml(after), afterYAML, name + "-after.yaml processed"); } @NonNull - private String loadFileAsStream(String name) throws IOException { + private String loadFileAsStream(String name) throws Exception { var is = getClass().getResourceAsStream(getClass().getSimpleName() + "/" + name); if (is == null) { throw new IllegalStateException("Test file \"src/test/resources/" diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ClientAuthenticationTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ClientAuthenticationTest.java index f55cfa7c76..63d0aed2b2 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ClientAuthenticationTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ClientAuthenticationTest.java @@ -32,19 +32,16 @@ import io.fabric8.kubernetes.client.KubernetesClient; import java.net.URL; -import java.util.logging.Logger; import org.jenkinsci.plugins.kubernetes.auth.KubernetesAuthException; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.Issue; import org.mockito.MockedStatic; -public class ClientAuthenticationTest { - - private static final Logger LOGGER = Logger.getLogger(ClientAuthenticationTest.class.getName()); +class ClientAuthenticationTest { @Issue("JENKINS-76047") @Test - public void testConnectCallsCreateClient() throws Exception { + void testConnectCallsCreateClient() throws Exception { KubernetesClient mockClient = mock(KubernetesClient.class); when(mockClient.getMasterUrl()).thenReturn(new URL("http://localhost:9999/")); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ConfigMapVolumeTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ConfigMapVolumeTest.java index 1c7b1fefe4..1da6639286 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ConfigMapVolumeTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ConfigMapVolumeTest.java @@ -15,23 +15,24 @@ package org.csanchez.jenkins.plugins.kubernetes; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import org.csanchez.jenkins.plugins.kubernetes.volumes.ConfigMapVolume; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class ConfigMapVolumeTest { +class ConfigMapVolumeTest { @Test - public void testNullSubPathValue() { + void testNullSubPathValue() { ConfigMapVolume configMapVolume = new ConfigMapVolume("oneMountPath", "Myvolume", false); assertNull(configMapVolume.getSubPath()); } @Test - public void testValidSubPathValue() { + void testValidSubPathValue() { ConfigMapVolume configMapVolume = new ConfigMapVolume("oneMountPath", "Myvolume", false); configMapVolume.setSubPath("miSubpath"); - assertEquals(configMapVolume.getSubPath(), "miSubpath"); + assertEquals("miSubpath", configMapVolume.getSubPath()); } } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ContainerTemplateTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ContainerTemplateTest.java index a879f5d69e..7fe2a6cb3e 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ContainerTemplateTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ContainerTemplateTest.java @@ -15,16 +15,17 @@ package org.csanchez.jenkins.plugins.kubernetes; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import hudson.util.FormValidation; import java.util.Collections; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class ContainerTemplateTest { +class ContainerTemplateTest { @Test - public void testCopyConstructorCreatesEqualInstance() { + void testCopyConstructorCreatesEqualInstance() { ContainerTemplate originalTemplate = new ContainerTemplate("myname", "myimage"); originalTemplate.setPrivileged(true); originalTemplate.setAlwaysPullImage(true); @@ -43,31 +44,31 @@ public void testCopyConstructorCreatesEqualInstance() { ContainerTemplate clonedTemplate = new ContainerTemplate(originalTemplate); - assertEquals("Cloned ContainerTemplate is not equal to the original one!", originalTemplate, clonedTemplate); + assertEquals(originalTemplate, clonedTemplate, "Cloned ContainerTemplate is not equal to the original one!"); assertEquals( - "String representation (toString()) of the cloned and original ContainerTemplate is not equal!", originalTemplate.toString(), - clonedTemplate.toString()); + clonedTemplate.toString(), + "String representation (toString()) of the cloned and original ContainerTemplate is not equal!"); } @SuppressWarnings("ResultOfObjectAllocationIgnored") @Test - public void badImage() throws Exception { + void badImage() { new ContainerTemplate("n", "something"); assertEquals(FormValidation.Kind.OK, new ContainerTemplate.DescriptorImpl().doCheckImage("something").kind); for (String empty : new String[] {null, ""}) { - assertThrows("rejected " + empty, IllegalArgumentException.class, () -> new ContainerTemplate("n", empty)); + assertThrows(IllegalArgumentException.class, () -> new ContainerTemplate("n", empty), "rejected " + empty); assertEquals( - "tolerating " + empty + " during form validation", FormValidation.Kind.OK, - new ContainerTemplate.DescriptorImpl().doCheckImage(empty).kind); + new ContainerTemplate.DescriptorImpl().doCheckImage(empty).kind, + "tolerating " + empty + " during form validation"); } for (String bad : new String[] {" ", " something"}) { - assertThrows("rejected " + bad, IllegalArgumentException.class, () -> new ContainerTemplate("n", bad)); + assertThrows(IllegalArgumentException.class, () -> new ContainerTemplate("n", bad), "rejected " + bad); assertEquals( - "rejected " + bad, FormValidation.Kind.ERROR, - new ContainerTemplate.DescriptorImpl().doCheckImage(bad).kind); + new ContainerTemplate.DescriptorImpl().doCheckImage(bad).kind, + "rejected " + bad); } } } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubectlBuildWrapperTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubectlBuildWrapperTest.java index 140898bc80..45505a8a13 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubectlBuildWrapperTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubectlBuildWrapperTest.java @@ -2,19 +2,20 @@ import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.deletePods; import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.getLabels; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotNull; import com.cloudbees.plugins.credentials.CredentialsScope; import com.cloudbees.plugins.credentials.SystemCredentialsProvider; import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl; import hudson.model.Result; import org.csanchez.jenkins.plugins.kubernetes.pipeline.AbstractKubernetesPipelineTest; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class KubectlBuildWrapperTest extends AbstractKubernetesPipelineTest { - @Before - public void setUp() throws Exception { +class KubectlBuildWrapperTest extends AbstractKubernetesPipelineTest { + + @BeforeEach + void beforeEach() throws Exception { deletePods(cloud.connect(), getLabels(cloud, this, name), false); assertNotNull(createJobThenScheduleRun()); UsernamePasswordCredentialsImpl creds = new UsernamePasswordCredentialsImpl( @@ -23,13 +24,13 @@ public void setUp() throws Exception { } @Test - public void kubectlBuildWrapper_missingCredentials() throws Exception { + void kubectlBuildWrapper_missingCredentials() throws Exception { r.assertBuildStatus(Result.FAILURE, r.waitForCompletion(b)); r.assertLogContains("No credentials found for id \"abcd\"", b); } @Test - public void kubectlBuildWrapper_invalidCredentials() throws Exception { + void kubectlBuildWrapper_invalidCredentials() throws Exception { r.assertBuildStatus(Result.FAILURE, r.waitForCompletion(b)); r.assertLogContains("Unable to connect to the server", b); } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesClientProviderTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesClientProviderTest.java index b732454ebb..a05a7cf228 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesClientProviderTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesClientProviderTest.java @@ -23,17 +23,15 @@ */ package org.csanchez.jenkins.plugins.kubernetes; -import static org.junit.Assert.assertEquals; - import java.util.function.Consumer; import org.csanchez.jenkins.plugins.kubernetes.pod.retention.Always; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; -public class KubernetesClientProviderTest { +class KubernetesClientProviderTest { @Test - public void testGetValidity() { + void testGetValidity() { KubernetesCloud cloud = new KubernetesCloud("foo"); // changes to these properties should trigger different validity value checkValidityChanges( @@ -60,15 +58,16 @@ public void testGetValidity() { c -> c.setDirectConnection(true)); // verify stability - assertEquals(KubernetesClientProvider.getValidity(cloud), KubernetesClientProvider.getValidity(cloud)); + Assertions.assertEquals( + KubernetesClientProvider.getValidity(cloud), KubernetesClientProvider.getValidity(cloud)); } private void checkValidityChanges(KubernetesCloud cloud, Consumer... mutations) { - checkValidity(cloud, Assert::assertNotEquals, mutations); + checkValidity(cloud, Assertions::assertNotEquals, mutations); } private void checkValidityDoesNotChange(KubernetesCloud cloud, Consumer... mutations) { - checkValidity(cloud, Assert::assertEquals, mutations); + checkValidity(cloud, Assertions::assertEquals, mutations); } private void checkValidity( @@ -78,12 +77,12 @@ private void checkValidity( for (Consumer mut : mutations) { mut.accept(cloud); int after = KubernetesClientProvider.getValidity(cloud); - validityAssertion.doAssert("change #" + count++ + " of " + mutations.length, v, after); + validityAssertion.doAssert(v, after, "change #" + count++ + " of " + mutations.length); v = after; } } interface ValidityAssertion { - void doAssert(String message, int before, int after); + void doAssert(int before, int after, String message); } } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudFIPSTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudFIPSTest.java index e9c3797356..8602dd6543 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudFIPSTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudFIPSTest.java @@ -4,54 +4,72 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertThrows; +import static org.junit.jupiter.api.Assertions.assertThrows; import hudson.ExtensionList; import io.jenkins.cli.shaded.org.apache.commons.io.FileUtils; -import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.Paths; import jenkins.security.FIPS140; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.jvnet.hudson.test.FlagRule; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +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 org.jvnet.hudson.test.recipes.LocalData; -public class KubernetesCloudFIPSTest { +@WithJenkins +class KubernetesCloudFIPSTest { - @ClassRule - public static FlagRule fipsFlag = FlagRule.systemProperty(FIPS140.class.getName() + ".COMPLIANCE", "true"); + private static String fipsFlag; - @Rule - public JenkinsRule r = new JenkinsRule(); + private JenkinsRule r; + + @BeforeAll + static void beforeAll() { + fipsFlag = System.setProperty(FIPS140.class.getName() + ".COMPLIANCE", "true"); + } + + @BeforeEach + void beforeEach(JenkinsRule rule) { + r = rule; + } + + @AfterAll + static void afterAll() { + if (fipsFlag != null) { + System.setProperty(FIPS140.class.getName() + ".COMPLIANCE", fipsFlag); + } else { + System.clearProperty(FIPS140.class.getName() + ".COMPLIANCE"); + } + } @Test @Issue("JENKINS-73460") - public void onlyFipsCompliantValuesAreAcceptedTest() throws IOException { + void onlyFipsCompliantValuesAreAcceptedTest() throws Exception { KubernetesCloud cloud = new KubernetesCloud("test-cloud"); assertThrows(IllegalArgumentException.class, () -> cloud.setSkipTlsVerify(true)); cloud.setSkipTlsVerify(false); assertThrows(IllegalArgumentException.class, () -> cloud.setServerUrl("http://example.org")); cloud.setServerUrl("https://example.org"); assertThrows( - "Invalid certificates throw exception", IllegalArgumentException.class, - () -> cloud.setServerCertificate(getCert("not-a-cert"))); + () -> cloud.setServerCertificate(getCert("not-a-cert")), + "Invalid certificates throw exception"); Throwable exception = assertThrows( - "Invalid length", IllegalArgumentException.class, () -> cloud.setServerCertificate(getCert("rsa1024"))); + IllegalArgumentException.class, () -> cloud.setServerCertificate(getCert("rsa1024")), "Invalid length"); assertThat(exception.getLocalizedMessage(), containsString("2048")); cloud.setServerCertificate(getCert("rsa2048")); exception = assertThrows( - "invalid length", IllegalArgumentException.class, () -> cloud.setServerCertificate(getCert("dsa1024"))); + IllegalArgumentException.class, () -> cloud.setServerCertificate(getCert("dsa1024")), "invalid length"); assertThat(exception.getLocalizedMessage(), containsString("2048")); cloud.setServerCertificate(getCert("dsa2048")); exception = assertThrows( - "Invalid field size", IllegalArgumentException.class, - () -> cloud.setServerCertificate(getCert("ecdsa192"))); + () -> cloud.setServerCertificate(getCert("ecdsa192")), + "Invalid field size"); assertThat(exception.getLocalizedMessage(), containsString("224")); cloud.setServerCertificate(getCert("ecdsa224")); } @@ -59,7 +77,7 @@ public void onlyFipsCompliantValuesAreAcceptedTest() throws IOException { @Test @Issue("JENKINS-73460") @LocalData - public void nonCompliantCloudsAreCleanedTest() { + void nonCompliantCloudsAreCleanedTest() { assertThat("compliant-cloud is loaded", r.jenkins.getCloud("compliant-cloud"), notNullValue()); assertThat( "no certificate is a valid cloud", @@ -72,7 +90,7 @@ public void nonCompliantCloudsAreCleanedTest() { @Test @Issue("JENKINS-73460") - public void formValidationTest() throws IOException { + void formValidationTest() throws Exception { ExtensionList descriptors = ExtensionList.lookup(KubernetesCloud.DescriptorImpl.class); KubernetesCloud.DescriptorImpl descriptor = descriptors.stream() @@ -109,7 +127,7 @@ public void formValidationTest() throws IOException { notNullValue()); } - private String getCert(String alg) throws IOException { + private String getCert(String alg) throws Exception { return FileUtils.readFileToString( Paths.get("src/test/resources/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudFIPSTest/certs") .resolve(alg) diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudTest.java index 20a255fbc0..3032d6bf6d 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudTest.java @@ -2,11 +2,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.*; import edu.umd.cs.findbugs.annotations.NonNull; import hudson.model.User; @@ -14,7 +10,6 @@ import hudson.security.ACLContext; import hudson.security.AccessDeniedException3; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; @@ -39,31 +34,37 @@ import org.htmlunit.html.HtmlForm; import org.htmlunit.html.HtmlInput; import org.htmlunit.html.HtmlPage; -import org.junit.After; -import org.junit.Rule; -import org.junit.Test; -import org.junit.function.ThrowingRunnable; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.LoggerRule; +import org.jvnet.hudson.test.LogRecorder; import org.jvnet.hudson.test.MockAuthorizationStrategy; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.jvnet.hudson.test.recipes.LocalData; -public class KubernetesCloudTest { +@WithJenkins +class KubernetesCloudTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + private JenkinsRule j; - @Rule - public LoggerRule logs = new LoggerRule() + @SuppressWarnings("unused") + private final LogRecorder logs = new LogRecorder() .record(Logger.getLogger(KubernetesCloud.class.getPackage().getName()), Level.ALL); - @After - public void tearDown() { + @BeforeEach + void beforeEach(JenkinsRule rule) { + j = rule; + } + + @AfterEach + void afterEach() { System.getProperties().remove("KUBERNETES_JENKINS_URL"); } @Test - public void configRoundTrip() throws Exception { + void configRoundTrip() throws Exception { var cloud = new KubernetesCloud("kubernetes"); var podTemplate = new PodTemplate(); podTemplate.setName("test-template"); @@ -77,8 +78,7 @@ public void configRoundTrip() throws Exception { } @Test - public void testInheritance() { - + void testInheritance() { ContainerTemplate jnlp = new ContainerTemplate("jnlp", "jnlp:1"); ContainerTemplate maven = new ContainerTemplate("maven", "maven:1"); maven.setTtyEnabled(true); @@ -88,26 +88,25 @@ public void testInheritance() { PodTemplate parent = new PodTemplate(); parent.setName("parent"); parent.setLabel("parent"); - parent.setContainers(Arrays.asList(jnlp)); - parent.setVolumes(Arrays.asList(podVolume)); + parent.setContainers(List.of(jnlp)); + parent.setVolumes(List.of(podVolume)); ContainerTemplate maven2 = new ContainerTemplate("maven", "maven:2"); PodTemplate withNewMavenVersion = new PodTemplate(); - withNewMavenVersion.setContainers(Arrays.asList(maven2)); + withNewMavenVersion.setContainers(List.of(maven2)); PodTemplate result = PodTemplateUtils.combine(parent, withNewMavenVersion); } - @Test(expected = IllegalStateException.class) - public void getJenkinsUrlOrDie_NoJenkinsUrl() { + @Test + void getJenkinsUrlOrDie_NoJenkinsUrl() { JenkinsLocationConfiguration.get().setUrl(null); KubernetesCloud cloud = new KubernetesCloud("name"); - String url = cloud.getJenkinsUrlOrDie(); - fail("Should have thrown IllegalStateException at this point but got " + url + " instead."); + assertThrows(IllegalStateException.class, () -> cloud.getJenkinsUrlOrDie()); } @Test - public void getJenkinsUrlOrDie_UrlInCloud() { + void getJenkinsUrlOrDie_UrlInCloud() { System.setProperty("KUBERNETES_JENKINS_URL", "http://mylocationinsysprop"); KubernetesCloud cloud = new KubernetesCloud("name"); cloud.setJenkinsUrl("http://mylocation"); @@ -115,21 +114,21 @@ public void getJenkinsUrlOrDie_UrlInCloud() { } @Test - public void getJenkinsUrlOrDie_UrlInSysprop() { + void getJenkinsUrlOrDie_UrlInSysprop() { System.setProperty("KUBERNETES_JENKINS_URL", "http://mylocation"); KubernetesCloud cloud = new KubernetesCloud("name"); assertEquals("http://mylocation/", cloud.getJenkinsUrlOrDie()); } @Test - public void getJenkinsUrlOrDie_UrlInLocation() { + void getJenkinsUrlOrDie_UrlInLocation() { JenkinsLocationConfiguration.get().setUrl("http://mylocation"); KubernetesCloud cloud = new KubernetesCloud("name"); assertEquals("http://mylocation/", cloud.getJenkinsUrlOrDie()); } @Test - public void getJenkinsUrlOrNull_NoJenkinsUrl() { + void getJenkinsUrlOrNull_NoJenkinsUrl() { JenkinsLocationConfiguration.get().setUrl(null); KubernetesCloud cloud = new KubernetesCloud("name"); String url = cloud.getJenkinsUrlOrNull(); @@ -137,7 +136,7 @@ public void getJenkinsUrlOrNull_NoJenkinsUrl() { } @Test - public void getJenkinsUrlOrNull_UrlInCloud() { + void getJenkinsUrlOrNull_UrlInCloud() { System.setProperty("KUBERNETES_JENKINS_URL", "http://mylocationinsysprop"); KubernetesCloud cloud = new KubernetesCloud("name"); cloud.setJenkinsUrl("http://mylocation"); @@ -145,27 +144,27 @@ public void getJenkinsUrlOrNull_UrlInCloud() { } @Test - public void getJenkinsUrlOrNull_UrlInSysprop() { + void getJenkinsUrlOrNull_UrlInSysprop() { System.setProperty("KUBERNETES_JENKINS_URL", "http://mylocation"); KubernetesCloud cloud = new KubernetesCloud("name"); assertEquals("http://mylocation/", cloud.getJenkinsUrlOrNull()); } @Test - public void getJenkinsUrlOrNull_UrlInLocation() { + void getJenkinsUrlOrNull_UrlInLocation() { JenkinsLocationConfiguration.get().setUrl("http://mylocation"); KubernetesCloud cloud = new KubernetesCloud("name"); assertEquals("http://mylocation/", cloud.getJenkinsUrlOrNull()); } @Test - public void testKubernetesCloudDefaults() { + void testKubernetesCloudDefaults() { KubernetesCloud cloud = new KubernetesCloud("name"); assertEquals(PodRetention.getKubernetesCloudDefault(), cloud.getPodRetention()); } @Test - public void testPodLabels() { + void testPodLabels() { List defaultPodLabelsList = PodLabel.fromMap(KubernetesCloud.DEFAULT_POD_LABELS); KubernetesCloud cloud = new KubernetesCloud("name"); assertEquals(KubernetesCloud.DEFAULT_POD_LABELS, cloud.getPodLabelsMap()); @@ -192,7 +191,7 @@ public void testPodLabels() { } @Test - public void testLabels() { + void testLabels() { KubernetesCloud cloud = new KubernetesCloud("name"); List labels = PodLabel.listOf("foo", "bar", "cat", "dog"); @@ -215,7 +214,7 @@ public void testLabels() { } @Test - public void copyConstructor() throws Exception { + void copyConstructor() throws Exception { PodTemplate pt = new PodTemplate(); pt.setName("podTemplate"); @@ -236,7 +235,7 @@ public void copyConstructor() throws Exception { } else if (propertyType == int.class) { PropertyUtils.setProperty(cloud, property, RandomUtils.nextInt()); } else if (propertyType == Integer.class) { - PropertyUtils.setProperty(cloud, property, Integer.valueOf(RandomUtils.nextInt())); + PropertyUtils.setProperty(cloud, property, RandomUtils.nextInt()); } else if (propertyType == boolean.class) { PropertyUtils.setProperty(cloud, property, RandomUtils.nextBoolean()); } else if (!objectProperties.contains(property)) { @@ -253,12 +252,12 @@ public void copyConstructor() throws Exception { KubernetesCloud copy = new KubernetesCloud("copy", cloud); assertEquals("copy", copy.name); assertTrue( - "Expected cloud from copy constructor to be equal to the source except for name", - EqualsBuilder.reflectionEquals(cloud, copy, true, KubernetesCloud.class, "name")); + EqualsBuilder.reflectionEquals(cloud, copy, true, KubernetesCloud.class, "name"), + "Expected cloud from copy constructor to be equal to the source except for name"); } @Test - public void defaultWorkspaceVolume() throws Exception { + void defaultWorkspaceVolume() throws Exception { KubernetesCloud cloud = new KubernetesCloud("kubernetes"); j.jenkins.clouds.add(cloud); j.jenkins.save(); @@ -282,11 +281,11 @@ public void defaultWorkspaceVolume() throws Exception { assertEquals("default-workspace", podTemplate.getName()); p = wc.goTo("cloud/kubernetes/templates"); DomElement row = p.getElementById("template_" + podTemplate.getId()); - assertTrue(row != null); + assertNotNull(row); } @Test - public void minRetentionTimeout() { + void minRetentionTimeout() { KubernetesCloud cloud = new KubernetesCloud("kubernetes"); assertEquals(KubernetesCloud.DEFAULT_RETENTION_TIMEOUT_MINUTES, cloud.getRetentionTimeout()); cloud.setRetentionTimeout(0); @@ -295,7 +294,7 @@ public void minRetentionTimeout() { @Test @LocalData - public void emptyKubernetesCloudReadResolve() { + void emptyKubernetesCloudReadResolve() { KubernetesCloud cloud = j.jenkins.clouds.get(KubernetesCloud.class); assertEquals(KubernetesCloud.DEFAULT_RETENTION_TIMEOUT_MINUTES, cloud.getRetentionTimeout()); assertEquals(Integer.MAX_VALUE, cloud.getContainerCap()); @@ -306,9 +305,9 @@ public void emptyKubernetesCloudReadResolve() { @Test @LocalData - public void readResolveContainerCapZero() { + void readResolveContainerCapZero() { KubernetesCloud cloud = j.jenkins.clouds.get(KubernetesCloud.class); - assertEquals(cloud.getContainerCap(), Integer.MAX_VALUE); + assertEquals(Integer.MAX_VALUE, cloud.getContainerCap()); } public HtmlInput getInputByName(DomElement root, String name) { @@ -322,7 +321,7 @@ public HtmlInput getInputByName(DomElement root, String name) { } @Test - public void authorization() throws Exception { + void authorization() { var securityRealm = j.createDummySecurityRealm(); j.jenkins.setSecurityRealm(securityRealm); var authorizationStrategy = new MockAuthorizationStrategy(); @@ -348,10 +347,9 @@ public void authorization() throws Exception { } } - private static void assertAccessDenied(ThrowingRunnable throwingRunnable, String expectedMessage) { + private static void assertAccessDenied(Executable executable, String expectedMessage) { assertThat( - assertThrows(AccessDeniedException3.class, throwingRunnable).getMessage(), - containsString(expectedMessage)); + assertThrows(AccessDeniedException3.class, executable).getMessage(), containsString(expectedMessage)); } private static @NonNull ACLContext asUser(String admin) { diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudTraitTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudTraitTest.java index ee3e41dad1..20e2844706 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudTraitTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudTraitTest.java @@ -2,40 +2,44 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import edu.umd.cs.findbugs.annotations.NonNull; import hudson.ExtensionList; import java.util.List; import java.util.Optional; -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.TestExtension; import org.jvnet.hudson.test.WithoutJenkins; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.kohsuke.stapler.DataBoundConstructor; -public class KubernetesCloudTraitTest { +@WithJenkins +class KubernetesCloudTraitTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + private JenkinsRule j; + + @BeforeEach + void beforeEach(JenkinsRule rule) { + j = rule; + } @Test - public void testKubernetesCloudAll() { + void testKubernetesCloudAll() { assertEquals(2, KubernetesCloudTrait.all().size()); } @Test - public void testKubernetesCloudDescriptorAllTraits() { + void testKubernetesCloudDescriptorAllTraits() { var descriptors = ExtensionList.lookup(KubernetesCloud.DescriptorImpl.class); assertThat(descriptors.size(), greaterThanOrEqualTo(1)); assertEquals(2, descriptors.get(0).getAllTraits().size()); } @Test - public void testKubernetesCloudDescriptorDefaultTraits() { + void testKubernetesCloudDescriptorDefaultTraits() { var descriptors = ExtensionList.lookup(KubernetesCloud.DescriptorImpl.class); assertThat(descriptors.size(), greaterThanOrEqualTo(1)); var traits = descriptors.get(0).getDefaultTraits(); @@ -47,7 +51,7 @@ public void testKubernetesCloudDescriptorDefaultTraits() { @WithoutJenkins @Test - public void testKubernetesCloudTraits() { + void testKubernetesCloudTraits() { var cloud = new KubernetesCloud("Foo"); // empty optional when trait instance not found diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesFactoryAdapterTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesFactoryAdapterTest.java index 4272c2f9ce..32634f3ff1 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesFactoryAdapterTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesFactoryAdapterTest.java @@ -33,10 +33,7 @@ import static io.fabric8.kubernetes.client.Config.KUBERNETES_PROXY_USERNAME; import static io.fabric8.kubernetes.client.Config.KUBERNETES_SERVICE_HOST_PROPERTY; import static io.fabric8.kubernetes.client.Config.KUBERNETES_SERVICE_PORT_PROPERTY; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import com.cloudbees.plugins.credentials.CredentialsScope; import com.cloudbees.plugins.credentials.SystemCredentialsProvider; @@ -46,19 +43,19 @@ import io.fabric8.kubernetes.client.KubernetesClient; import java.util.HashMap; import java.util.Map; -import org.jenkinsci.plugins.kubernetes.auth.KubernetesAuthException; import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +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; /** * Test the creation of clients */ -public class KubernetesFactoryAdapterTest { +@WithJenkins +class KubernetesFactoryAdapterTest { private static final String[] SYSTEM_PROPERTY_NAMES = new String[] { // KUBERNETES_KUBECONFIG_FILE, // @@ -79,13 +76,14 @@ public class KubernetesFactoryAdapterTest { private static final String KUBERNETES_PORT = "443"; private static final String KUBERNETES_MASTER_URL = "https://" + KUBERNETES_HOST + ":" + KUBERNETES_PORT + "/"; - private Map systemProperties = new HashMap<>(); + private final Map systemProperties = new HashMap<>(); - @Rule - public JenkinsRule j = new JenkinsRule(); + private JenkinsRule j; + + @BeforeEach + void beforeEach(JenkinsRule rule) { + j = rule; - @Before - public void saveSystemProperties() { for (String key : SYSTEM_PROPERTY_NAMES) { systemProperties.put(key, System.getProperty(key)); // use bogus values to avoid influence from environment @@ -102,8 +100,8 @@ public void saveSystemProperties() { System.setProperty(KUBERNETES_SERVICE_PORT_PROPERTY, KUBERNETES_PORT); } - @After - public void restoreSystemProperties() { + @AfterEach + void afterEach() { for (String key : systemProperties.keySet()) { String s = systemProperties.get(key); if (s != null) { @@ -115,7 +113,7 @@ public void restoreSystemProperties() { } @Test - public void defaultNamespace() throws Exception { + void defaultNamespace() throws Exception { KubernetesFactoryAdapter factory = new KubernetesFactoryAdapter(null, null, null, false); KubernetesClient client = factory.createClient(); assertEquals("default", client.getNamespace()); @@ -124,7 +122,7 @@ public void defaultNamespace() throws Exception { } @Test - public void autoConfig() throws Exception { + void autoConfig() throws Exception { System.setProperty(KUBERNETES_NAMESPACE_FILE, "src/test/resources/kubenamespace"); KubernetesFactoryAdapter factory = new KubernetesFactoryAdapter(null, null, null, false); KubernetesClient client = factory.createClient(); @@ -139,7 +137,7 @@ public void autoConfig() throws Exception { } @Test - public void autoConfigWithMasterUrl() throws Exception { + void autoConfigWithMasterUrl() throws Exception { KubernetesFactoryAdapter factory = new KubernetesFactoryAdapter("http://example.com", null, null, false); KubernetesClient client = factory.createClient(); assertEquals(HTTP_PROXY, client.getConfiguration().getHttpProxy()); @@ -183,7 +181,7 @@ public void autoConfigWithKubeconfig() throws Exception { @Test @Issue("JENKINS-70416") - public void autoConfigWithAuth() throws Exception { + void autoConfigWithAuth() throws Exception { System.setProperty(KUBERNETES_NAMESPACE_FILE, "src/test/resources/kubenamespace"); StringCredentialsImpl tokenCredential = new StringCredentialsImpl( CredentialsScope.GLOBAL, "sa-token", "some credentials", Secret.fromString("sa-token")); @@ -203,8 +201,7 @@ public void autoConfigWithAuth() throws Exception { @Test @Issue("JENKINS-70563") - public void jenkinsProxyConfiguration() throws KubernetesAuthException { - + void jenkinsProxyConfiguration() throws Exception { j.jenkins.setProxy(new ProxyConfiguration( "proxy.com", 123, PROXY_USERNAME, PROXY_PASSWORD, "*acme.com\n*acme*.com\n*.example.com|192.168.*")); KubernetesFactoryAdapter factory = diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesFolderPropertyTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesFolderPropertyTest.java index 188a3b233e..0a51a1fddd 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesFolderPropertyTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesFolderPropertyTest.java @@ -8,17 +8,23 @@ import com.cloudbees.hudson.plugins.folder.Folder; import java.util.Collections; -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; -public class KubernetesFolderPropertyTest { +@WithJenkins +class KubernetesFolderPropertyTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + private JenkinsRule j; + + @BeforeEach + void beforeEach(JenkinsRule rule) { + j = rule; + } @Test - public void propertySavedOnFirstSaveTest() throws Exception { + void propertySavedOnFirstSaveTest() throws Exception { KubernetesCloud kube1 = new KubernetesCloud("kube1"); kube1.setUsageRestricted(true); KubernetesCloud kube2 = new KubernetesCloud("kube2"); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesProvisioningLimitsTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesProvisioningLimitsTest.java index 6e42cb7974..6fe2a3981c 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesProvisioningLimitsTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesProvisioningLimitsTest.java @@ -1,7 +1,7 @@ package org.csanchez.jenkins.plugins.kubernetes; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.List; import java.util.concurrent.CompletionService; @@ -11,21 +11,27 @@ import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; import java.util.logging.Level; -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.LoggerRule; +import org.jvnet.hudson.test.LogRecorder; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; -public class KubernetesProvisioningLimitsTest { +@WithJenkins +class KubernetesProvisioningLimitsTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + @SuppressWarnings("unused") + private final LogRecorder log = new LogRecorder().record(KubernetesProvisioningLimits.class, Level.FINEST); - @Rule - public LoggerRule log = new LoggerRule().record(KubernetesProvisioningLimits.class, Level.FINEST); + private JenkinsRule j; + + @BeforeEach + void beforeEach(JenkinsRule rule) { + j = rule; + } @Test - public void lotsOfCloudsAndTemplates() throws InterruptedException { + void lotsOfCloudsAndTemplates() throws Exception { ThreadLocalRandom testRandom = ThreadLocalRandom.current(); for (int i = 1; i < 4; i++) { KubernetesCloud cloud = new KubernetesCloud("kubernetes-" + i); @@ -61,11 +67,7 @@ public void lotsOfCloudsAndTemplates() throws InterruptedException { } } - ecs.submit( - () -> { - kubernetesProvisioningLimits.unregister(cloud, podTemplate, 1); - }, - null); + ecs.submit(() -> kubernetesProvisioningLimits.unregister(cloud, podTemplate, 1), null); }, null); } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesQueueTaskDispatcherTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesQueueTaskDispatcherTest.java index 9359711432..a9c6a919f8 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesQueueTaskDispatcherTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesQueueTaskDispatcherTest.java @@ -1,6 +1,7 @@ package org.csanchez.jenkins.plugins.kubernetes; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.mockito.Mockito.when; import com.cloudbees.hudson.plugins.folder.Folder; @@ -16,21 +17,18 @@ import net.sf.json.JSONObject; import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.support.steps.ExecutorStepExecution; -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.ExtendWith; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.kohsuke.stapler.StaplerRequest2; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; +import org.mockito.junit.jupiter.MockitoExtension; -public class KubernetesQueueTaskDispatcherTest { - - @Rule - public JenkinsRule jenkins = new JenkinsRule(); - - @Rule - public MockitoRule mockitoRule = MockitoJUnit.rule(); +@WithJenkins +@ExtendWith(MockitoExtension.class) +class KubernetesQueueTaskDispatcherTest { @Mock private ExecutorStepExecution.PlaceholderTask task; @@ -40,11 +38,18 @@ public class KubernetesQueueTaskDispatcherTest { private KubernetesSlave slaveA; private KubernetesSlave slaveB; - public void setUpTwoClouds() throws Exception { - folderA = new Folder(jenkins.jenkins, "A"); - folderB = new Folder(jenkins.jenkins, "B"); - jenkins.jenkins.add(folderA, "Folder A"); - jenkins.jenkins.add(folderB, "Folder B"); + private JenkinsRule j; + + @BeforeEach + void beforeEach(JenkinsRule rule) { + j = rule; + } + + private void setUpTwoClouds() throws Exception { + folderA = new Folder(j.jenkins, "A"); + folderB = new Folder(j.jenkins, "B"); + j.jenkins.add(folderA, "Folder A"); + j.jenkins.add(folderB, "Folder B"); KubernetesCloud cloudA = new KubernetesCloud("A"); cloudA.setUsageRestricted(true); @@ -52,8 +57,8 @@ public void setUpTwoClouds() throws Exception { KubernetesCloud cloudB = new KubernetesCloud("B"); cloudB.setUsageRestricted(true); - jenkins.jenkins.clouds.add(cloudA); - jenkins.jenkins.clouds.add(cloudB); + j.jenkins.clouds.add(cloudA); + j.jenkins.clouds.add(cloudB); KubernetesFolderProperty property1 = new KubernetesFolderProperty(); folderA.addProperty(property1); @@ -76,7 +81,7 @@ public void setUpTwoClouds() throws Exception { } @Test - public void checkRestrictedTwoClouds() throws Exception { + void checkRestrictedTwoClouds() throws Exception { setUpTwoClouds(); FreeStyleProject projectA = folderA.createProject(FreeStyleProject.class, "buildJob"); @@ -86,23 +91,21 @@ public void checkRestrictedTwoClouds() throws Exception { assertNull(dispatcher.canTake( slaveA, new Queue.BuildableItem(new Queue.WaitingItem(Calendar.getInstance(), projectA, new ArrayList<>())))); - assertTrue( - canTake(dispatcher, slaveB, projectA) - instanceof KubernetesQueueTaskDispatcher.KubernetesCloudNotAllowed); - assertTrue( - canTake(dispatcher, slaveA, projectB) - instanceof KubernetesQueueTaskDispatcher.KubernetesCloudNotAllowed); + assertInstanceOf( + KubernetesQueueTaskDispatcher.KubernetesCloudNotAllowed.class, canTake(dispatcher, slaveB, projectA)); + assertInstanceOf( + KubernetesQueueTaskDispatcher.KubernetesCloudNotAllowed.class, canTake(dispatcher, slaveA, projectB)); assertNull(canTake(dispatcher, slaveB, projectB)); } @Test - public void checkNotRestrictedClouds() throws Exception { - Folder folder = new Folder(jenkins.jenkins, "C"); + void checkNotRestrictedClouds() throws Exception { + Folder folder = new Folder(j.jenkins, "C"); FreeStyleProject project = folder.createProject(FreeStyleProject.class, "buildJob"); - jenkins.jenkins.add(folder, "C"); + j.jenkins.add(folder, "C"); KubernetesCloud cloud = new KubernetesCloud("C"); cloud.setUsageRestricted(false); - jenkins.jenkins.clouds.add(cloud); + j.jenkins.clouds.add(cloud); KubernetesQueueTaskDispatcher dispatcher = new KubernetesQueueTaskDispatcher(); KubernetesSlave slave = new KubernetesSlave( "C", new PodTemplate(), "testC", "C", "dockerC", new KubernetesLauncher(), RetentionStrategy.INSTANCE); @@ -111,16 +114,16 @@ public void checkNotRestrictedClouds() throws Exception { } @Test - public void checkDumbSlave() throws Exception { - DumbSlave slave = jenkins.createOnlineSlave(); - FreeStyleProject project = jenkins.createProject(FreeStyleProject.class); + void checkDumbSlave() throws Exception { + DumbSlave slave = j.createOnlineSlave(); + FreeStyleProject project = j.createProject(FreeStyleProject.class); KubernetesQueueTaskDispatcher dispatcher = new KubernetesQueueTaskDispatcher(); assertNull(canTake(dispatcher, slave, project)); } @Test - public void checkPipelinesRestrictedTwoClouds() throws Exception { + void checkPipelinesRestrictedTwoClouds() throws Exception { setUpTwoClouds(); WorkflowJob job = folderA.createProject(WorkflowJob.class, "pipeline"); @@ -128,8 +131,8 @@ public void checkPipelinesRestrictedTwoClouds() throws Exception { KubernetesQueueTaskDispatcher dispatcher = new KubernetesQueueTaskDispatcher(); assertNull(canTake(dispatcher, slaveA, task)); - assertTrue( - canTake(dispatcher, slaveB, task) instanceof KubernetesQueueTaskDispatcher.KubernetesCloudNotAllowed); + assertInstanceOf( + KubernetesQueueTaskDispatcher.KubernetesCloudNotAllowed.class, canTake(dispatcher, slaveB, task)); } private CauseOfBlockage canTake(KubernetesQueueTaskDispatcher dispatcher, Slave slave, Project project) { diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesRestartTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesRestartTest.java index 8a7ed9a05a..2893f72f2a 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesRestartTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesRestartTest.java @@ -25,23 +25,23 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasSize; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.List; import java.util.concurrent.atomic.AtomicReference; -import org.junit.Rule; -import org.junit.Test; -import org.jvnet.hudson.test.JenkinsSessionRule; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; import org.jvnet.hudson.test.recipes.LocalData; -public class KubernetesRestartTest { +class KubernetesRestartTest { - @Rule - public JenkinsSessionRule s = new JenkinsSessionRule(); + @RegisterExtension + private final JenkinsSessionExtension s = new JenkinsSessionExtension(); @Test @LocalData - public void upgradeFrom_1_27_1() throws Throwable { + void upgradeFrom_1_27_1() throws Throwable { AtomicReference podTemplateId = new AtomicReference<>(); AtomicReference toString = new AtomicReference<>(); s.then(r -> { diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesSlaveTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesSlaveTest.java index 1d1f406455..508dd5a8db 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesSlaveTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesSlaveTest.java @@ -26,10 +26,9 @@ import static java.util.Map.entry; import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.assertRegex; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; -import hudson.model.Descriptor; import io.fabric8.kubernetes.api.model.Pod; import io.fabric8.kubernetes.client.dsl.PodResource; import java.io.IOException; @@ -46,23 +45,29 @@ import org.csanchez.jenkins.plugins.kubernetes.pod.retention.PodRetention; import org.csanchez.jenkins.plugins.kubernetes.volumes.PodVolume; import org.jenkinsci.plugins.kubernetes.auth.KubernetesAuthException; -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.WithoutJenkins; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.mockito.Mockito; /** * @author Carlos Sanchez */ -public class KubernetesSlaveTest { +@WithJenkins +class KubernetesSlaveTest { - @Rule - public JenkinsRule r = new JenkinsRule(); + private JenkinsRule r; + + @BeforeEach + void beforeEach(JenkinsRule rule) { + r = rule; + } @WithoutJenkins @Test - public void testGetSlaveName() { + void testGetSlaveName() { List volumes = Collections.emptyList(); List containers = Collections.emptyList(); @@ -80,7 +85,7 @@ public void testGetSlaveName() { } @Test - public void testGetPod() throws Exception { + void testGetPod() throws Exception { Map testCases = Map.ofEntries( entry("assigned", (KubernetesCloud cloud, KubernetesSlave slave, PodResource podResource) -> { Pod p = new Pod(); @@ -165,8 +170,8 @@ private interface GetPodTestCase { } @Test - public void testGetPodRetention() { - try { + void testGetPodRetention() { + assertDoesNotThrow(() -> { List> cases = Arrays.asList( createPodRetentionTestCase(new Never(), new Default(), new Default()), createPodRetentionTestCase(new Never(), new Always(), new Always()), @@ -191,9 +196,7 @@ public void testGetPodRetention() { KubernetesSlave testSlave = testCase.buildSubject(cloud); assertEquals(testCase.getExpectedResult(), testSlave.getPodRetention(cloud)); } - } catch (IOException | Descriptor.FormException e) { - fail(e.getMessage()); - } + }); } private KubernetesSlaveTestCase createPodRetentionTestCase( @@ -212,7 +215,7 @@ public static class KubernetesSlaveTestCase { private String podPhase; private T expectedResult; - public KubernetesSlave buildSubject(KubernetesCloud cloud) throws IOException, Descriptor.FormException { + public KubernetesSlave buildSubject(KubernetesCloud cloud) throws Exception { return new KubernetesSlave.Builder() .cloud(cloud) .podTemplate(podTemplate) @@ -269,7 +272,7 @@ public KubernetesSlaveTestCase build() { testTemplate.setPodRetention(templatePodRetention); testTemplate.setName("test-template"); testTemplate.setLabel("test-template"); - testTemplate.setContainers(Arrays.asList(testContainer)); + testTemplate.setContainers(List.of(testContainer)); KubernetesSlaveTestCase testCase = new KubernetesSlaveTestCase<>(); testCase.cloudPodRetention = cloudPodRetention; diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesTest.java index 8a7d9a86f3..5494ad050b 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesTest.java @@ -26,11 +26,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import com.cloudbees.plugins.credentials.Credentials; import com.cloudbees.plugins.credentials.SystemCredentialsProvider; @@ -55,12 +51,12 @@ import org.csanchez.jenkins.plugins.kubernetes.volumes.HostPathVolume; import org.jenkinsci.plugins.kubernetes.credentials.FileSystemServiceAccountCredential; import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl; -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.Issue; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.LoggerRule; +import org.jvnet.hudson.test.LogRecorder; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.jvnet.hudson.test.recipes.LocalData; /** @@ -68,25 +64,25 @@ * @since 0.9 * */ -public class KubernetesTest { +@WithJenkins +class KubernetesTest { - @Rule - public JenkinsRule r = new JenkinsRule(); - - @Rule - public LoggerRule log = new LoggerRule(); + private final LogRecorder log = new LogRecorder(); private KubernetesCloud cloud; - @Before - public void before() throws Exception { + private JenkinsRule r; + + @BeforeEach + void beforeEach(JenkinsRule rule) { + r = rule; cloud = r.jenkins.clouds.get(KubernetesCloud.class); assertNotNull(cloud); } @Test @LocalData() - public void upgradeFrom_1_17_2() throws Exception { + void upgradeFrom_1_17_2() { Map labels = cloud.getPodLabelsMap(); assertEquals(2, labels.size()); assertThat(cloud.getPodLabelsMap(), hasEntry("jenkins", "slave")); @@ -101,7 +97,7 @@ public void upgradeFrom_1_17_2() throws Exception { @Test @LocalData - public void upgradeFrom_1_15_9() { + void upgradeFrom_1_15_9() { List templates = cloud.getTemplates(); assertPodTemplates(templates); PodTemplate template = templates.get(0); @@ -112,7 +108,7 @@ public void upgradeFrom_1_15_9() { @Test @LocalData - public void upgradeFrom_1_15_9_invalid() { + void upgradeFrom_1_15_9_invalid() { log.record(PodTemplate.class, Level.WARNING).capture(1); List templates = cloud.getTemplates(); assertPodTemplates(templates); @@ -127,7 +123,7 @@ public void upgradeFrom_1_15_9_invalid() { @Test @LocalData() @Issue("JENKINS-57116") - public void upgradeFrom_1_15_1() throws Exception { + void upgradeFrom_1_15_1() { List templates = cloud.getTemplates(); assertPodTemplates(templates); PodTemplate template = templates.get(0); @@ -137,7 +133,7 @@ public void upgradeFrom_1_15_1() throws Exception { @Test @LocalData() - public void upgradeFrom_1_10() throws Exception { + void upgradeFrom_1_10() { List templates = cloud.getTemplates(); assertPodTemplates(templates); assertEquals(new Never(), cloud.getPodRetention()); @@ -151,7 +147,7 @@ public void upgradeFrom_1_10() throws Exception { @Test @LocalData() - public void upgradeFrom_1_1() throws Exception { + void upgradeFrom_1_1() { List credentials = SystemCredentialsProvider.getInstance().getCredentials(); assertEquals(3, credentials.size()); UsernamePasswordCredentialsImpl cred0 = (UsernamePasswordCredentialsImpl) credentials.get(0); @@ -166,7 +162,7 @@ public void upgradeFrom_1_1() throws Exception { @Test @LocalData() - public void upgradeFrom_0_12() throws Exception { + void upgradeFrom_0_12() { List templates = cloud.getTemplates(); assertPodTemplates(templates); PodTemplate template = templates.get(0); @@ -180,7 +176,7 @@ public void upgradeFrom_0_12() throws Exception { @Test @LocalData() - public void upgradeFrom_0_10() throws Exception { + void upgradeFrom_0_10() { List templates = cloud.getTemplates(); PodTemplate template = templates.get(0); DescribableList, NodePropertyDescriptor> nodeProperties = template.getNodeProperties(); @@ -196,7 +192,7 @@ public void upgradeFrom_0_10() throws Exception { @Test @LocalData() - public void upgradeFrom_0_8() throws Exception { + void upgradeFrom_0_8() { List templates = cloud.getTemplates(); assertPodTemplates(templates); assertEquals(cloud.DEFAULT_WAIT_FOR_POD_SEC, cloud.getWaitForPodSec()); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesTestUtil.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesTestUtil.java index 590bdb90fb..89a397eade 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesTestUtil.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesTestUtil.java @@ -26,10 +26,9 @@ import static java.util.logging.Level.FINE; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeNoException; -import static org.junit.Assume.assumeTrue; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.Util; @@ -42,7 +41,6 @@ import io.fabric8.kubernetes.client.KubernetesClientBuilder; import io.fabric8.kubernetes.client.KubernetesClientException; import io.fabric8.kubernetes.client.utils.Serialization; -import java.io.IOException; import java.net.InetAddress; import java.net.URL; import java.util.Collections; @@ -60,11 +58,9 @@ import jenkins.model.JenkinsLocationConfiguration; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; -import org.jenkinsci.plugins.kubernetes.auth.KubernetesAuthException; import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; -import org.junit.rules.TestName; import org.jvnet.hudson.test.JenkinsRule; public class KubernetesTestUtil { @@ -83,7 +79,7 @@ public class KubernetesTestUtil { public static final String WINDOWS_1809_BUILD = "10.0.17763"; - public static KubernetesCloud setupCloud(Object test, TestName name) throws KubernetesAuthException, IOException { + public static KubernetesCloud setupCloud(Object test, String name) throws Exception { KubernetesCloud cloud = new KubernetesCloud("kubernetes"); // unique labels per test cloud.setPodLabels(PodLabel.fromMap(getLabels(cloud, test, name))); @@ -141,11 +137,11 @@ public static void setupHost(KubernetesCloud cloud) throws Exception { } } - public static void assumeKubernetes() throws Exception { + public static void assumeKubernetes() { try (KubernetesClient client = new KubernetesClientBuilder().build()) { client.pods().list(); } catch (Exception e) { - assumeNoException(e); + assumeTrue(false, e.toString()); } } @@ -156,7 +152,7 @@ public static void assumeKubernetes() throws Exception { * Note that running the controller on Windows is untested. */ public static void assumeWindows(String buildNumber) { - assumeTrue("Cluster seems to contain no Windows nodes with build " + buildNumber, isWindows(buildNumber)); + assumeTrue(isWindows(buildNumber), "Cluster seems to contain no Windows nodes with build " + buildNumber); } public static boolean isWindows(@CheckForNull String buildNumber) { @@ -177,14 +173,14 @@ public static boolean isWindows(@CheckForNull String buildNumber) { return false; } - public static Map getLabels(Object o, TestName name) { + public static Map getLabels(Object o, String name) { return getLabels(null, o, name); } /** * Labels to add to the pods so we can match them to a specific build run, test class and method */ - public static Map getLabels(KubernetesCloud cloud, Object o, TestName name) { + public static Map getLabels(KubernetesCloud cloud, Object o, String name) { Map l = new HashMap<>(); l.put("BRANCH_NAME", BRANCH_NAME == null ? "undefined" : BRANCH_NAME); l.put("BUILD_NUMBER", BUILD_NUMBER == null ? "undefined" : BUILD_NUMBER); @@ -192,7 +188,7 @@ public static Map getLabels(KubernetesCloud cloud, Object o, Tes l.putAll(cloud.getPodLabelsMap()); } l.put("class", o.getClass().getSimpleName()); - l.put("test", name.getMethodName()); + l.put("test", name); return l; } @@ -245,7 +241,7 @@ public static boolean deletePods(KubernetesClient client, Map la PodList list = client.pods().withLabels(labels).list(); if (!list.getItems().isEmpty()) { LOGGER.log(WARNING, "Deleting leftover pods: {0}", print(list)); - return client.pods().withLabels(labels).delete().size() > 0; + return !client.pods().withLabels(labels).delete().isEmpty(); } } return false; @@ -320,6 +316,6 @@ public static String loadPipelineScript(Class clazz, String name) { public static void assertRegex(String name, String regex) { assertNotNull(name); - assertTrue(String.format("Name does not match regex [%s]: '%s'", regex, name), name.matches(regex)); + assertTrue(name.matches(regex), String.format("Name does not match regex [%s]: '%s'", regex, name)); } } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/MetricNamesTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/MetricNamesTest.java index 6856045815..efc1f17629 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/MetricNamesTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/MetricNamesTest.java @@ -1,31 +1,32 @@ package org.csanchez.jenkins.plugins.kubernetes; -import org.junit.Assert; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; -public class MetricNamesTest { +import org.junit.jupiter.api.Test; + +class MetricNamesTest { @Test - public void metricNameForPodStatusAddsNullWhenStatusIsNull() { + void metricNameForPodStatusAddsNullWhenStatusIsNull() { String expected = "kubernetes.cloud.pods.launch.status.null"; String actual = MetricNames.metricNameForPodStatus(null); - Assert.assertEquals(expected, actual); + assertEquals(expected, actual); } @Test - public void metricNameForPodStatusAddsStatusValueIfNotNull() { + void metricNameForPodStatusAddsStatusValueIfNotNull() { String expected = "kubernetes.cloud.pods.launch.status.running"; String actual = MetricNames.metricNameForPodStatus("RUNNING"); - Assert.assertEquals(expected, actual); + assertEquals(expected, actual); } @Test - public void metricNameForPodStatusChangeStatusToLowercase() { + void metricNameForPodStatusChangeStatusToLowercase() { String expected = "kubernetes.cloud.pods.launch.status.failed"; String actual = MetricNames.metricNameForPodStatus("FaIlEd"); - Assert.assertEquals(expected, actual); + assertEquals(expected, actual); } } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/NonConfigurableKubernetesCloudTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/NonConfigurableKubernetesCloudTest.java index dbb00cbc44..4f4e946424 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/NonConfigurableKubernetesCloudTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/NonConfigurableKubernetesCloudTest.java @@ -1,29 +1,35 @@ package org.csanchez.jenkins.plugins.kubernetes; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.logging.Level; import java.util.logging.Logger; -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.LoggerRule; +import org.jvnet.hudson.test.LogRecorder; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; -public class NonConfigurableKubernetesCloudTest { +@WithJenkins +class NonConfigurableKubernetesCloudTest { - @Rule - public JenkinsRule j = new JenkinsRule(); - - @Rule - public LoggerRule logs = new LoggerRule() + @SuppressWarnings("unused") + private final LogRecorder logs = new LogRecorder() .record( Logger.getLogger(NonConfigurableKubernetesCloudTest.class .getPackage() .getName()), Level.ALL); + private JenkinsRule j; + + @BeforeEach + void beforeEach(JenkinsRule rule) { + j = rule; + } + @Test - public void configRoundTrip() throws Exception { + void configRoundTrip() throws Exception { // create a cloud with a template var cloud = new KubernetesCloud("kubernetes"); var podTemplate = new PodTemplate(); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodContainerSourceTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodContainerSourceTest.java index 34ad1bc0cd..dc899d41d6 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodContainerSourceTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodContainerSourceTest.java @@ -1,6 +1,6 @@ package org.csanchez.jenkins.plugins.kubernetes; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; import edu.umd.cs.findbugs.annotations.NonNull; import io.fabric8.kubernetes.api.model.ContainerStatus; @@ -10,19 +10,25 @@ import io.fabric8.kubernetes.api.model.PodStatus; import java.util.Optional; import org.apache.commons.lang3.StringUtils; -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.TestExtension; import org.jvnet.hudson.test.WithoutJenkins; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; -public class PodContainerSourceTest { +@WithJenkins +class PodContainerSourceTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + private JenkinsRule j; + + @BeforeEach + void beforeEach(JenkinsRule rule) { + j = rule; + } @Test - public void lookupContainerWorkingDir() { + void lookupContainerWorkingDir() { Pod pod = new PodBuilder() .withNewSpec() .addNewContainer() @@ -55,7 +61,7 @@ public void lookupContainerWorkingDir() { } @Test - public void lookupContainerStatus() { + void lookupContainerStatus() { Pod pod = new PodBuilder() .withNewStatus() .addNewContainerStatus() @@ -91,7 +97,7 @@ public void lookupContainerStatus() { @WithoutJenkins @Test - public void defaultPodContainerSourceGetContainerWorkingDir() { + void defaultPodContainerSourceGetContainerWorkingDir() { Pod pod = new PodBuilder() .withNewSpec() .addNewContainer() @@ -121,7 +127,7 @@ public void defaultPodContainerSourceGetContainerWorkingDir() { @WithoutJenkins @Test - public void defaultPodContainerSourceGetContainerStatus() { + void defaultPodContainerSourceGetContainerStatus() { Pod pod = new PodBuilder() .withNewStatus() .addNewContainerStatus() diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodEnvVarTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodEnvVarTest.java index a83457e8ed..126ca60ecb 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodEnvVarTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodEnvVarTest.java @@ -24,15 +24,15 @@ package org.csanchez.jenkins.plugins.kubernetes; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.csanchez.jenkins.plugins.kubernetes.model.KeyValueEnvVar; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class PodEnvVarTest { +class PodEnvVarTest { @Test - public void testEquals() { + void testEquals() { assertEquals(new PodEnvVar("a", "b"), new KeyValueEnvVar("a", "b")); } } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateBuilderTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateBuilderTest.java index 84b4fac6b5..9a79bbad71 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateBuilderTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateBuilderTest.java @@ -1,14 +1,10 @@ package org.csanchez.jenkins.plugins.kubernetes; -import static java.util.stream.Collectors.toList; import static org.csanchez.jenkins.plugins.kubernetes.PodTemplateBuilder.*; import static org.csanchez.jenkins.plugins.kubernetes.PodTemplateUtils.*; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; import io.fabric8.kubernetes.api.model.Container; @@ -20,7 +16,6 @@ import io.fabric8.kubernetes.api.model.Volume; import io.fabric8.kubernetes.api.model.VolumeMount; import io.fabric8.kubernetes.api.model.VolumeMountBuilder; -import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -32,9 +27,6 @@ import java.util.logging.Logger; import java.util.stream.Collectors; import jenkins.model.Jenkins; -import junitparams.JUnitParamsRunner; -import junitparams.Parameters; -import junitparams.naming.TestCaseName; import org.apache.commons.io.IOUtils; import org.csanchez.jenkins.plugins.kubernetes.model.KeyValueEnvVar; import org.csanchez.jenkins.plugins.kubernetes.model.TemplateEnvVar; @@ -48,40 +40,39 @@ import org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.DynamicPVCWorkspaceVolume; import org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.EmptyDirWorkspaceVolume; import org.hamcrest.Matcher; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.jvnet.hudson.test.FlagRule; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.LoggerRule; +import org.jvnet.hudson.test.LogRecorder; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.mockito.Mock; import org.mockito.Spy; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; -@RunWith(JUnitParamsRunner.class) -public class PodTemplateBuilderTest { +@WithJenkins +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +class PodTemplateBuilderTest { private static final String AGENT_NAME = "jenkins-agent"; private static final String AGENT_SECRET = "xxx"; private static final String JENKINS_URL = "http://jenkins.example.com"; private static final String JENKINS_PROTOCOLS = "JNLP4-connect"; - @Rule - public JenkinsRule r = new JenkinsRule(); + private JenkinsRule r; - @Rule - public MockitoRule mockitoRule = MockitoJUnit.rule(); - - @Rule - public LoggerRule logs = new LoggerRule() + @SuppressWarnings("unused") + private final LogRecorder logs = new LogRecorder() .record(Logger.getLogger(KubernetesCloud.class.getPackage().getName()), Level.ALL); - @Rule - public FlagRule dockerPrefix = new FlagRule<>( - () -> DEFAULT_JNLP_DOCKER_REGISTRY_PREFIX, prefix -> DEFAULT_JNLP_DOCKER_REGISTRY_PREFIX = prefix); + private String dockerPrefix; @Spy private KubernetesCloud cloud = new KubernetesCloud("test"); @@ -92,15 +83,21 @@ public class PodTemplateBuilderTest { @Mock private KubernetesComputer computer; - @Before - public void setUp() { + @BeforeEach + void beforeEach(JenkinsRule rule) { + r = rule; when(slave.getKubernetesCloud()).thenReturn(cloud); + dockerPrefix = DEFAULT_JNLP_DOCKER_REGISTRY_PREFIX; } - @Test - @TestCaseName("{method}(directConnection={0})") - @Parameters({"true", "false"}) - public void testBuildFromYaml(boolean directConnection) throws Exception { + @AfterEach + void afterEach() { + DEFAULT_JNLP_DOCKER_REGISTRY_PREFIX = dockerPrefix; + } + + @ParameterizedTest(name = "directConnection={0}") + @ValueSource(booleans = {true, false}) + void testBuildFromYaml(boolean directConnection) throws Exception { cloud.setDirectConnection(directConnection); PodTemplate template = new PodTemplate(); template.setYaml(loadYamlFile("pod-busybox.yaml")); @@ -121,7 +118,7 @@ public void testBuildFromYaml(boolean directConnection) throws Exception { } @Test - public void testBuildJnlpFromYamlWithNullEnv() throws Exception { + void testBuildJnlpFromYamlWithNullEnv() throws Exception { PodTemplate template = new PodTemplate(); template.setYaml(loadYamlFile("pod-jnlp-nullenv.yaml")); Pod pod = new PodTemplateBuilder(template, slave).build(); @@ -134,7 +131,7 @@ public void testBuildJnlpFromYamlWithNullEnv() throws Exception { @Test @Issue("JENKINS-71639") - public void testInjectRestrictedPssSecurityContextInJnlp() throws Exception { + void testInjectRestrictedPssSecurityContextInJnlp() throws Exception { cloud.setRestrictedPssSecurityContext(true); PodTemplate template = new PodTemplate(); template.setYaml(loadYamlFile("pod-busybox.yaml")); @@ -156,7 +153,7 @@ public void testInjectRestrictedPssSecurityContextInJnlp() throws Exception { } @Test - public void testValidateDockerRegistryUIOverride() throws Exception { + void testValidateDockerRegistryUIOverride() throws Exception { final String jnlpregistry = "registry.example.com"; cloud.setJnlpregistry(jnlpregistry); DEFAULT_JNLP_DOCKER_REGISTRY_PREFIX = "jenkins.docker.com/docker-hub"; // should be ignored @@ -175,7 +172,7 @@ public void testValidateDockerRegistryUIOverride() throws Exception { } @Test - public void testValidateDockerRegistryUIOverrideWithSlashSuffix() throws Exception { + void testValidateDockerRegistryUIOverrideWithSlashSuffix() throws Exception { final String jnlpregistry = "registry.example.com/"; cloud.setJnlpregistry(jnlpregistry); DEFAULT_JNLP_DOCKER_REGISTRY_PREFIX = "jenkins.docker.com/docker-hub"; // should be ignored @@ -192,10 +189,9 @@ public void testValidateDockerRegistryUIOverrideWithSlashSuffix() throws Excepti assertThat(pod.getMetadata().getLabels(), hasEntry("jenkins", "slave")); } - @Test - @TestCaseName("{method}(directConnection={0})") - @Parameters({"true", "false"}) - public void testValidateDockerRegistryPrefixOverride(boolean directConnection) throws Exception { + @ParameterizedTest(name = "directConnection={0}") + @ValueSource(booleans = {true, false}) + void testValidateDockerRegistryPrefixOverride(boolean directConnection) throws Exception { cloud.setDirectConnection(directConnection); DEFAULT_JNLP_DOCKER_REGISTRY_PREFIX = "jenkins.docker.com/docker-hub"; PodTemplate template = new PodTemplate(); @@ -213,10 +209,9 @@ public void testValidateDockerRegistryPrefixOverride(boolean directConnection) t assertThat(pod.getMetadata().getLabels(), hasEntry("jenkins", "slave")); } - @Test - @TestCaseName("{method}(directConnection={0})") - @Parameters({"true", "false"}) - public void testValidateDockerRegistryPrefixOverrideWithSlashSuffix(boolean directConnection) throws Exception { + @ParameterizedTest(name = "directConnection={0}") + @ValueSource(booleans = {true, false}) + void testValidateDockerRegistryPrefixOverrideWithSlashSuffix(boolean directConnection) throws Exception { cloud.setDirectConnection(directConnection); DEFAULT_JNLP_DOCKER_REGISTRY_PREFIX = "jenkins.docker.com/docker-hub/"; PodTemplate template = new PodTemplate(); @@ -234,10 +229,9 @@ public void testValidateDockerRegistryPrefixOverrideWithSlashSuffix(boolean dire assertThat(pod.getMetadata().getLabels(), hasEntry("jenkins", "slave")); } - @Test - @TestCaseName("{method}(directConnection={0})") - @Parameters({"true", "false"}) - public void testValidateDockerRegistryPrefixOverrideForInitContainer(boolean directConnection) throws Exception { + @ParameterizedTest(name = "directConnection={0}") + @ValueSource(booleans = {true, false}) + void testValidateDockerRegistryPrefixOverrideForInitContainer(boolean directConnection) throws Exception { cloud.setDirectConnection(directConnection); DEFAULT_JNLP_DOCKER_REGISTRY_PREFIX = "jenkins.docker.com/docker-hub"; PodTemplate template = new PodTemplate(); @@ -264,7 +258,7 @@ public void testValidateDockerRegistryPrefixOverrideForInitContainer(boolean dir @Test @Issue("JENKINS-50525") - public void testBuildWithCustomWorkspaceVolume() throws Exception { + void testBuildWithCustomWorkspaceVolume() { PodTemplate template = new PodTemplate(); var workspaceVolume = new EmptyDirWorkspaceVolume(true); workspaceVolume.setSizeLimit("1Gi"); @@ -293,7 +287,7 @@ public void testBuildWithCustomWorkspaceVolume() throws Exception { } @Test - public void testBuildWithDynamicPVCWorkspaceVolume() { + void testBuildWithDynamicPVCWorkspaceVolume() { PodTemplate template = new PodTemplate(); template.setWorkspaceVolume(new DynamicPVCWorkspaceVolume()); ContainerTemplate containerTemplate = new ContainerTemplate("name", "image"); @@ -316,10 +310,9 @@ public void testBuildWithDynamicPVCWorkspaceVolume() { assertNotNull(pod.getSpec().getVolumes().get(0).getPersistentVolumeClaim()); } - @Test - @TestCaseName("{method}(directConnection={0})") - @Parameters({"true", "false"}) - public void testBuildFromTemplate(boolean directConnection) throws Exception { + @ParameterizedTest(name = "directConnection={0}") + @ValueSource(booleans = {true, false}) + void testBuildFromTemplate(boolean directConnection) { cloud.setDirectConnection(directConnection); PodTemplate template = new PodTemplate(); template.setRunAsUser("1000"); @@ -328,16 +321,16 @@ public void testBuildFromTemplate(boolean directConnection) throws Exception { template.setHostNetwork(false); - List volumes = new ArrayList(); + List volumes = new ArrayList<>(); volumes.add(new HostPathVolume("/host/data", "/container/data", false)); volumes.add(new EmptyDirVolume("/empty/dir", false)); template.setVolumes(volumes); - List containers = new ArrayList(); + List containers = new ArrayList<>(); ContainerTemplate busyboxContainer = new ContainerTemplate("busybox", "busybox"); busyboxContainer.setCommand("cat"); busyboxContainer.setTtyEnabled(true); - List envVars = new ArrayList(); + List envVars = new ArrayList<>(); envVars.add(new KeyValueEnvVar("CONTAINER_ENV_VAR", "container-env-var-value")); busyboxContainer.setEnvVars(envVars); busyboxContainer.setRunAsUser("2000"); @@ -349,7 +342,7 @@ public void testBuildFromTemplate(boolean directConnection) throws Exception { Pod pod = new PodTemplateBuilder(template, slave).build(); pod.getMetadata().setLabels(Collections.singletonMap("some-label", "some-label-value")); validatePod(pod, false, directConnection); - ArrayList supplementalGroups = new ArrayList(); + ArrayList supplementalGroups = new ArrayList<>(); supplementalGroups.add(5001L); supplementalGroups.add(5002L); @@ -452,7 +445,7 @@ private void validateContainers(Pod pod, KubernetesSlave slave, boolean directCo validateJnlpContainer(c, slave, directConnection); } else { List env = c.getEnv(); - assertThat(env.stream().map(EnvVar::getName).collect(toList()), everyItem(not(isIn(exclusions)))); + assertThat(env.stream().map(EnvVar::getName).toList(), everyItem(not(is(in(exclusions))))); } } } @@ -484,11 +477,11 @@ private void validateJnlpContainer(Container jnlp, KubernetesSlave slave, boolea } else { assertThat(jnlp.getArgs(), empty()); } - assertThat(jnlp.getEnv(), containsInAnyOrder(envVars.toArray(new EnvVar[envVars.size()]))); + assertThat(jnlp.getEnv(), containsInAnyOrder(envVars.toArray(new EnvVar[0]))); } @Test - public void namespaceFromCloud() { + void namespaceFromCloud() { when(cloud.getNamespace()).thenReturn("cloud-namespace"); PodTemplate template = new PodTemplate(); Pod pod = new PodTemplateBuilder(template, slave).build(); @@ -496,7 +489,7 @@ public void namespaceFromCloud() { } @Test - public void namespaceFromTemplate() { + void namespaceFromTemplate() { when(cloud.getNamespace()).thenReturn("cloud-namespace"); PodTemplate template = new PodTemplate(); template.setNamespace("template-namespace"); @@ -505,7 +498,7 @@ public void namespaceFromTemplate() { } @Test - public void defaultRequests() throws Exception { + void defaultRequests() { PodTemplate template = new PodTemplate(); Pod pod = new PodTemplateBuilder(template, slave).build(); ResourceRequirements resources = pod.getSpec().getContainers().get(0).getResources(); @@ -517,10 +510,9 @@ public void defaultRequests() throws Exception { PodTemplateBuilder.DEFAULT_JNLP_CONTAINER_MEMORY_REQUEST, requests.get("memory")); } - @Test - @TestCaseName("{method}(directConnection={0})") - @Parameters({"true", "false"}) - public void testOverridesFromYaml(boolean directConnection) throws Exception { + @ParameterizedTest(name = "directConnection={0}") + @ValueSource(booleans = {true, false}) + void testOverridesFromYaml(boolean directConnection) throws Exception { cloud.setDirectConnection(directConnection); PodTemplate template = new PodTemplate(); template.setNamespace("template-namespace"); @@ -548,10 +540,9 @@ public void testOverridesFromYaml(boolean directConnection) throws Exception { * child ones. Then the fields override what is defined in the yaml, so in effect the parent resource limits and * requests are used. */ - @Test - @TestCaseName("{method}(directConnection={0})") - @Parameters({"true", "false"}) - public void testInheritsFromWithYaml(boolean directConnection) throws Exception { + @ParameterizedTest(name = "directConnection={0}") + @ValueSource(booleans = {true, false}) + void testInheritsFromWithYaml(boolean directConnection) throws Exception { cloud.setDirectConnection(directConnection); PodTemplate parent = new PodTemplate(); ContainerTemplate container1 = new ContainerTemplate("jnlp", "image1"); @@ -561,7 +552,7 @@ public void testInheritsFromWithYaml(boolean directConnection) throws Exception container1.setResourceRequestMemory("156Mi"); container1.setRunAsUser("1000"); container1.setRunAsGroup("2000"); - parent.setContainers(Arrays.asList(container1)); + parent.setContainers(List.of(container1)); PodTemplate template = new PodTemplate(); template.setYaml(loadYamlFile("pod-overrides.yaml")); @@ -587,14 +578,17 @@ public void testInheritsFromWithYaml(boolean directConnection) throws Exception } @Test - public void inheritYamlMergeStrategy() throws Exception { + void inheritYamlMergeStrategy() { PodTemplate parent = new PodTemplate(); - parent.setYaml("apiVersion: v1\n" + "kind: Pod\n" - + "spec:\n" - + " tolerations:\n" - + " - key: \"reservedFor\"\n" - + " operator: Exists\n" - + " effect: NoSchedule"); + parent.setYaml( + """ + apiVersion: v1 + kind: Pod + spec: + tolerations: + - key: "reservedFor" + operator: Exists + effect: NoSchedule"""); PodTemplate child = new PodTemplate(); child.setYaml("spec:\n"); @@ -643,27 +637,35 @@ public void inheritYamlMergeStrategy() throws Exception { } @Test - public void yamlMergeContainers() throws Exception { + void yamlMergeContainers() { PodTemplate parent = new PodTemplate(); - parent.setYaml("apiVersion: v1\n" + "kind: Pod\n" - + "metadata:\n" - + " labels:\n" - + " some-label: some-label-value\n" - + "spec:\n" - + " containers:\n" - + " - name: container1\n" - + " image: busybox\n" - + " command:\n" - + " - cat\n" - + " tty: true\n"); + parent.setYaml( + """ + apiVersion: v1 + kind: Pod + metadata: + labels: + some-label: some-label-value + spec: + containers: + - name: container1 + image: busybox + command: + - cat + tty: true + """); PodTemplate child = new PodTemplate(); - child.setYaml("spec:\n" + " containers:\n" - + " - name: container2\n" - + " image: busybox\n" - + " command:\n" - + " - cat\n" - + " tty: true\n"); + child.setYaml( + """ + spec: + containers: + - name: container2 + image: busybox + command: + - cat + tty: true + """); child.setYamlMergeStrategy(merge()); child.setInheritFrom("parent"); setupStubs(); @@ -682,27 +684,35 @@ public void yamlMergeContainers() throws Exception { } @Test - public void yamlOverrideContainer() throws Exception { + void yamlOverrideContainer() { PodTemplate parent = new PodTemplate(); - parent.setYaml("apiVersion: v1\n" + "kind: Pod\n" - + "metadata:\n" - + " labels:\n" - + " some-label: some-label-value\n" - + "spec:\n" - + " containers:\n" - + " - name: container\n" - + " image: busybox\n" - + " command:\n" - + " - cat\n" - + " tty: true\n"); + parent.setYaml( + """ + apiVersion: v1 + kind: Pod + metadata: + labels: + some-label: some-label-value + spec: + containers: + - name: container + image: busybox + command: + - cat + tty: true + """); PodTemplate child = new PodTemplate(); - child.setYaml("spec:\n" + " containers:\n" - + " - name: container\n" - + " image: busybox2\n" - + " command:\n" - + " - cat\n" - + " tty: true\n"); + child.setYaml( + """ + spec: + containers: + - name: container + image: busybox2 + command: + - cat + tty: true + """); child.setInheritFrom("parent"); child.setYamlMergeStrategy(merge()); setupStubs(); @@ -719,24 +729,32 @@ public void yamlOverrideContainer() throws Exception { @Issue("JENKINS-58374") @Test - public void yamlOverrideContainerEnvvar() throws Exception { + void yamlOverrideContainerEnvvar() { PodTemplate parent = new PodTemplate(); - parent.setYaml("kind: Pod\n" + "spec:\n" - + " containers:\n" - + " - name: jnlp\n" - + " env:\n" - + " - name: VAR1\n" - + " value: \"1\"\n" - + " - name: VAR2\n" - + " value: \"1\"\n"); + parent.setYaml( + """ + kind: Pod + spec: + containers: + - name: jnlp + env: + - name: VAR1 + value: "1" + - name: VAR2 + value: "1" + """); PodTemplate child = new PodTemplate(); child.setYamlMergeStrategy(merge()); - child.setYaml("kind: Pod\n" + "spec:\n" - + " containers:\n" - + " - name: jnlp\n" - + " env:\n" - + " - name: VAR1\n" - + " value: \"2\"\n"); + child.setYaml( + """ + kind: Pod + spec: + containers: + - name: jnlp + env: + - name: VAR1 + value: "2" + """); setupStubs(); PodTemplate result = combine(parent, child); @@ -752,29 +770,37 @@ public void yamlOverrideContainerEnvvar() throws Exception { } @Test - public void yamlOverrideVolume() throws Exception { + void yamlOverrideVolume() { PodTemplate parent = new PodTemplate(); - parent.setYaml("apiVersion: v1\n" + "kind: Pod\n" - + "metadata:\n" - + " labels:\n" - + " some-label: some-label-value\n" - + "spec:\n" - + " containers:\n" - + " - name: jnlp\n" - + " volumeMounts:\n" - + " - name: host-volume\n" - + " mountPath: /etc/config\n" - + " subPath: mypath\n" - + " volumes:\n" - + " - name: host-volume\n" - + " hostPath:\n" - + " path: /host/data\n"); + parent.setYaml( + """ + apiVersion: v1 + kind: Pod + metadata: + labels: + some-label: some-label-value + spec: + containers: + - name: jnlp + volumeMounts: + - name: host-volume + mountPath: /etc/config + subPath: mypath + volumes: + - name: host-volume + hostPath: + path: /host/data + """); PodTemplate child = new PodTemplate(); - child.setYaml("spec:\n" + " volumes:\n" - + " - name: host-volume\n" - + " hostPath:\n" - + " path: /host/data2\n"); + child.setYaml( + """ + spec: + volumes: + - name: host-volume + hostPath: + path: /host/data2 + """); child.setContainers(Collections.singletonList(new ContainerTemplate("jnlp", "image"))); ConfigMapVolume cmVolume = new ConfigMapVolume("/etc/configmap", "my-configmap", false); cmVolume.setSubPath("subpath"); @@ -810,35 +836,43 @@ public void yamlOverrideVolume() throws Exception { } @Test - public void yamlOverrideHostNetwork() { + void yamlOverrideHostNetwork() { PodTemplate parent = new PodTemplate(); - parent.setYaml("apiVersion: v1\n" + "kind: Pod\n" - + "metadata:\n" - + " labels:\n" - + " some-label: some-label-value\n" - + "spec:\n" - + " hostNetwork: false\n" - + " containers:\n" - + " - name: container\n" - + " securityContext:\n" - + " runAsUser: 1000\n" - + " runAsGroup: 1000\n" - + " image: busybox\n" - + " command:\n" - + " - cat\n" - + " tty: true\n"); + parent.setYaml( + """ + apiVersion: v1 + kind: Pod + metadata: + labels: + some-label: some-label-value + spec: + hostNetwork: false + containers: + - name: container + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + image: busybox + command: + - cat + tty: true + """); PodTemplate child = new PodTemplate(); - child.setYaml("spec:\n" + " hostNetwork: true\n" - + " containers:\n" - + " - name: container\n" - + " image: busybox2\n" - + " securityContext:\n" - + " runAsUser: 2000\n" - + " runAsGroup: 2000\n" - + " command:\n" - + " - cat\n" - + " tty: true\n"); + child.setYaml( + """ + spec: + hostNetwork: true + containers: + - name: container + image: busybox2 + securityContext: + runAsUser: 2000 + runAsGroup: 2000 + command: + - cat + tty: true + """); child.setInheritFrom("parent"); child.setYamlMergeStrategy(merge()); PodTemplate result = combine(parent, child); @@ -847,17 +881,24 @@ public void yamlOverrideHostNetwork() { } @Test - public void yamlOverrideSchedulerName() { + void yamlOverrideSchedulerName() { PodTemplate parent = new PodTemplate(); - parent.setYaml("apiVersion: v1\n" + "kind: Pod\n" - + "metadata:\n" - + " labels:\n" - + " some-label: some-label-value\n" - + "spec:\n" - + " schedulerName: default-scheduler\n"); + parent.setYaml( + """ + apiVersion: v1 + kind: Pod + metadata: + labels: + some-label: some-label-value + spec: + schedulerName: default-scheduler + """); PodTemplate child = new PodTemplate(); - child.setYaml("spec:\n" + " schedulerName: custom-scheduler\n"); + child.setYaml(""" + spec: + schedulerName: custom-scheduler + """); child.setInheritFrom("parent"); child.setYamlMergeStrategy(merge()); PodTemplate result = combine(parent, child); @@ -866,39 +907,47 @@ public void yamlOverrideSchedulerName() { } @Test - public void yamlOverrideSecurityContext() { + void yamlOverrideSecurityContext() { PodTemplate parent = new PodTemplate(); - parent.setYaml("apiVersion: v1\n" + "kind: Pod\n" - + "metadata:\n" - + " labels:\n" - + " some-label: some-label-value\n" - + "spec:\n" - + " securityContext:\n" - + " runAsUser: 2000\n" - + " runAsGroup: 2000\n" - + " containers:\n" - + " - name: container\n" - + " securityContext:\n" - + " runAsUser: 1000\n" - + " runAsGroup: 1000\n" - + " image: busybox\n" - + " command:\n" - + " - cat\n" - + " tty: true\n"); + parent.setYaml( + """ + apiVersion: v1 + kind: Pod + metadata: + labels: + some-label: some-label-value + spec: + securityContext: + runAsUser: 2000 + runAsGroup: 2000 + containers: + - name: container + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + image: busybox + command: + - cat + tty: true + """); PodTemplate child = new PodTemplate(); - child.setYaml("spec:\n" + " securityContext:\n" - + " runAsUser: 3000\n" - + " runAsGroup: 3000\n" - + " containers:\n" - + " - name: container\n" - + " image: busybox2\n" - + " securityContext:\n" - + " runAsUser: 2000\n" - + " runAsGroup: 2000\n" - + " command:\n" - + " - cat\n" - + " tty: true\n"); + child.setYaml( + """ + spec: + securityContext: + runAsUser: 3000 + runAsGroup: 3000 + containers: + - name: container + image: busybox2 + securityContext: + runAsUser: 2000 + runAsGroup: 2000 + command: + - cat + tty: true + """); child.setInheritFrom("parent"); child.setYamlMergeStrategy(merge()); setupStubs(); @@ -916,23 +965,31 @@ public void yamlOverrideSecurityContext() { } @Test - public void yamlMergeVolumes() throws Exception { + void yamlMergeVolumes() { PodTemplate parent = new PodTemplate(); - parent.setYaml("apiVersion: v1\n" + "kind: Pod\n" - + "metadata:\n" - + " labels:\n" - + " some-label: some-label-value\n" - + "spec:\n" - + " volumes:\n" - + " - name: host-volume\n" - + " hostPath:\n" - + " path: /host/data\n"); + parent.setYaml( + """ + apiVersion: v1 + kind: Pod + metadata: + labels: + some-label: some-label-value + spec: + volumes: + - name: host-volume + hostPath: + path: /host/data + """); PodTemplate child = new PodTemplate(); - child.setYaml("spec:\n" + " volumes:\n" - + " - name: host-volume2\n" - + " hostPath:\n" - + " path: /host/data2\n"); + child.setYaml( + """ + spec: + volumes: + - name: host-volume2 + hostPath: + path: /host/data2 + """); child.setInheritFrom("parent"); child.setYamlMergeStrategy(merge()); setupStubs(); @@ -952,14 +1009,13 @@ public void yamlMergeVolumes() throws Exception { assertThat(hostVolume2.get().getHostPath().getPath(), equalTo("/host/data2")); // child value } - @Test - @TestCaseName("{method}(directConnection={0})") - @Parameters({"true", "false"}) - public void testOverridesContainerSpec(boolean directConnection) throws Exception { + @ParameterizedTest(name = "directConnection={0}") + @ValueSource(booleans = {true, false}) + void testOverridesContainerSpec(boolean directConnection) throws Exception { cloud.setDirectConnection(directConnection); PodTemplate template = new PodTemplate(); ContainerTemplate cT = new ContainerTemplate("jnlp", "jenkinsci/jnlp-slave:latest"); - template.setContainers(Arrays.asList(cT)); + template.setContainers(List.of(cT)); template.setYaml(loadYamlFile("pod-overrides.yaml")); setupStubs(); Pod pod = new PodTemplateBuilder(template, slave).build(); @@ -967,15 +1023,12 @@ public void testOverridesContainerSpec(boolean directConnection) throws Exceptio Map containers = toContainerMap(pod); assertEquals(1, containers.size()); Container jnlp = containers.get("jnlp"); - assertEquals( - "Wrong number of volume mounts: " + jnlp.getVolumeMounts(), - 1, - jnlp.getVolumeMounts().size()); + assertEquals(1, jnlp.getVolumeMounts().size(), "Wrong number of volume mounts: " + jnlp.getVolumeMounts()); validateContainers(pod, slave, directConnection); } @Test - public void whenRuntimeClassNameIsSetDoNotSetDefaultNodeSelector() { + void whenRuntimeClassNameIsSetDoNotSetDefaultNodeSelector() { setupStubs(); PodTemplate template = new PodTemplate(); template.setYaml("spec:\n" + " runtimeClassName: windows"); @@ -994,7 +1047,7 @@ private Map toInitContainerMap(Pod pod) { .collect(Collectors.toMap(Container::getName, Function.identity())); } - private String loadYamlFile(String s) throws IOException { + private String loadYamlFile(String s) throws Exception { return new String(IOUtils.toByteArray(getClass().getResourceAsStream(s))); } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateFilterTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateFilterTest.java index 64a18fec25..6394654bbd 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateFilterTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateFilterTest.java @@ -1,7 +1,7 @@ package org.csanchez.jenkins.plugins.kubernetes; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; @@ -9,14 +9,21 @@ import java.util.ArrayList; import java.util.List; import org.hamcrest.Matchers; -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.TestExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; -public class PodTemplateFilterTest { - @Rule - public JenkinsRule j = new JenkinsRule(); +@WithJenkins +class PodTemplateFilterTest { + + private JenkinsRule j; + + @BeforeEach + void beforeEach(JenkinsRule rule) { + j = rule; + } @TestExtension public static class PodTemplateFilter1 extends PodTemplateFilter { @@ -39,7 +46,7 @@ protected PodTemplate transform( } @Test - public void multipleFilters() { + void multipleFilters() { List podtemplates = new ArrayList<>(); PodTemplate podTemplate = new PodTemplate(); podTemplate.setLabel("label"); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateJenkinsTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateJenkinsTest.java index bc28dcd938..9fa00b4258 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateJenkinsTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateJenkinsTest.java @@ -3,7 +3,7 @@ import static org.csanchez.jenkins.plugins.kubernetes.PodTemplate.getLabelDigestFunction; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import hudson.model.Label; import java.math.BigInteger; @@ -13,18 +13,25 @@ import java.util.Set; import java.util.stream.Collectors; import org.hamcrest.Matchers; -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; -public class PodTemplateJenkinsTest { - @Rule - public JenkinsRule j = new JenkinsRule(); +@WithJenkins +class PodTemplateJenkinsTest { + + private JenkinsRule j; + + @BeforeEach + void beforeEach(JenkinsRule rule) { + j = rule; + } @Test @Issue({"JENKINS-59690", "JENKINS-60537"}) - public void singleLabel() { + void singleLabel() { PodTemplate podTemplate = new PodTemplate(); podTemplate.setLabel("foo"); Map labelsMap = podTemplate.getLabelsMap(); @@ -38,7 +45,7 @@ public void singleLabel() { @Test @Issue({"JENKINS-59690", "JENKINS-60537"}) - public void multiLabel() { + void multiLabel() { PodTemplate podTemplate = new PodTemplate(); podTemplate.setLabel("foo bar"); Map labelsMap = podTemplate.getLabelsMap(); @@ -52,7 +59,7 @@ public void multiLabel() { @Test @Issue({"JENKINS-59690", "JENKINS-60537"}) - public void defaultLabel() { + void defaultLabel() { PodTemplate podTemplate = new PodTemplate(); podTemplate.setLabel(null); Map labelsMap = podTemplate.getLabelsMap(); @@ -61,7 +68,7 @@ public void defaultLabel() { } @Test - public void jenkinsLabels() { + void jenkinsLabels() { KubernetesCloud kubernetesCloud = new KubernetesCloud("kubernetes"); j.jenkins.clouds.add(kubernetesCloud); PodTemplate podTemplate = new PodTemplate(); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateMapTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateMapTest.java index aa2b8cd056..13a1c32b5e 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateMapTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateMapTest.java @@ -1,23 +1,24 @@ package org.csanchez.jenkins.plugins.kubernetes; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; -import java.io.IOException; import org.csanchez.jenkins.plugins.kubernetes.pipeline.PodTemplateMap; -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; -public class PodTemplateMapTest { - @Rule - public JenkinsRule j = new JenkinsRule(); +@WithJenkins +class PodTemplateMapTest { private PodTemplateMap instance; private KubernetesCloud cloud; - @Before - public void setUp() throws IOException { + private JenkinsRule j; + + @BeforeEach + void beforeEach(JenkinsRule rule) throws Exception { + j = rule; this.instance = PodTemplateMap.get(); this.cloud = new KubernetesCloud("kubernetes"); j.jenkins.clouds.add(cloud); @@ -25,7 +26,7 @@ public void setUp() throws IOException { } @Test - public void concurrentAdds() throws Exception { + void concurrentAdds() throws Exception { assertEquals(0, this.instance.getTemplates(cloud).size()); int n = 10; Thread[] t = new Thread[n]; @@ -43,11 +44,7 @@ public void concurrentAdds() throws Exception { private Thread newThread(int i) { String name = "test-" + i; - return new Thread( - () -> { - instance.addTemplate(cloud, buildPodTemplate(name)); - }, - name); + return new Thread(() -> instance.addTemplate(cloud, buildPodTemplate(name)), name); } private PodTemplate buildPodTemplate(String label) { diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateTest.java index 33993670b4..75b7798380 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateTest.java @@ -3,14 +3,15 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.empty; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import hudson.util.XStream2; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +class PodTemplateTest { -public class PodTemplateTest { @Test - public void getYamlsExposesSingleYamlField() { + void getYamlsExposesSingleYamlField() { PodTemplate podTemplate = new PodTemplate(); assertThat(podTemplate.getYamls(), empty()); podTemplate.setYamls(null); @@ -22,7 +23,7 @@ public void getYamlsExposesSingleYamlField() { } @Test - public void copyConstructor() throws Exception { + void copyConstructor() { XStream2 xs = new XStream2(); PodTemplate pt = new PodTemplate(); assertEquals(xs.toXML(pt), xs.toXML(new PodTemplate(pt))); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateUtilsTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateUtilsTest.java index d9869f631a..78f65d1dd3 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateUtilsTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateUtilsTest.java @@ -41,12 +41,7 @@ import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.*; import hudson.model.Node; import hudson.tools.ToolLocationNodeProperty; @@ -64,7 +59,6 @@ import io.fabric8.kubernetes.api.model.Toleration; import io.fabric8.kubernetes.api.model.VolumeMount; import io.fabric8.kubernetes.api.model.VolumeMountBuilder; -import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; @@ -77,20 +71,18 @@ import org.csanchez.jenkins.plugins.kubernetes.model.KeyValueEnvVar; import org.csanchez.jenkins.plugins.kubernetes.model.SecretEnvVar; import org.csanchez.jenkins.plugins.kubernetes.volumes.HostPathVolume; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.theories.Theories; -import org.junit.experimental.theories.Theory; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.WithoutJenkins; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; -@RunWith(Theories.class) -public class PodTemplateUtilsTest { - - @Rule - public JenkinsRule j = new JenkinsRule(); +@WithJenkins +class PodTemplateUtilsTest { private static final PodImagePullSecret SECRET_1 = new PodImagePullSecret("secret1"); private static final PodImagePullSecret SECRET_2 = new PodImagePullSecret("secret2"); @@ -106,21 +98,28 @@ public class PodTemplateUtilsTest { private static final ContainerTemplate MAVEN_1 = new ContainerTemplate("maven", "maven:1", "sh -c", "cat"); private static final ContainerTemplate MAVEN_2 = new ContainerTemplate("maven", "maven:2"); + private JenkinsRule j; + + @BeforeEach + void beforeEach(JenkinsRule rule) { + j = rule; + } + @Test - public void shouldReturnContainerTemplateWhenParentIsNull() { + void shouldReturnContainerTemplateWhenParentIsNull() { ContainerTemplate result = combine(null, JNLP_2); - assertEquals(result, JNLP_2); + assertEquals(JNLP_2, result); } @Test - public void shouldOverrideTheImageAndInheritTheRest() { + void shouldOverrideTheImageAndInheritTheRest() { ContainerTemplate result = combine(MAVEN_1, MAVEN_2); assertEquals("maven:2", result.getImage()); assertEquals("cat", result.getArgs()); } @Test - public void shouldReturnPodTemplateWhenParentIsNull() { + void shouldReturnPodTemplateWhenParentIsNull() { PodTemplate template = new PodTemplate(); template.setName("template"); template.setServiceAccount("sa1"); @@ -129,7 +128,7 @@ public void shouldReturnPodTemplateWhenParentIsNull() { } @Test - public void shouldOverrideServiceAccountIfSpecified() { + void shouldOverrideServiceAccountIfSpecified() { PodTemplate parent = new PodTemplate(); parent.setName("parent"); parent.setServiceAccount("sa"); @@ -149,7 +148,7 @@ public void shouldOverrideServiceAccountIfSpecified() { } @Test - public void shouldOverrideNodeSelectorIfSpecified() { + void shouldOverrideNodeSelectorIfSpecified() { PodTemplate parent = new PodTemplate(); parent.setName("parent"); parent.setNodeSelector("key:value"); @@ -169,11 +168,11 @@ public void shouldOverrideNodeSelectorIfSpecified() { } @Test - public void shouldCombineAllImagePullSecrets() { + void shouldCombineAllImagePullSecrets() { PodTemplate parent = new PodTemplate(); parent.setName("parent"); parent.setNodeSelector("key:value"); - parent.setImagePullSecrets(asList(SECRET_1)); + parent.setImagePullSecrets(List.of(SECRET_1)); PodTemplate template1 = new PodTemplate(); template1.setName("template1"); @@ -197,7 +196,7 @@ public void shouldCombineAllImagePullSecrets() { } @Test - public void shouldCombineAllAnnotations() { + void shouldCombineAllAnnotations() { PodTemplate parent = new PodTemplate(); parent.setName("parent"); parent.setNodeSelector("key:value"); @@ -205,35 +204,29 @@ public void shouldCombineAllAnnotations() { PodTemplate template1 = new PodTemplate(); template1.setName("template"); - template1.setAnnotations(asList(ANNOTATION_3)); + template1.setAnnotations(List.of(ANNOTATION_3)); PodTemplate result = combine(parent, template1); assertEquals(2, result.getAnnotations().size()); - assertEquals("value3", result.getAnnotations().get(0).getValue().toString()); + assertEquals("value3", result.getAnnotations().get(0).getValue()); } @Test - public void shouldCombineAllLabels() { - Map labelsMap1 = new HashMap<>(); - labelsMap1.put("label1", "pod1"); - labelsMap1.put("label2", "pod1"); + void shouldCombineAllLabels() { Pod pod1 = new PodBuilder() .withNewMetadata() .withLabels( // - Collections.unmodifiableMap(labelsMap1) // + Map.of("label1", "pod1", "label2", "pod1") // ) .endMetadata() .withNewSpec() .endSpec() .build(); - Map labelsMap2 = new HashMap<>(); - labelsMap2.put("label1", "pod2"); - labelsMap2.put("label3", "pod2"); Pod pod2 = new PodBuilder() .withNewMetadata() .withLabels( // - Collections.unmodifiableMap(labelsMap2) // + Map.of("label1", "pod2", "label3", "pod2") // ) .endMetadata() .withNewSpec() @@ -247,13 +240,13 @@ public void shouldCombineAllLabels() { } @Test - public void shouldUnwrapParent() { + void shouldUnwrapParent() { PodTemplate parent = new PodTemplate(); parent.setName("parent"); parent.setLabel("parent"); parent.setServiceAccount("sa"); parent.setNodeSelector("key:value"); - parent.setImagePullSecrets(asList(SECRET_1)); + parent.setImagePullSecrets(List.of(SECRET_1)); parent.setYaml("Yaml"); parent.setAgentContainer("agentContainer"); parent.setAgentInjection(true); @@ -278,7 +271,7 @@ public void shouldUnwrapParent() { } @Test - public void shouldDropNoDataWhenIdentical() { + void shouldDropNoDataWhenIdentical() { PodTemplate podTemplate = new PodTemplate(); podTemplate.setName("Name"); podTemplate.setNamespace("NameSpace"); @@ -286,7 +279,7 @@ public void shouldDropNoDataWhenIdentical() { podTemplate.setServiceAccount("ServiceAccount"); podTemplate.setNodeSelector("NodeSelector"); podTemplate.setNodeUsageMode(Node.Mode.EXCLUSIVE); - podTemplate.setImagePullSecrets(asList(SECRET_1)); + podTemplate.setImagePullSecrets(List.of(SECRET_1)); podTemplate.setInheritFrom("Inherit"); podTemplate.setInstanceCap(99); podTemplate.setSlaveConnectTimeout(99); @@ -303,7 +296,7 @@ public void shouldDropNoDataWhenIdentical() { assertEquals("ServiceAccount", selfCombined.getServiceAccount()); assertEquals("NodeSelector", selfCombined.getNodeSelector()); assertEquals(Node.Mode.EXCLUSIVE, selfCombined.getNodeUsageMode()); - assertEquals(asList(SECRET_1), selfCombined.getImagePullSecrets()); + assertEquals(List.of(SECRET_1), selfCombined.getImagePullSecrets()); assertEquals("Inherit", selfCombined.getInheritFrom()); assertEquals(99, selfCombined.getInstanceCap()); assertEquals(99, selfCombined.getSlaveConnectTimeout()); @@ -314,13 +307,13 @@ public void shouldDropNoDataWhenIdentical() { } @Test - public void shouldUnwrapMultipleParents() { + void shouldUnwrapMultipleParents() { PodTemplate parent = new PodTemplate(); parent.setName("parent"); parent.setLabel("parent"); parent.setServiceAccount("sa"); parent.setNodeSelector("key:value"); - parent.setImagePullSecrets(asList(SECRET_1)); + parent.setImagePullSecrets(List.of(SECRET_1)); parent.setContainers(asList(JNLP_1, MAVEN_2)); PodTemplate template1 = new PodTemplate(); @@ -328,14 +321,14 @@ public void shouldUnwrapMultipleParents() { template1.setLabel("template1"); template1.setInheritFrom("parent"); template1.setServiceAccount("sa1"); - template1.setImagePullSecrets(asList(SECRET_2)); - template1.setContainers(asList(JNLP_2)); + template1.setImagePullSecrets(List.of(SECRET_2)); + template1.setContainers(List.of(JNLP_2)); PodTemplate template2 = new PodTemplate(); template2.setName("template2"); template2.setLabel("template2"); - template2.setImagePullSecrets(asList(SECRET_3)); - template2.setContainers(asList(MAVEN_2)); + template2.setImagePullSecrets(List.of(SECRET_3)); + template2.setContainers(List.of(MAVEN_2)); PodTemplate toUnwrap = new PodTemplate(); toUnwrap.setName("toUnwrap"); @@ -356,7 +349,7 @@ public void shouldUnwrapMultipleParents() { } @Test - public void shouldCombineInitContainers() { + void shouldCombineInitContainers() { Pod parentPod = new PodBuilder() .withNewMetadata() .endMetadata() @@ -382,7 +375,7 @@ public void shouldCombineInitContainers() { } @Test - public void childShouldOverrideParentInitContainer() { + void childShouldOverrideParentInitContainer() { Pod parentPod = new PodBuilder() .withNewMetadata() .endMetadata() @@ -412,7 +405,7 @@ public void childShouldOverrideParentInitContainer() { } @Test - public void shouldCombineAllPodKeyValueEnvVars() { + void shouldCombineAllPodKeyValueEnvVars() { PodTemplate template1 = new PodTemplate(); KeyValueEnvVar podEnvVar1 = new KeyValueEnvVar("key-1", "value-1"); template1.setEnvVars(singletonList(podEnvVar1)); @@ -428,7 +421,7 @@ public void shouldCombineAllPodKeyValueEnvVars() { } @Test - public void childShouldOverrideParentActiveDeadlineSeconds() { + void childShouldOverrideParentActiveDeadlineSeconds() { Pod parentPod = new PodBuilder() .withNewMetadata() .endMetadata() @@ -449,7 +442,7 @@ public void childShouldOverrideParentActiveDeadlineSeconds() { } @Test - public void shouldCombineActiveDeadlineSeconds() { + void shouldCombineActiveDeadlineSeconds() { Pod parentPod = new PodBuilder() .withNewMetadata() .endMetadata() @@ -469,7 +462,7 @@ public void shouldCombineActiveDeadlineSeconds() { } @Test - public void shouldFilterOutNullOrEmptyPodKeyValueEnvVars() { + void shouldFilterOutNullOrEmptyPodKeyValueEnvVars() { PodTemplate template1 = new PodTemplate(); KeyValueEnvVar podEnvVar1 = new KeyValueEnvVar("", "value-1"); template1.setEnvVars(singletonList(podEnvVar1)); @@ -484,7 +477,7 @@ public void shouldFilterOutNullOrEmptyPodKeyValueEnvVars() { } @Test - public void shouldCombineAllPodSecretEnvVars() { + void shouldCombineAllPodSecretEnvVars() { PodTemplate template1 = new PodTemplate(); SecretEnvVar podSecretEnvVar1 = new SecretEnvVar("key-1", "secret-1", "secret-key-1", false); template1.setEnvVars(singletonList(podSecretEnvVar1)); @@ -500,7 +493,7 @@ public void shouldCombineAllPodSecretEnvVars() { } @Test - public void shouldFilterOutNullOrEmptyPodSecretEnvVars() { + void shouldFilterOutNullOrEmptyPodSecretEnvVars() { PodTemplate template1 = new PodTemplate(); SecretEnvVar podSecretEnvVar1 = new SecretEnvVar("", "secret-1", "secret-key-1", false); template1.setEnvVars(singletonList(podSecretEnvVar1)); @@ -515,7 +508,7 @@ public void shouldFilterOutNullOrEmptyPodSecretEnvVars() { } @Test - public void shouldCombineAllEnvVars() { + void shouldCombineAllEnvVars() { ContainerTemplate template1 = new ContainerTemplate("name-1", "image-1"); KeyValueEnvVar containerEnvVar1 = new KeyValueEnvVar("key-1", "value-1"); template1.setEnvVars(singletonList(containerEnvVar1)); @@ -531,7 +524,7 @@ public void shouldCombineAllEnvVars() { } @Test - public void shouldFilterOutNullOrEmptyEnvVars() { + void shouldFilterOutNullOrEmptyEnvVars() { ContainerTemplate template1 = new ContainerTemplate("name-1", "image-1"); KeyValueEnvVar containerEnvVar1 = new KeyValueEnvVar("", "value-1"); template1.setEnvVars(singletonList(containerEnvVar1)); @@ -546,7 +539,7 @@ public void shouldFilterOutNullOrEmptyEnvVars() { } @Test - public void shouldCombineAllSecretEnvVars() { + void shouldCombineAllSecretEnvVars() { ContainerTemplate template1 = new ContainerTemplate("name-1", "image-1"); SecretEnvVar containerSecretEnvVar1 = new SecretEnvVar("key-1", "secret-1", "secret-key-1", false); template1.setEnvVars(singletonList(containerSecretEnvVar1)); @@ -563,7 +556,7 @@ public void shouldCombineAllSecretEnvVars() { } @Test - public void shouldCombineAllEnvFromSourcesWithoutChangingOrder() { + void shouldCombineAllEnvFromSourcesWithoutChangingOrder() { EnvFromSource configMap1 = new EnvFromSource(new ConfigMapEnvSource("config-map-1", false), null, null); EnvFromSource secret1 = new EnvFromSource(null, null, new SecretEnvSource("secret-1", false)); EnvFromSource configMap2 = new EnvFromSource(new ConfigMapEnvSource("config-map-2", true), null, null); @@ -583,7 +576,7 @@ public void shouldCombineAllEnvFromSourcesWithoutChangingOrder() { } @Test - public void shouldFilterOutEnvFromSourcesWithNullOrEmptyKey() { + void shouldFilterOutEnvFromSourcesWithNullOrEmptyKey() { EnvFromSource noSource = new EnvFromSource(null, null, null); EnvFromSource noConfigMapKey = new EnvFromSource(new ConfigMapEnvSource(null, false), null, null); EnvFromSource emptyConfigMapKey = new EnvFromSource(new ConfigMapEnvSource("", false), null, null); @@ -598,8 +591,9 @@ public void shouldFilterOutEnvFromSourcesWithNullOrEmptyKey() { assertEquals(0, result.getEnvFrom().size()); } - @Theory - public void shouldTreatNullEnvFromSouresAsEmpty(boolean parentEnvNull, boolean templateEnvNull) { + @ParameterizedTest + @CsvSource({"true, true", "true, false", "false, true", "false, false"}) + void shouldTreatNullEnvFromSourcesAsEmpty(boolean parentEnvNull, boolean templateEnvNull) { Container parent = new Container(); if (parentEnvNull) { parent.setEnv(null); @@ -616,7 +610,7 @@ public void shouldTreatNullEnvFromSouresAsEmpty(boolean parentEnvNull, boolean t } @Test - public void shouldCombineAllMounts() { + void shouldCombineAllMounts() { PodTemplate template1 = new PodTemplate(); HostPathVolume hostPathVolume1 = new HostPathVolume("/host/mnt1", "/container/mnt1", false); HostPathVolume hostPathVolume2 = new HostPathVolume("/host/mnt2", "/container/mnt2", false); @@ -650,7 +644,7 @@ private ContainerBuilder containerBuilder() { } @Test - public void shouldCombineAllPodMounts() { + void shouldCombineAllPodMounts() { VolumeMount vm1 = new VolumeMountBuilder() .withMountPath("/host/mnt1") .withName("volume-1") @@ -698,7 +692,7 @@ public void shouldCombineAllPodMounts() { } @Test - public void shouldCombineAllTolerations() { + void shouldCombineAllTolerations() { PodSpec podSpec1 = new PodSpec(); Pod pod1 = new Pod(); Toleration toleration1 = new Toleration("effect1", "key1", "oper1", Long.parseLong("1"), "val1"); @@ -722,17 +716,17 @@ public void shouldCombineAllTolerations() { } @Test - public void shouldCombineAllPorts() { + void shouldCombineAllPorts() { ContainerTemplate template1 = new ContainerTemplate("name-1", "image-1"); PortMapping port1 = new PortMapping("port-1", 1000, 1000); - template1.setPorts(Arrays.asList(port1)); + template1.setPorts(List.of(port1)); ContainerTemplate template2 = new ContainerTemplate("name-2", "image-2"); assertThat(combine(template1, template2).getPorts(), contains(port1)); PortMapping port2 = new PortMapping("port-2", 2000, 2000); - template2.setPorts(Arrays.asList(port2)); + template2.setPorts(List.of(port2)); assertThat(combine(template1, template2).getPorts(), containsInAnyOrder(port1, port2)); port2.setName("port-1"); @@ -740,7 +734,7 @@ public void shouldCombineAllPorts() { } @Test - public void shouldCombineAllResources() { + void shouldCombineAllResources() { Container container1 = new Container(); container1.setResources( new ResourceRequirementsBuilder() // @@ -768,7 +762,7 @@ public void shouldCombineAllResources() { } @Test - public void shouldCombineContainersInOrder() { + void shouldCombineContainersInOrder() { Container container1 = containerBuilder().withName("mysql").build(); Container container2 = containerBuilder().withName("jnlp").build(); Pod pod1 = new PodBuilder() @@ -799,7 +793,7 @@ public void shouldCombineContainersInOrder() { } /** - * Use instead of {@link org.junit.Assert#assertEquals(Object, Object)} on {@link Quantity}. + * Use instead of {@link Assertions#assertEquals(Object, Object)} on {@link Quantity}. * @see kubernetes-client #2034 */ public static void assertQuantity(String expected, Quantity actual) { @@ -809,7 +803,7 @@ public static void assertQuantity(String expected, Quantity actual) { } @Test - public void shouldFilterOutNullOrEmptySecretEnvVars() { + void shouldFilterOutNullOrEmptySecretEnvVars() { ContainerTemplate template1 = new ContainerTemplate("name-1", "image-1"); SecretEnvVar containerSecretEnvVar1 = new SecretEnvVar("", "secret-1", "secret-key-1", false); template1.setEnvVars(singletonList(containerSecretEnvVar1)); @@ -826,21 +820,21 @@ public void shouldFilterOutNullOrEmptySecretEnvVars() { // Substitute tests @Test - public void shouldIgnoreMissingProperties() { + void shouldIgnoreMissingProperties() { Map properties = new HashMap<>(); properties.put("key1", "value1"); assertEquals("${key2}", substitute("${key2}", properties)); } @Test - public void shouldSubstituteSingleEnvVar() { + void shouldSubstituteSingleEnvVar() { Map properties = new HashMap<>(); properties.put("key1", "value1"); assertEquals("value1", substitute("${key1}", properties)); } @Test - public void shouldSubstituteMultipleEnvVars() { + void shouldSubstituteMultipleEnvVars() { Map properties = new HashMap<>(); properties.put("key1", "value1"); properties.put("key2", "value2"); @@ -848,7 +842,7 @@ public void shouldSubstituteMultipleEnvVars() { } @Test - public void shouldSubstituteMultipleEnvVarsAndIgnoreMissing() { + void shouldSubstituteMultipleEnvVarsAndIgnoreMissing() { Map properties = new HashMap<>(); properties.put("key1", "value1"); properties.put("key2", "value2"); @@ -856,7 +850,7 @@ public void shouldSubstituteMultipleEnvVarsAndIgnoreMissing() { } @Test - public void shouldSubstituteMultipleEnvVarsAndNotUseDefaultsForMissing() { + void shouldSubstituteMultipleEnvVarsAndNotUseDefaultsForMissing() { Map properties = new HashMap<>(); properties.put("key1", "value1"); properties.put("key2", "value2"); @@ -865,64 +859,64 @@ public void shouldSubstituteMultipleEnvVarsAndNotUseDefaultsForMissing() { } @Test - public void testValidateLabelA() { + void testValidateLabelA() { assertTrue(validateLabel("1")); assertTrue(validateLabel("a")); } @Test - public void testValidateLabelAb() { + void testValidateLabelAb() { assertTrue(validateLabel("12")); assertTrue(validateLabel("ab")); } @Test - public void testValidateLabelAbc() { + void testValidateLabelAbc() { assertTrue(validateLabel("123")); assertTrue(validateLabel("abc")); } @Test - public void testValidateLabelAbcd() { + void testValidateLabelAbcd() { assertTrue(validateLabel("1234")); assertTrue(validateLabel("abcd")); } @Test - public void testValidateLabelMypod() { + void testValidateLabelMypod() { assertTrue(validateLabel("mypod")); } @Test - public void testValidateLabelMyPodNested() { + void testValidateLabelMyPodNested() { assertTrue(validateLabel("mypodNested")); } @Test - public void testValidateLabelSpecialChars() { + void testValidateLabelSpecialChars() { assertTrue(validateLabel("x-_.z")); assertFalse(validateLabel("one two")); } @Test - public void testValidateLabelStartWithSpecialChars() { + void testValidateLabelStartWithSpecialChars() { assertFalse(validateLabel("-x")); } @Test - public void testValidateLabelLong() { + void testValidateLabelLong() { assertTrue(validateLabel("123456789012345678901234567890123456789012345678901234567890123")); assertTrue(validateLabel("abcdefghijklmnopqrstuwxyzabcdefghijklmnopqrstuwxyzabcdefghijklm")); } @Test - public void testValidateLabelTooLong() { + void testValidateLabelTooLong() { assertFalse(validateLabel("1234567890123456789012345678901234567890123456789012345678901234")); assertFalse(validateLabel("abcdefghijklmnopqrstuwxyzabcdefghijklmnopqrstuwxyzabcdefghijklmn")); } @Test - public void shouldCombineAllToolLocations() { + void shouldCombineAllToolLocations() { PodTemplate podTemplate1 = new PodTemplate(); List nodeProperties1 = new ArrayList<>(); @@ -947,14 +941,14 @@ public void shouldCombineAllToolLocations() { @Test @Issue("JENKINS-57116") - public void testParseYaml() { + void testParseYaml() { PodTemplateUtils.parseFromYaml("{}"); PodTemplateUtils.parseFromYaml(null); PodTemplateUtils.parseFromYaml(""); } @Test - public void octalParsing() throws IOException { + void octalParsing() throws Exception { var fileStream = getClass().getResourceAsStream(getClass().getSimpleName() + "/octal.yaml"); assertNotNull(fileStream); var pod = parseFromYaml(IOUtils.toString(fileStream, StandardCharsets.UTF_8)); @@ -962,7 +956,7 @@ public void octalParsing() throws IOException { } @Test - public void decimalParsing() throws IOException { + void decimalParsing() throws Exception { var fileStream = getClass().getResourceAsStream(getClass().getSimpleName() + "/decimal.yaml"); assertNotNull(fileStream); var pod = parseFromYaml(IOUtils.toString(fileStream, StandardCharsets.UTF_8)); @@ -1000,7 +994,7 @@ private static void checkParsed(Pod pod) { @Test @Issue("JENKINS-72886") - public void shouldIgnoreContainerEmptyArgs() { + void shouldIgnoreContainerEmptyArgs() { Container parent = new Container(); parent.setArgs(List.of("arg1", "arg2")); parent.setCommand(List.of("parent command")); @@ -1011,7 +1005,7 @@ public void shouldIgnoreContainerEmptyArgs() { } @Test - public void shouldSanitizeJenkinsLabel() { + void shouldSanitizeJenkinsLabel() { assertEquals("foo", sanitizeLabel("foo")); assertEquals("foo_bar__3", sanitizeLabel("foo bar #3")); assertEquals("This_Thing", sanitizeLabel("This/Thing")); @@ -1032,7 +1026,7 @@ public void shouldSanitizeJenkinsLabel() { } @Test - public void shouldCombineCapabilities() { + void shouldCombineCapabilities() { Container container1 = containerBuilder() .withNewSecurityContext() .withNewCapabilities() @@ -1075,7 +1069,7 @@ public void shouldCombineCapabilities() { } @Test - public void shouldOverrideCapabilitiesWithTemplate() { + void shouldOverrideCapabilitiesWithTemplate() { Container container1 = containerBuilder() .withNewSecurityContext() .withNewCapabilities() @@ -1101,7 +1095,7 @@ public void shouldOverrideCapabilitiesWithTemplate() { } @Test - public void shouldRetainNullsWhenCombiningCapabilities() { + void shouldRetainNullsWhenCombiningCapabilities() { Container container1 = new ContainerBuilder().build(); Container container2 = new ContainerBuilder().build(); @@ -1120,7 +1114,7 @@ public void shouldRetainNullsWhenCombiningCapabilities() { } @Test - public void shouldOverrideShareProcessNamespaceIfSpecified() { + void shouldOverrideShareProcessNamespaceIfSpecified() { Pod parent1 = new PodBuilder() .withNewMetadata() .endMetadata() @@ -1166,7 +1160,7 @@ public void shouldOverrideShareProcessNamespaceIfSpecified() { @WithoutJenkins @Test - public void testSplitCommandLine() { + void testSplitCommandLine() { assertNull(PodTemplateUtils.splitCommandLine("")); assertNull(PodTemplateUtils.splitCommandLine(null)); assertEquals(List.of("bash"), PodTemplateUtils.splitCommandLine("bash")); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodUtilsTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodUtilsTest.java index b7ff7e66f4..713a4c1bdb 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodUtilsTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodUtilsTest.java @@ -1,20 +1,18 @@ package org.csanchez.jenkins.plugins.kubernetes; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.IntStream; import org.apache.commons.lang.StringUtils; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class PodUtilsTest { +class PodUtilsTest { @Test - public void generateRandomSuffix() { + void generateRandomSuffix() { List generated = IntStream.range(0, 100) .mapToObj(i -> PodUtils.generateRandomSuffix()) .toList(); @@ -28,7 +26,7 @@ public void generateRandomSuffix() { } @Test - public void createNameWithRandomSuffix() { + void createNameWithRandomSuffix() { String name = PodUtils.createNameWithRandomSuffix("foo"); assertEquals(9, name.length()); assertTrue(name.startsWith("foo-")); @@ -46,7 +44,7 @@ public void createNameWithRandomSuffix() { } @Test - public void isValidName() { + void isValidName() { assertTrue(PodUtils.isValidName("foo")); assertTrue(PodUtils.isValidName("foo-bar")); assertTrue(PodUtils.isValidName("foo.bar")); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/RestrictedPssSecurityInjectorTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/RestrictedPssSecurityInjectorTest.java index b3188b98e9..b91970af04 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/RestrictedPssSecurityInjectorTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/RestrictedPssSecurityInjectorTest.java @@ -1,13 +1,13 @@ package org.csanchez.jenkins.plugins.kubernetes; -import java.io.IOException; import org.csanchez.jenkins.plugins.kubernetes.pod.decorator.PodDecorator; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class RestrictedPssSecurityInjectorTest extends AbstractGoldenFileTest { - @Before - public void configureCloud() { +class RestrictedPssSecurityInjectorTest extends AbstractGoldenFileTest { + + @BeforeEach + void configureCloud() { cloud.setRestrictedPssSecurityContext(true); } @@ -17,22 +17,22 @@ protected PodDecorator newDecorator() { } @Test - public void simple() throws IOException { + void simple() throws Exception { test("simple"); } @Test - public void multiContainer() throws IOException { + void multiContainer() throws Exception { test("multiContainer"); } @Test - public void existingSecurityContext() throws IOException { + void existingSecurityContext() throws Exception { test("existingSecurityContext"); } @Test - public void agentInjection() throws IOException { + void agentInjection() throws Exception { test("agentInjection"); } } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/TaskListenerEventWatcherTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/TaskListenerEventWatcherTest.java index b934412fbd..6941bb646e 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/TaskListenerEventWatcherTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/TaskListenerEventWatcherTest.java @@ -23,7 +23,7 @@ */ package org.csanchez.jenkins.plugins.kubernetes; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.*; import hudson.model.TaskListener; @@ -32,38 +32,40 @@ import io.fabric8.kubernetes.client.Watcher; import java.io.ByteArrayOutputStream; import java.io.PrintStream; -import java.io.UnsupportedEncodingException; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import java.nio.charset.StandardCharsets; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; -@RunWith(MockitoJUnitRunner.class) -public class TaskListenerEventWatcherTest { +@ExtendWith(MockitoExtension.class) +class TaskListenerEventWatcherTest { + + @Mock + private TaskListener listener; - private @Mock TaskListener listener; private TaskListenerEventWatcher watcher; - @Before - public void setup() { + @BeforeEach + void beforeEach() { watcher = new TaskListenerEventWatcher("foo", listener); } @Test - public void ignoreBookmarkAction() { + void ignoreBookmarkAction() { watcher.eventReceived(Watcher.Action.BOOKMARK, new Event()); verifyNoInteractions(listener); } @Test - public void ignoreErrorAction() { + void ignoreErrorAction() { watcher.eventReceived(Watcher.Action.ERROR, null); verifyNoInteractions(listener); } @Test - public void logEventMessage() throws UnsupportedEncodingException { + void logEventMessage() { ByteArrayOutputStream bos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(bos); when(listener.getLogger()).thenReturn(ps); @@ -80,7 +82,7 @@ public void logEventMessage() throws UnsupportedEncodingException { verify(listener).getLogger(); ps.flush(); - String output = bos.toString("UTF-8"); + String output = bos.toString(StandardCharsets.UTF_8); assertEquals("[Update][bar/foo-123][because] cat\n[Update][bar/foo-123][because] dog\n", output); } } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/CasCTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/CasCTest.java index fc2aba252c..d34e9280a1 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/CasCTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/CasCTest.java @@ -3,13 +3,9 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.isA; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.*; -import io.jenkins.plugins.casc.misc.RoundTripAbstractTest; +import io.jenkins.plugins.casc.misc.junit.jupiter.AbstractRoundTripTest; import java.util.List; import org.csanchez.jenkins.plugins.kubernetes.ContainerLivenessProbe; import org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate; @@ -19,13 +15,15 @@ import org.csanchez.jenkins.plugins.kubernetes.pod.yaml.Overrides; import org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.DynamicPVCWorkspaceVolume; import org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.WorkspaceVolume; -import org.jvnet.hudson.test.RestartableJenkinsRule; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; -public class CasCTest extends RoundTripAbstractTest { +@WithJenkins +class CasCTest extends AbstractRoundTripTest { @Override - protected void assertConfiguredAsExpected(RestartableJenkinsRule r, String configContent) { - List all = r.j.jenkins.clouds.getAll(KubernetesCloud.class); + protected void assertConfiguredAsExpected(JenkinsRule r, String configContent) { + List all = r.jenkins.clouds.getAll(KubernetesCloud.class); assertThat(all, hasSize(1)); KubernetesCloud cloud = all.get(0); assertNotNull(cloud); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/EnvVarCasCTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/EnvVarCasCTest.java index 3fab7aa2c2..3a2d223c74 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/EnvVarCasCTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/EnvVarCasCTest.java @@ -2,41 +2,44 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.instanceOf; -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 io.jenkins.plugins.casc.misc.RoundTripAbstractTest; +import io.jenkins.plugins.casc.misc.junit.jupiter.AbstractRoundTripTest; import java.util.List; +import java.util.stream.Stream; import org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud; import org.csanchez.jenkins.plugins.kubernetes.PodTemplate; import org.csanchez.jenkins.plugins.kubernetes.model.KeyValueEnvVar; import org.csanchez.jenkins.plugins.kubernetes.model.SecretEnvVar; import org.csanchez.jenkins.plugins.kubernetes.model.TemplateEnvVar; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.jvnet.hudson.test.RestartableJenkinsRule; +import org.junit.jupiter.params.Parameter; +import org.junit.jupiter.params.ParameterizedClass; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; -@RunWith(Parameterized.class) -public class EnvVarCasCTest extends RoundTripAbstractTest { - final EnvVarStrategy strategy; - final String resource; +@WithJenkins +@ParameterizedClass(name = "{index}: {1}") +@MethodSource("permutations") +class EnvVarCasCTest extends AbstractRoundTripTest { - public EnvVarCasCTest(EnvVarStrategy strategy, String resource) { - this.strategy = strategy; - this.resource = resource; - } + @Parameter(0) + private EnvVarStrategy strategy; + + @Parameter(1) + private String resource; - @Parameterized.Parameters(name = "{index}: {1}") - public static Object[] permutations() { - return new Object[][] { - {new KeyValueEnvVarStrategy(), "keyValue"}, - {new SecretEnvVarStrategy(), "secret"}, - }; + static Stream permutations() { + return Stream.of( + Arguments.of(new KeyValueEnvVarStrategy(), "keyValue"), + Arguments.of(new SecretEnvVarStrategy(), "secret")); } @Override - protected void assertConfiguredAsExpected(RestartableJenkinsRule r, String configContent) { - KubernetesCloud cloud = r.j.jenkins.clouds.get(KubernetesCloud.class); + protected void assertConfiguredAsExpected(JenkinsRule r, String configContent) { + KubernetesCloud cloud = r.jenkins.clouds.get(KubernetesCloud.class); assertNotNull(cloud); List templates = cloud.getTemplates(); assertNotNull(templates); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/VolumeCasCTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/VolumeCasCTest.java index 48b5ca1d19..82c5854280 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/VolumeCasCTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/VolumeCasCTest.java @@ -2,44 +2,47 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.instanceOf; -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 io.jenkins.plugins.casc.misc.RoundTripAbstractTest; +import io.jenkins.plugins.casc.misc.junit.jupiter.AbstractRoundTripTest; import java.util.List; +import java.util.stream.Stream; import org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud; import org.csanchez.jenkins.plugins.kubernetes.PodTemplate; import org.csanchez.jenkins.plugins.kubernetes.volumes.*; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.jvnet.hudson.test.RestartableJenkinsRule; - -@RunWith(Parameterized.class) -public class VolumeCasCTest extends RoundTripAbstractTest { - final VolumeStrategy strategy; - final String resource; - - public VolumeCasCTest(VolumeStrategy strategy, String resource) { - this.strategy = strategy; - this.resource = resource; - } - - @Parameterized.Parameters(name = "{index}: {1}") - public static Object[] permutations() { - return new Object[][] { - {new EmptyDirVolumeStrategy(), "emptyDir"}, - {new EmptyDirVolumeStrategy(Boolean.TRUE), "emptyDir_memory"}, - {new ConfigMapVolumeStrategy(), "configMap"}, - {new HostPathVolumeStrategy(), "hostPath"}, - {new NfsVolumeStrategy(), "nfs"}, - {new PVCVolumeStrategy(), "pvc"}, - {new GenericEphemeralVolumeStrategy(), "genericEphemeral"}, - }; +import org.junit.jupiter.params.Parameter; +import org.junit.jupiter.params.ParameterizedClass; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; + +@WithJenkins +@ParameterizedClass(name = "{index}: {1}") +@MethodSource("permutations") +class VolumeCasCTest extends AbstractRoundTripTest { + + @Parameter(0) + private VolumeStrategy strategy; + + @Parameter(1) + private String resource; + + static Stream permutations() { + return Stream.of( + Arguments.of(new EmptyDirVolumeStrategy(), "emptyDir"), + Arguments.of(new EmptyDirVolumeStrategy(Boolean.TRUE), "emptyDir_memory"), + Arguments.of(new ConfigMapVolumeStrategy(), "configMap"), + Arguments.of(new HostPathVolumeStrategy(), "hostPath"), + Arguments.of(new NfsVolumeStrategy(), "nfs"), + Arguments.of(new PVCVolumeStrategy(), "pvc"), + Arguments.of(new GenericEphemeralVolumeStrategy(), "genericEphemeral")); } @Override - protected void assertConfiguredAsExpected(RestartableJenkinsRule r, String configContent) { - KubernetesCloud cloud = r.j.jenkins.clouds.get(KubernetesCloud.class); + protected void assertConfiguredAsExpected(JenkinsRule r, String configContent) { + KubernetesCloud cloud = r.jenkins.clouds.get(KubernetesCloud.class); assertNotNull(cloud); List templates = cloud.getTemplates(); assertNotNull(templates); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/WorkspaceVolumeCasCTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/WorkspaceVolumeCasCTest.java index 4632953260..2ea9b7ae5b 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/WorkspaceVolumeCasCTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/WorkspaceVolumeCasCTest.java @@ -2,44 +2,47 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.instanceOf; -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 io.jenkins.plugins.casc.misc.RoundTripAbstractTest; +import io.jenkins.plugins.casc.misc.junit.jupiter.AbstractRoundTripTest; import java.util.List; +import java.util.stream.Stream; import org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud; import org.csanchez.jenkins.plugins.kubernetes.PodTemplate; import org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.*; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.jvnet.hudson.test.RestartableJenkinsRule; - -@RunWith(Parameterized.class) -public class WorkspaceVolumeCasCTest extends RoundTripAbstractTest { - final WorkspaceVolumeStrategy strategy; - final String resource; - - public WorkspaceVolumeCasCTest(WorkspaceVolumeStrategy strategy, String resource) { - this.strategy = strategy; - this.resource = resource; - } - - @Parameterized.Parameters(name = "{index}: {1}") - public static Object[] permutations() { - return new Object[][] { - {new DynamicPVCWorkspaceVolumeStrategy(), "dynamicPVC"}, - {new EmptyDirWorkspaceVolumeStrategy(), "emptyDir"}, - {new EmptyDirWorkspaceVolumeStrategy(Boolean.TRUE), "emptyDir_memory"}, - {new HostPathWorkspaceVolumeStrategy(), "hostPath"}, - {new NfsWorkspaceVolumeStrategy(), "nfs"}, - {new PVCWorkspaceVolumeStrategy(), "pvc"}, - {new GenericEphemeralWorkspaceVolumeStrategy(), "genericEphemeral"}, - }; +import org.junit.jupiter.params.Parameter; +import org.junit.jupiter.params.ParameterizedClass; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; + +@WithJenkins +@ParameterizedClass(name = "{index}: {1}") +@MethodSource("permutations") +public class WorkspaceVolumeCasCTest extends AbstractRoundTripTest { + + @Parameter(0) + private WorkspaceVolumeStrategy strategy; + + @Parameter(1) + private String resource; + + static Stream permutations() { + return Stream.of( + Arguments.of(new DynamicPVCWorkspaceVolumeStrategy(), "dynamicPVC"), + Arguments.of(new EmptyDirWorkspaceVolumeStrategy(), "emptyDir"), + Arguments.of(new EmptyDirWorkspaceVolumeStrategy(Boolean.TRUE), "emptyDir_memory"), + Arguments.of(new HostPathWorkspaceVolumeStrategy(), "hostPath"), + Arguments.of(new NfsWorkspaceVolumeStrategy(), "nfs"), + Arguments.of(new PVCWorkspaceVolumeStrategy(), "pvc"), + Arguments.of(new GenericEphemeralWorkspaceVolumeStrategy(), "genericEphemeral")); } @Override - protected void assertConfiguredAsExpected(RestartableJenkinsRule r, String configContent) { - KubernetesCloud cloud = r.j.jenkins.clouds.get(KubernetesCloud.class); + protected void assertConfiguredAsExpected(JenkinsRule r, String configContent) { + KubernetesCloud cloud = r.jenkins.clouds.get(KubernetesCloud.class); assertNotNull(cloud); List templates = cloud.getTemplates(); assertNotNull(templates); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/AbstractKubernetesPipelineRJRTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/AbstractKubernetesPipelineRJRTest.java index 6a9d862a45..92a98245df 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/AbstractKubernetesPipelineRJRTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/AbstractKubernetesPipelineRJRTest.java @@ -7,22 +7,18 @@ import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.CreateWorkflowJobThenScheduleRun; import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.RunId; import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.SetupCloud; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.rules.TestName; -import org.jvnet.hudson.test.RealJenkinsRule; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.TestInfo; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension; -public abstract class AbstractKubernetesPipelineRJRTest { +abstract class AbstractKubernetesPipelineRJRTest { - @Rule - public TestName name = new TestName(); - - @Rule - public RealJenkinsRule rjr; + @RegisterExtension + protected RealJenkinsExtension rjr = new RealJenkinsExtension(); { - rjr = new RealJenkinsRule(); String port = System.getProperty("port"); if (StringUtils.isNotBlank(port)) { System.err.println("Overriding port using system property: " + port); @@ -30,25 +26,28 @@ public abstract class AbstractKubernetesPipelineRJRTest { } } - private SetupCloud setup; + protected final SetupCloud setup; + + protected String name; public AbstractKubernetesPipelineRJRTest(SetupCloud setup) { this.setup = setup; } - @BeforeClass - public static void isKubernetesConfigured() throws Exception { + @BeforeAll + protected static void beforeAll() { assumeKubernetes(); } - @Before - public void setUp() throws Throwable { + @BeforeEach + protected void beforeEach(TestInfo info) throws Throwable { + name = info.getTestMethod().orElseThrow().getName(); rjr.startJenkins(); rjr.runRemotely(setup); } protected RunId createWorkflowJobThenScheduleRun() throws Throwable { return rjr.runRemotely(new CreateWorkflowJobThenScheduleRun( - KubernetesTestUtil.loadPipelineScript(getClass(), name.getMethodName() + ".groovy"))); + KubernetesTestUtil.loadPipelineScript(getClass(), name + ".groovy"))); } } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/AbstractKubernetesPipelineTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/AbstractKubernetesPipelineTest.java index dc353d2019..cef6ba0bd6 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/AbstractKubernetesPipelineTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/AbstractKubernetesPipelineTest.java @@ -54,43 +54,40 @@ import org.csanchez.jenkins.plugins.kubernetes.model.TemplateEnvVar; 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.Rule; -import org.junit.rules.TestName; -import org.jvnet.hudson.test.BuildWatcher; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.TestInfo; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.LoggerRule; +import org.jvnet.hudson.test.LogRecorder; +import org.jvnet.hudson.test.junit.jupiter.BuildWatcherExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; +@WithJenkins public abstract class AbstractKubernetesPipelineTest { protected static final String CONTAINER_ENV_VAR_VALUE = "container-env-var-value"; protected static final String POD_ENV_VAR_VALUE = "pod-env-var-value"; protected static final String GLOBAL = "GLOBAL"; - @ClassRule - public static BuildWatcher buildWatcher = new BuildWatcher(); + @SuppressWarnings("unused") + protected static final BuildWatcherExtension BUILD_WATCHER = new BuildWatcherExtension(); protected KubernetesCloud cloud; - @Rule - public JenkinsRule r = new JenkinsRule(); + protected JenkinsRule r; - @Rule - public LoggerRule logs = new LoggerRule() + protected final LogRecorder logs = new LogRecorder() .recordPackage(KubernetesCloud.class, Level.FINE) .recordPackage(NoDelayProvisionerStrategy.class, Level.FINE) .record(PodUtils.class, Level.FINE) .record(NodeProvisioner.class, Level.FINE) .record(KubernetesAgentErrorCondition.class, Level.FINE); - @BeforeClass - public static void isKubernetesConfigured() throws Exception { + @BeforeAll + protected static void beforeAll() { assumeKubernetes(); } - @Rule - public TestName name = new TestName(); + protected String name; private String projectName; @@ -98,10 +95,29 @@ public static void isKubernetesConfigured() throws Exception { protected WorkflowRun b; - @Before - public void defineProjectName() { + @BeforeEach + protected void beforeEach(JenkinsRule rule, TestInfo info) throws Exception { + r = rule; + name = info.getTestMethod().orElseThrow().getName(); // Add spaces before uppercases - this.projectName = generateProjectName(name.getMethodName()); + projectName = generateProjectName(name); + + cloud = setupCloud(this, name); + createSecret(cloud.connect(), cloud.getNamespace()); + cloud.getTemplates().clear(); + cloud.addTemplate(buildBusyboxTemplate("busybox")); + + setupHost(cloud); + + r.jenkins.clouds.add(cloud); + + DescribableList, NodePropertyDescriptor> list = r.jenkins.getGlobalNodeProperties(); + EnvironmentVariablesNodeProperty newEnvVarsNodeProperty = new hudson.slaves.EnvironmentVariablesNodeProperty(); + list.add(newEnvVarsNodeProperty); + EnvVars envVars = newEnvVarsNodeProperty.getEnvVars(); + envVars.put("GLOBAL", "GLOBAL"); + envVars.put("JAVA_HOME_X", "java-home-x"); + r.jenkins.save(); } protected String getProjectName() { @@ -132,33 +148,13 @@ protected final WorkflowRun createJobThenScheduleRun() throws Exception { * @return The scheduled pipeline run */ protected final WorkflowRun createJobThenScheduleRun(Map env) throws Exception { - b = createPipelineJobThenScheduleRun(r, getClass(), name.getMethodName(), env); + b = createPipelineJobThenScheduleRun(r, getClass(), name, env); p = b.getParent(); return b; } protected final String loadPipelineDefinition() { - return KubernetesTestUtil.loadPipelineDefinition(getClass(), name.getMethodName(), null); - } - - @Before - public void configureCloud() throws Exception { - cloud = setupCloud(this, name); - createSecret(cloud.connect(), cloud.getNamespace()); - cloud.getTemplates().clear(); - cloud.addTemplate(buildBusyboxTemplate("busybox")); - - setupHost(cloud); - - r.jenkins.clouds.add(cloud); - - DescribableList, NodePropertyDescriptor> list = r.jenkins.getGlobalNodeProperties(); - EnvironmentVariablesNodeProperty newEnvVarsNodeProperty = new hudson.slaves.EnvironmentVariablesNodeProperty(); - list.add(newEnvVarsNodeProperty); - EnvVars envVars = newEnvVarsNodeProperty.getEnvVars(); - envVars.put("GLOBAL", "GLOBAL"); - envVars.put("JAVA_HOME_X", "java-home-x"); - r.jenkins.save(); + return KubernetesTestUtil.loadPipelineDefinition(getClass(), name, null); } private PodTemplate buildBusyboxTemplate(String label) { diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorPipelineTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorPipelineTest.java index 5ecb69fdd2..519fbb013f 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorPipelineTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorPipelineTest.java @@ -16,7 +16,7 @@ package org.csanchez.jenkins.plugins.kubernetes.pipeline; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; import com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey; import com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey.PrivateKeySource; @@ -28,21 +28,19 @@ import java.util.logging.Logger; import org.apache.commons.io.IOUtils; import org.jenkinsci.plugins.durabletask.BourneShellScript; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.Issue; -import org.jvnet.hudson.test.LoggerRule; +import org.jvnet.hudson.test.LogRecorder; -public class ContainerExecDecoratorPipelineTest extends AbstractKubernetesPipelineTest { +class ContainerExecDecoratorPipelineTest extends AbstractKubernetesPipelineTest { - @Rule - public LoggerRule containerExecLogs = new LoggerRule() + private final LogRecorder containerExecLogs = new LogRecorder() .record(Logger.getLogger(ContainerExecDecorator.class.getName()), Level.ALL) .record(BourneShellScript.class, Level.ALL); @Issue({"JENKINS-47225", "JENKINS-42582"}) @Test - public void sshagent() throws Exception { + void sshagent() throws Exception { PrivateKeySource source = new BasicSSHUserPrivateKey.DirectEntryPrivateKeySource( new String(IOUtils.toByteArray(getClass().getResourceAsStream("id_rsa")))); BasicSSHUserPrivateKey credentials = new BasicSSHUserPrivateKey( @@ -68,7 +66,7 @@ public void sshagent() throws Exception { } @Test - public void docker() throws Exception { + void docker() throws Exception { StandardUsernamePasswordCredentials credentials = new UsernamePasswordCredentialsImpl( CredentialsScope.GLOBAL, "ContainerExecDecoratorPipelineTest-docker", @@ -88,26 +86,26 @@ public void docker() throws Exception { r.assertLogNotContains("secret_password", b); // check that we don't accidentally start exporting sensitive info to the Jenkins log assertFalse( - "credential leaked to log", - containerExecLogs.getMessages().stream().anyMatch(msg -> msg.contains("secret_password"))); + containerExecLogs.getMessages().stream().anyMatch(msg -> msg.contains("secret_password")), + "credential leaked to log"); } @Issue("JENKINS-58290") @Test - public void closedWebSocketExit() throws Exception { + void closedWebSocketExit() throws Exception { assertNotNull(createJobThenScheduleRun()); containerExecLogs.capture(1000); r.waitForMessage("have started user process", b); assertTrue( - "WebSocket was closed in a timely fashion", - containerExecLogs.getMessages().stream().anyMatch(m -> m.startsWith("onClose : "))); + containerExecLogs.getMessages().stream().anyMatch(m -> m.startsWith("onClose : ")), + "WebSocket was closed in a timely fashion"); b.getExecutor().interrupt(); r.waitForCompletion(b); } @Issue("JENKINS-61950") @Test - public void envVarDollarSignEscaping() throws Exception { + void envVarDollarSignEscaping() throws Exception { assertNotNull(createJobThenScheduleRun()); containerExecLogs.capture(1000); r.waitForCompletion(b); @@ -117,7 +115,7 @@ public void envVarDollarSignEscaping() throws Exception { } @Test - public void containerEnvironmentIsHonored() throws Exception { + void containerEnvironmentIsHonored() throws Exception { assertNotNull(createJobThenScheduleRun()); r.waitForCompletion(b); r.assertLogContains( diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorTest.java index 937e20aec9..6988b73614 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorTest.java @@ -28,11 +28,10 @@ import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.deletePods; import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.getLabels; import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.setupCloud; +import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.arrayContaining; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -51,6 +50,7 @@ import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.KubernetesClientException; import java.io.ByteArrayOutputStream; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -70,28 +70,26 @@ import org.csanchez.jenkins.plugins.kubernetes.KubernetesSlave; import org.csanchez.jenkins.plugins.kubernetes.PodTemplate; import org.jenkinsci.plugins.workflow.steps.StepContext; -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TestName; -import org.junit.rules.Timeout; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; +import org.junit.jupiter.api.Timeout; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.LoggerRule; +import org.jvnet.hudson.test.LogRecorder; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; /** * @author Carlos Sanchez */ -public class ContainerExecDecoratorTest { - @Rule - public ExpectedException exception = ExpectedException.none(); +@WithJenkins +@Timeout(value = 3, unit = TimeUnit.MINUTES) +class ContainerExecDecoratorTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + private JenkinsRule j; private KubernetesCloud cloud; private static KubernetesClient client; @@ -102,25 +100,23 @@ public class ContainerExecDecoratorTest { private KubernetesSlave agent; private DumbSlave dumbAgent; - @Rule - public Timeout timeout = new Timeout(3, TimeUnit.MINUTES); - - @Rule - public LoggerRule containerExecLogs = new LoggerRule() + @SuppressWarnings("unused") + private final LogRecorder containerExecLogs = new LogRecorder() .record(Logger.getLogger(ContainerExecDecorator.class.getName()), Level.ALL) // .record(ContainerExecProc.class, Level.ALL) // .record(Logger.getLogger(KubernetesClientProvider.class.getName()), Level.ALL); - @Rule - public TestName name = new TestName(); + private String name; - @BeforeClass - public static void isKubernetesConfigured() throws Exception { + @BeforeAll + static void beforeAll() { assumeKubernetes(); } - @Before - public void configureCloud() throws Exception { + @BeforeEach + void beforeEach(JenkinsRule rule, TestInfo info) throws Exception { + j = rule; + name = info.getTestMethod().orElseThrow().getName(); cloud = setupCloud(this, name); client = cloud.connect(); deletePods(client, getLabels(this, name), false); @@ -172,8 +168,8 @@ public void configureCloud() throws Exception { decorator.setContainerName(image); } - @After - public void after() throws Exception { + @AfterEach + void afterEach() throws Exception { client.pods().delete(pod); deletePods(client, getLabels(this, name), true); } @@ -181,9 +177,9 @@ public void after() throws Exception { /** * Test that multiple command execution in parallel works. */ - @Ignore("TODO PID_PATTERN match flaky in CI") + @Disabled("TODO PID_PATTERN match flaky in CI") @Test - public void testCommandExecution() throws Exception { + void testCommandExecution() throws Exception { Thread[] t = new Thread[10]; List results = Collections.synchronizedList(new ArrayList<>(t.length)); for (int i = 0; i < t.length; i++) { @@ -195,26 +191,21 @@ public void testCommandExecution() throws Exception { for (Thread thread : t) { thread.join(); } - assertEquals("Not all threads finished successfully", t.length, results.size()); + assertEquals(t.length, results.size(), "Not all threads finished successfully"); for (ProcReturn r : results) { - assertEquals("Command didn't complete in time or failed", 0, r.exitCode); - assertTrue( - "Output should contain pid: " + r.output, - PID_PATTERN.matcher(r.output).find()); + assertEquals(0, r.exitCode, "Command didn't complete in time or failed"); + assertTrue(PID_PATTERN.matcher(r.output).find(), "Output should contain pid: " + r.output); assertFalse(r.proc.isAlive()); } } private Thread newThread(int i, List results) { return new Thread( - new Runnable() { - @Override - public void run() { - try { - command(results, i); - } finally { - System.out.println("Thread " + i + " finished"); - } + () -> { + try { + command(results, i); + } finally { + System.out.println("Thread " + i + " finished"); } }, "test-" + i); @@ -231,42 +222,38 @@ private void command(List results, int i) { } @Test - public void testCommandExecutionFailure() throws Exception { + void testCommandExecutionFailure() throws Exception { ProcReturn r = execCommand(false, false, "false"); assertEquals(1, r.exitCode); assertFalse(r.proc.isAlive()); } @Test - public void testCommandExecutionFailureHighError() throws Exception { + void testCommandExecutionFailureHighError() throws Exception { ProcReturn r = execCommand(false, false, "sh", "-c", "return 127"); assertEquals(127, r.exitCode); assertFalse(r.proc.isAlive()); } @Test - public void testQuietCommandExecution() throws Exception { + void testQuietCommandExecution() throws Exception { ProcReturn r = execCommand(true, false, "echo", "pid is 9999"); - assertFalse( - "Output should not contain command: " + r.output, - PID_PATTERN.matcher(r.output).find()); + assertFalse(PID_PATTERN.matcher(r.output).find(), "Output should not contain command: " + r.output); assertEquals(0, r.exitCode); assertFalse(r.proc.isAlive()); } @Test - public void testCommandExecutionWithNohup() throws Exception { + void testCommandExecutionWithNohup() throws Exception { ProcReturn r = execCommand( false, false, "nohup", "sh", "-c", "sleep 5; cd /tmp; echo pid is $$$$ > test; cat /tmp/test"); - assertTrue( - "Output should contain pid: " + r.output, - PID_PATTERN.matcher(r.output).find()); + assertTrue(PID_PATTERN.matcher(r.output).find(), "Output should contain pid: " + r.output); assertEquals(0, r.exitCode); assertFalse(r.proc.isAlive()); } @Test - public void commandsEscaping() { + void commandsEscaping() { DummyLauncher launcher = new DummyLauncher(null); assertThat( ContainerExecDecorator.getCommands(launcher.launch().cmds("$$$$", "$$?"), null, true), @@ -279,34 +266,34 @@ public void commandsEscaping() { } @Test - public void testCommandExecutionWithEscaping() throws Exception { + void testCommandExecutionWithEscaping() throws Exception { ProcReturn r = execCommand(false, false, "sh", "-c", "cd /tmp; false; echo result is $$? > test; cat /tmp/test"); assertTrue( - "Output should contain result: " + r.output, Pattern.compile("^(result is 1)$", Pattern.MULTILINE) .matcher(r.output) - .find()); + .find(), + "Output should contain result: " + r.output); assertEquals(0, r.exitCode); assertFalse(r.proc.isAlive()); } @Test @Issue("JENKINS-62502") - public void testCommandExecutionEscapingDoubleQuotes() throws Exception { + void testCommandExecutionEscapingDoubleQuotes() throws Exception { ProcReturn r = execCommand(false, false, "sh", "-c", "cd /tmp; false; echo \"result is 1\" > test; cat /tmp/test"); assertTrue( - "Output should contain result: " + r.output, Pattern.compile("^(result is 1)$", Pattern.MULTILINE) .matcher(r.output) - .find()); + .find(), + "Output should contain result: " + r.output); assertEquals(0, r.exitCode); assertFalse(r.proc.isAlive()); } @Test - public void testCommandExecutionOutput() throws Exception { + void testCommandExecutionOutput() throws Exception { String testString = "Should appear once"; // Check output with quiet=false @@ -333,7 +320,7 @@ public void testCommandExecutionOutput() throws Exception { } @Test - public void testCommandExecutionWithNohupAndError() throws Exception { + void testCommandExecutionWithNohupAndError() throws Exception { ProcReturn r = execCommand(false, false, "nohup", "sh", "-c", "sleep 5; return 127"); assertEquals(127, r.exitCode); assertFalse(r.proc.isAlive()); @@ -341,11 +328,12 @@ public void testCommandExecutionWithNohupAndError() throws Exception { @Test @Issue("JENKINS-46719") - public void testContainerDoesNotExist() throws Exception { + void testContainerDoesNotExist() { decorator.setContainerName("doesNotExist"); - exception.expect(KubernetesClientException.class); - exception.expectMessage("container doesNotExist not found in pod"); - execCommand(false, false, "nohup", "sh", "-c", "sleep 5; return 127"); + Throwable exception = assertThrows( + KubernetesClientException.class, + () -> execCommand(false, false, "nohup", "sh", "-c", "sleep 5; return 127")); + assertThat(exception.getMessage(), containsString("container doesNotExist not found in pod")); } /** @@ -359,7 +347,7 @@ public void testContainerDoesNotExist() throws Exception { */ @Test @Issue("JENKINS-55392") - public void testRejectedExecutionException() throws Exception { + void testRejectedExecutionException() throws Exception { List threads = new ArrayList<>(); final AtomicInteger errors = new AtomicInteger(0); for (int i = 0; i < 10; i++) { @@ -378,8 +366,8 @@ public void testRejectedExecutionException() throws Exception { // force expiration of client KubernetesClientProvider.invalidate(cloud.getDisplayName()); cloud.connect(); - threads.stream().forEach(t -> t.start()); - threads.stream().forEach(t -> { + threads.forEach(Thread::start); + threads.forEach(t -> { try { System.out.println("Waiting for " + t.getName()); t.join(); @@ -387,12 +375,12 @@ public void testRejectedExecutionException() throws Exception { throw new RuntimeException(e); } }); - assertEquals("Errors in threads", 0, errors.get()); + assertEquals(0, errors.get(), "Errors in threads"); } @Test @Issue("JENKINS-50429") - public void testContainerExecPerformance() throws Exception { + void testContainerExecPerformance() throws Exception { for (int i = 0; i < 10; i++) { ProcReturn r = execCommand(false, false, "ls"); } @@ -400,19 +388,19 @@ public void testContainerExecPerformance() throws Exception { @Test @Issue("JENKINS-58975") - public void testContainerExecOnCustomWorkingDir() throws Exception { + void testContainerExecOnCustomWorkingDir() throws Exception { doReturn(null).when((Node) agent).toComputer(); ProcReturn r = execCommandInContainer("busybox1", agent, false, false, "env"); assertTrue( - "Environment variable workingDir1 should be changed to /home/jenkins/agent1", - r.output.contains("workingDir1=/home/jenkins/agent1")); + r.output.contains("workingDir1=/home/jenkins/agent1"), + "Environment variable workingDir1 should be changed to /home/jenkins/agent1"); assertEquals(0, r.exitCode); assertFalse(r.proc.isAlive()); } @Test @Issue("JENKINS-58975") - public void testContainerExecOnCustomWorkingDirWithComputeEnvVars() throws Exception { + void testContainerExecOnCustomWorkingDirWithComputeEnvVars() throws Exception { EnvVars computeEnvVars = new EnvVars(); computeEnvVars.put("MyDir", "dir"); computeEnvVars.put("MyCustomDir", "/home/jenkins/agent"); @@ -422,11 +410,11 @@ public void testContainerExecOnCustomWorkingDirWithComputeEnvVars() throws Excep doReturn(computer).when((Node) agent).toComputer(); ProcReturn r = execCommandInContainer("busybox1", agent, false, false, "env"); assertTrue( - "Environment variable workingDir1 should be changed to /home/jenkins/agent1", - r.output.contains("workingDir1=/home/jenkins/agent1")); + r.output.contains("workingDir1=/home/jenkins/agent1"), + "Environment variable workingDir1 should be changed to /home/jenkins/agent1"); assertTrue( - "Environment variable MyCustomDir should be changed to /home/jenkins/agent1", - r.output.contains("MyCustomDir=/home/jenkins/agent1")); + r.output.contains("MyCustomDir=/home/jenkins/agent1"), + "Environment variable MyCustomDir should be changed to /home/jenkins/agent1"); assertEquals(0, r.exitCode); assertFalse(r.proc.isAlive()); } @@ -440,9 +428,10 @@ public void testContainerExecOnCustomWorkingDirWithComputeEnvVars() throws Excep */ @Test @Issue("JENKINS-66986") - public void testRunningANonKubernetesNodeInsideContainerClause() throws Exception { + void testRunningANonKubernetesNodeInsideContainerClause() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); - DummyLauncher dummyLauncher = new DummyLauncher(new StreamTaskListener(new TeeOutputStream(out, System.out))); + DummyLauncher dummyLauncher = + new DummyLauncher(new StreamTaskListener(new TeeOutputStream(out, System.out), StandardCharsets.UTF_8)); dumbAgent = j.createSlave("test", "", null); Launcher launcher = decorator.decorate(dummyLauncher, dumbAgent); assertEquals(dummyLauncher, launcher); @@ -458,7 +447,8 @@ private ProcReturn execCommandInContainer( decorator.setContainerName(containerName); } ByteArrayOutputStream out = new ByteArrayOutputStream(); - DummyLauncher dummyLauncher = new DummyLauncher(new StreamTaskListener(new TeeOutputStream(out, System.out))); + DummyLauncher dummyLauncher = + new DummyLauncher(new StreamTaskListener(new TeeOutputStream(out, System.out), StandardCharsets.UTF_8)); Launcher launcher = decorator.decorate(dummyLauncher, node); Map envs = new HashMap<>(100); for (int i = 0; i < 50; i++) { @@ -476,12 +466,12 @@ private ProcReturn execCommandInContainer( for (int i = 0; proc.isAlive() && i < 200; i++) { Thread.sleep(100); } - assertFalse("proc is alive", proc.isAlive()); + assertFalse(proc.isAlive(), "proc is alive"); int exitCode = proc.join(); return new ProcReturn(proc, exitCode, out.toString()); } - class ProcReturn { + static class ProcReturn { public int exitCode; public String output; public ContainerExecProc proc; diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorWindowsTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorWindowsTest.java index 4dd73abe8b..a5e8fb4e44 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorWindowsTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorWindowsTest.java @@ -30,8 +30,8 @@ import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.deletePods; import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.getLabels; import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.setupCloud; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -62,23 +62,20 @@ import org.csanchez.jenkins.plugins.kubernetes.KubernetesSlave; import org.csanchez.jenkins.plugins.kubernetes.PodTemplate; import org.jenkinsci.plugins.workflow.steps.StepContext; -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TestName; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.LoggerRule; +import org.jvnet.hudson.test.LogRecorder; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.jvnet.hudson.test.recipes.WithTimeout; -public class ContainerExecDecoratorWindowsTest { - @Rule - public ExpectedException exception = ExpectedException.none(); +@WithJenkins +class ContainerExecDecoratorWindowsTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + private JenkinsRule j; private KubernetesCloud cloud; private static KubernetesClient client; @@ -88,22 +85,23 @@ public class ContainerExecDecoratorWindowsTest { private Pod pod; private KubernetesSlave agent; - @Rule - public LoggerRule containerExecLogs = new LoggerRule() + @SuppressWarnings("unused") + private final LogRecorder containerExecLogs = new LogRecorder() .record(Logger.getLogger(ContainerExecDecorator.class.getName()), Level.ALL) .record(Logger.getLogger(KubernetesClientProvider.class.getName()), Level.ALL); - @Rule - public TestName name = new TestName(); + private String name; - @BeforeClass - public static void setUpClass() throws Exception { + @BeforeAll + static void beforeAll() { assumeKubernetes(); assumeWindows(WINDOWS_1809_BUILD); } - @Before - public void configureCloud() throws Exception { + @BeforeEach + void beforeEach(JenkinsRule rule, TestInfo info) throws Exception { + j = rule; + name = info.getTestMethod().orElseThrow().getName(); cloud = setupCloud(this, name); client = cloud.connect(); deletePods(client, getLabels(this, name), false); @@ -147,39 +145,40 @@ public void configureCloud() throws Exception { decorator.setContainerName(image); } - @After - public void after() throws Exception { + @AfterEach + void afterEach() throws Exception { client.pods().delete(pod); deletePods(client, getLabels(this, name), true); } + // in case we need to pull windows docker image @Test - @WithTimeout(value = 900) // in case we need to pull windows docker image - public void testCommandExecution() throws Exception { + @WithTimeout(value = 900) + void testCommandExecution() throws Exception { ByteArrayOutputStream output = new ByteArrayOutputStream(); ProcReturn r = execCommandInContainer("container", null, false, output, "where", "cmd.exe"); - assertEquals("C:\\Windows\\System32\\cmd.exe\r\n", output.toString(StandardCharsets.UTF_8.name())); + assertEquals("C:\\Windows\\System32\\cmd.exe\r\n", output.toString(StandardCharsets.UTF_8)); assertEquals(0, r.exitCode); assertFalse(r.proc.isAlive()); } + // in case we need to pull windows docker image @Test - @WithTimeout(value = 900) // in case we need to pull windows docker image - public void testCommandExecutionNoOutput() throws Exception { + @WithTimeout(value = 900) + void testCommandExecutionNoOutput() throws Exception { ProcReturn r = execCommandInContainer("container", null, false, null, "where", "cmd.exe"); assertEquals(0, r.exitCode); assertFalse(r.proc.isAlive()); } + // in case we need to pull windows docker image @Test - @WithTimeout(value = 900) // in case we need to pull windows docker image - public void testQuietCommandExecution() throws Exception { + @WithTimeout(value = 900) + void testQuietCommandExecution() throws Exception { ByteArrayOutputStream output = new ByteArrayOutputStream(); ProcReturn r = execCommandInContainer("container", null, true, output, "echo", "pid is 9999"); - String out = output.toString(StandardCharsets.UTF_8.name()); - assertFalse( - "Output should not contain command: " + out, - PID_PATTERN.matcher(out).find()); + String out = output.toString(StandardCharsets.UTF_8); + assertFalse(PID_PATTERN.matcher(out).find(), "Output should not contain command: " + out); assertEquals(0, r.exitCode); assertFalse(r.proc.isAlive()); } @@ -189,12 +188,14 @@ private ProcReturn execCommandInContainer( throws Exception { decorator.setContainerName(containerName); ByteArrayOutputStream out = new ByteArrayOutputStream(); - DummyLauncher dummyLauncher = new DummyLauncher(new StreamTaskListener(new TeeOutputStream(out, System.out))) { - @Override - public boolean isUnix() { - return false; - } - }; + DummyLauncher dummyLauncher = + new DummyLauncher( + new StreamTaskListener(new TeeOutputStream(out, System.out), StandardCharsets.UTF_8)) { + @Override + public boolean isUnix() { + return false; + } + }; Launcher launcher = decorator.decorate(dummyLauncher, node); Map envs = new HashMap<>(100); for (int i = 0; i < 50; i++) { @@ -212,12 +213,12 @@ public boolean isUnix() { for (int i = 0; proc.isAlive() && i < 200; i++) { Thread.sleep(100); } - assertFalse("proc is alive", proc.isAlive()); + assertFalse(proc.isAlive(), "proc is alive"); int exitCode = proc.join(); return new ProcReturn(proc, exitCode, out.toString()); } - class ProcReturn { + static class ProcReturn { public int exitCode; public String output; public ContainerExecProc proc; diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerLogStepTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerLogStepTest.java index ba168814eb..04e8dce1d8 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerLogStepTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerLogStepTest.java @@ -16,16 +16,16 @@ package org.csanchez.jenkins.plugins.kubernetes.pipeline; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotNull; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.Issue; -public class ContainerLogStepTest extends AbstractKubernetesPipelineTest { +class ContainerLogStepTest extends AbstractKubernetesPipelineTest { @Issue("JENKINS-46085") @Test - public void getContainerLog() throws Exception { + void getContainerLog() throws Exception { assertNotNull(createJobThenScheduleRun()); r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogContains("INFO: Handshaking", b); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/DirectConnectionTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/DirectConnectionTest.java index 9713823cf8..32e30224ba 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/DirectConnectionTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/DirectConnectionTest.java @@ -20,25 +20,29 @@ import java.util.logging.Level; import org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil; import org.csanchez.jenkins.plugins.kubernetes.PodTemplateBuilder; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; +import org.jvnet.hudson.test.JenkinsRule; -public final class DirectConnectionTest extends AbstractKubernetesPipelineTest { +class DirectConnectionTest extends AbstractKubernetesPipelineTest { static { System.setProperty( TcpSlaveAgentListener.class.getName() + ".hostName", System.getProperty("jenkins.host.address")); } - @Before - public void setUp() throws Exception { + @Override + @BeforeEach + protected void beforeEach(JenkinsRule rule, TestInfo info) throws Exception { + super.beforeEach(rule, info); KubernetesTestUtil.deletePods(cloud.connect(), KubernetesTestUtil.getLabels(cloud, this, name), false); cloud.setDirectConnection(true); logs.record(PodTemplateBuilder.class, Level.FINEST); } @Test - public void directConnectionAgent() throws Exception { + void directConnectionAgent() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(createJobThenScheduleRun())); } } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesAgentErrorConditionTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesAgentErrorConditionTest.java index 20d114cf0f..d095035483 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesAgentErrorConditionTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesAgentErrorConditionTest.java @@ -29,38 +29,44 @@ import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; import org.jenkinsci.plugins.workflow.test.steps.SemaphoreStep; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.jvnet.hudson.test.BuildWatcher; +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.LoggerRule; +import org.jvnet.hudson.test.LogRecorder; +import org.jvnet.hudson.test.junit.jupiter.BuildWatcherExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; @Issue("JENKINS-49707") -public class KubernetesAgentErrorConditionTest { +@WithJenkins +class KubernetesAgentErrorConditionTest { - @ClassRule - public static BuildWatcher buildWatcher = new BuildWatcher(); + @SuppressWarnings("unused") + private static final BuildWatcherExtension BUILD_WATCHER = new BuildWatcherExtension(); - @Rule - public JenkinsRule r = new JenkinsRule(); + private JenkinsRule r; - @Rule - public LoggerRule logging = new LoggerRule().record(KubernetesAgentErrorCondition.class, Level.FINE); + @SuppressWarnings("unused") + private final LogRecorder logging = new LogRecorder().record(KubernetesAgentErrorCondition.class, Level.FINE); + + @BeforeEach + void beforeEach(JenkinsRule rule) { + r = rule; + } @Test - public void handleNonKubernetes() throws Exception { + void handleNonKubernetes() throws Exception { Slave s = r.createSlave(Label.get("remote")); // *not* a KubernetesSlave WorkflowJob p = r.createProject(WorkflowJob.class, "p"); p.addProperty(new ParametersDefinitionProperty(new BooleanParameterDefinition("HNK"))); p.setDefinition(new CpsFlowDefinition( - "retry(count: 2, conditions: [kubernetesAgent(handleNonKubernetes: params.HNK)]) {\n" - + " node('remote') {\n" - + " semaphore 'wait'\n" - + " pwd()\n" - + " }\n" - + "}", + """ + retry(count: 2, conditions: [kubernetesAgent(handleNonKubernetes: params.HNK)]) { + node('remote') { + semaphore 'wait' + pwd() + } + }""", true)); WorkflowRun b = p.scheduleBuild2(0, new ParametersAction(new BooleanParameterValue("HNK", false))) .waitForStart(); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentRJRTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentRJRTest.java index 5b41ad3864..4760ddb172 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentRJRTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentRJRTest.java @@ -16,20 +16,19 @@ package org.csanchez.jenkins.plugins.kubernetes.pipeline; -import java.net.UnknownHostException; import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.AssertBuildStatusSuccess; import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.RunId; import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.SetupCloud; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public final class KubernetesDeclarativeAgentRJRTest extends AbstractKubernetesPipelineRJRTest { +class KubernetesDeclarativeAgentRJRTest extends AbstractKubernetesPipelineRJRTest { - public KubernetesDeclarativeAgentRJRTest() throws UnknownHostException { + public KubernetesDeclarativeAgentRJRTest() throws Exception { super(new SetupCloud()); } @Test - public void declarative() throws Throwable { + void declarative() throws Throwable { RunId runId = createWorkflowJobThenScheduleRun(); rjr.runRemotely(new AssertBuildStatusSuccess(runId)); } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentTest.java index 098b0ee30b..92fb160d62 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentTest.java @@ -27,7 +27,7 @@ // Required for workflow-api graph analysis import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.deletePods; import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.getLabels; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; import com.google.common.base.Predicates; import hudson.model.Result; @@ -35,6 +35,7 @@ import java.util.Map; import jenkins.plugins.git.GitSampleRepoRule; import jenkins.plugins.git.GitStep; +import jenkins.plugins.git.junit.jupiter.WithGitSampleRepo; import org.csanchez.jenkins.plugins.kubernetes.pod.retention.OnFailure; import org.jenkinsci.plugins.structs.describable.UninstantiatedDescribable; import org.jenkinsci.plugins.workflow.actions.ArgumentsAction; @@ -44,18 +45,23 @@ import org.jenkinsci.plugins.workflow.graphanalysis.FlowScanningUtils; import org.jenkinsci.plugins.workflow.graphanalysis.NodeStepTypePredicate; import org.jenkinsci.plugins.workflow.job.WorkflowJob; -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; -public class KubernetesDeclarativeAgentTest extends AbstractKubernetesPipelineTest { +@WithGitSampleRepo +class KubernetesDeclarativeAgentTest extends AbstractKubernetesPipelineTest { - @Rule - public GitSampleRepoRule repoRule = new GitSampleRepoRule(); + private GitSampleRepoRule repoRule; + + @BeforeEach + void beforeEach(GitSampleRepoRule repo) { + repoRule = repo; + } @Issue({"JENKINS-41758", "JENKINS-57827", "JENKINS-60886"}) @Test - public void declarative() throws Exception { + void declarative() throws Exception { assertNotNull(createJobThenScheduleRun()); r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogContains("Apache Maven 3.3.9", b); @@ -67,7 +73,7 @@ public void declarative() throws Exception { Predicates.and( new NodeStepTypePredicate("podTemplate"), FlowScanningUtils.hasActionPredicate(ArgumentsAction.class))); - assertNotNull("recorded arguments for podTemplate", podTemplateNode); + assertNotNull(podTemplateNode, "recorded arguments for podTemplate"); Map arguments = podTemplateNode.getAction(ArgumentsAction.class).getArguments(); FlowNode nodeNode = new DepthFirstScanner() @@ -76,7 +82,7 @@ public void declarative() throws Exception { Predicates.and( new NodeStepTypePredicate("node"), FlowScanningUtils.hasActionPredicate(ArgumentsAction.class))); - assertNotNull("recorded arguments for node", nodeNode); + assertNotNull(nodeNode, "recorded arguments for node"); Map nodeArguments = nodeNode.getAction(ArgumentsAction.class).getArguments(); assertEquals("labels && multiple", nodeArguments.get("label")); @@ -84,24 +90,23 @@ public void declarative() throws Exception { List containers = (List) arguments.get("containers"); assertNotNull(containers); assertFalse( - "no junk in arguments: " + arguments, - containers.get(0).getArguments().containsKey("alwaysPullImage")); + containers.get(0).getArguments().containsKey("alwaysPullImage"), "no junk in arguments: " + arguments); FlowNode containerNode = new DepthFirstScanner() .findFirstMatch( b.getExecution(), Predicates.and( new NodeStepTypePredicate("container"), FlowScanningUtils.hasActionPredicate(ArgumentsAction.class))); - assertNotNull("recorded arguments for container", containerNode); + assertNotNull(containerNode, "recorded arguments for container"); // JENKINS-60886 UninstantiatedDescribable podRetention = (UninstantiatedDescribable) arguments.get("podRetention"); assertNotNull(podRetention); - assertEquals(podRetention.getModel().getType(), OnFailure.class); + assertEquals(OnFailure.class, podRetention.getModel().getType()); } @Issue("JENKINS-48135") @Test - public void declarativeFromYaml() throws Exception { + void declarativeFromYaml() throws Exception { assertNotNull(createJobThenScheduleRun()); r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogContains("Apache Maven 3.3.9", b); @@ -112,7 +117,7 @@ public void declarativeFromYaml() throws Exception { @Issue("JENKINS-51610") @Test - public void declarativeWithNamespaceFromYaml() throws Exception { + void declarativeWithNamespaceFromYaml() throws Exception { createNamespaceIfNotExist(cloud.connect(), "kubernetes-plugin-test-overridden-namespace"); assertNotNull(createJobThenScheduleRun()); r.assertBuildStatusSuccess(r.waitForCompletion(b)); @@ -124,7 +129,7 @@ public void declarativeWithNamespaceFromYaml() throws Exception { @Issue("JENKINS-52259") @Test - public void declarativeFromYamlFile() throws Exception { + void declarativeFromYamlFile() throws Exception { repoRule.init(); repoRule.write("Jenkinsfile", loadPipelineDefinition()); repoRule.write("declarativeYamlFile.yml", loadPipelineScript("declarativeYamlFile.yml")); @@ -144,7 +149,7 @@ public void declarativeFromYamlFile() throws Exception { } @Test - public void declarativeFromYamlWithNullEnv() throws Exception { + void declarativeFromYamlWithNullEnv() throws Exception { assertNotNull(createJobThenScheduleRun()); r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogContains("\njnlp container: OK\n", b); @@ -153,7 +158,7 @@ public void declarativeFromYamlWithNullEnv() throws Exception { @Issue("JENKINS-52623") @Test - public void declarativeSCMVars() throws Exception { + void declarativeSCMVars() throws Exception { p = r.jenkins.createProject(WorkflowJob.class, "job with repo"); // We can't use a local GitSampleRepoRule for this because the repo has to be accessible from within the // container. @@ -166,7 +171,7 @@ public void declarativeSCMVars() throws Exception { @Issue("JENKINS-53817") @Test - public void declarativeCustomWorkspace() throws Exception { + void declarativeCustomWorkspace() throws Exception { assertNotNull(createJobThenScheduleRun()); r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogContains("Apache Maven 3.3.9", b); @@ -175,7 +180,7 @@ public void declarativeCustomWorkspace() throws Exception { @Issue("JENKINS-58975") @Test - public void declarativeCustomWorkingDir() throws Exception { + void declarativeCustomWorkingDir() throws Exception { assertNotNull(createJobThenScheduleRun()); r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogContains( @@ -191,7 +196,7 @@ public void declarativeCustomWorkingDir() throws Exception { @Issue("JENKINS-57548") @Test - public void declarativeWithNestedExplicitInheritance() throws Exception { + void declarativeWithNestedExplicitInheritance() throws Exception { assertNotNull(createJobThenScheduleRun()); r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogContains("Apache Maven 3.3.9", b); @@ -199,14 +204,14 @@ public void declarativeWithNestedExplicitInheritance() throws Exception { } @Test - public void declarativeWithNonexistentDockerImage() throws Exception { + void declarativeWithNonexistentDockerImage() throws Exception { assertNotNull(createJobThenScheduleRun()); r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b)); r.assertLogContains("ERROR: Unable to pull container image", b); } @Test - public void declarativeWithCreateContainerError() throws Exception { + void declarativeWithCreateContainerError() throws Exception { assertNotNull(createJobThenScheduleRun()); r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b)); r.assertLogContains("was terminated", b); @@ -214,7 +219,7 @@ public void declarativeWithCreateContainerError() throws Exception { @Issue("JENKINS-61360") @Test - public void declarativeShowRawYamlFalse() throws Exception { + void declarativeShowRawYamlFalse() throws Exception { assertNotNull(createJobThenScheduleRun()); r.assertBuildStatusSuccess(r.waitForCompletion(b)); // check yaml metadata labels not logged @@ -223,7 +228,7 @@ public void declarativeShowRawYamlFalse() throws Exception { @Issue("JENKINS-49707") @Test - public void declarativeRetries() throws Exception { + void declarativeRetries() throws Exception { assertNotNull(createJobThenScheduleRun()); r.waitForMessage("+ sleep", b); deletePods(cloud.connect(), getLabels(this, name), false); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentUnitTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentUnitTest.java index 13926cbec0..46f10185cf 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentUnitTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentUnitTest.java @@ -11,35 +11,42 @@ import org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.DynamicPVCWorkspaceVolume; import org.jenkinsci.plugins.pipeline.modeldefinition.generator.AgentDirective; import org.jenkinsci.plugins.pipeline.modeldefinition.generator.DirectiveGeneratorTester; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; +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; -public class KubernetesDeclarativeAgentUnitTest { - @ClassRule - public static JenkinsRule j = new JenkinsRule(); +@WithJenkins +class KubernetesDeclarativeAgentUnitTest { - KubernetesDeclarativeAgent instance; + private static JenkinsRule j; - DirectiveGeneratorTester dg; - AgentDirective directive; + private KubernetesDeclarativeAgent instance; - @Before - public void setUp() { + private DirectiveGeneratorTester dg; + private AgentDirective directive; + + @BeforeAll + static void beforeAll(JenkinsRule rule) { + j = rule; + } + + @BeforeEach + void beforeEach() { instance = new KubernetesDeclarativeAgent(); directive = new AgentDirective(instance); dg = new DirectiveGeneratorTester(j); } @Test - public void serializationNull() { + void serializationNull() { Map args = instance.getAsArgs(); assertThat(args, equalTo(Collections.emptyMap())); } @Test - public void serialization() throws Exception { + void serialization() { instance.setCloud("cloud"); instance.setLabel("label"); instance.setYaml("yaml"); @@ -67,12 +74,16 @@ public void serialization() throws Exception { } @Test - public void simpleGenerator() throws Exception { - dg.assertGenerateDirective(directive, "agent {\n" + " kubernetes true\n" + "}"); + void simpleGenerator() throws Exception { + dg.assertGenerateDirective( + directive, """ + agent { + kubernetes true + }"""); } @Test - public void complexGenerator() throws Exception { + void complexGenerator() throws Exception { instance.setCloud("cloud"); instance.setYaml("yaml"); instance.setYamlMergeStrategy(new Merge()); @@ -85,14 +96,16 @@ public void complexGenerator() throws Exception { instance.setInheritFrom("inheritFrom"); dg.assertGenerateDirective( directive, - "agent {\n" + " kubernetes {\n" - + " cloud 'cloud'\n" - + " inheritFrom 'inheritFrom'\n" - + " podRetention never()\n" - + " workspaceVolume dynamicPVC(accessModes: 'ReadWrite', requestsSize: '1G', storageClassName: 'sc')\n" - + " yaml 'yaml'\n" - + " yamlMergeStrategy merge()\n" - + " }\n" - + "}"); + """ + agent { + kubernetes { + cloud 'cloud' + inheritFrom 'inheritFrom' + podRetention never() + workspaceVolume dynamicPVC(accessModes: 'ReadWrite', requestsSize: '1G', storageClassName: 'sc') + yaml 'yaml' + yamlMergeStrategy merge() + } + }"""); } } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesNodeContextTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesNodeContextTest.java index f038893e4d..2eddf46762 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesNodeContextTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesNodeContextTest.java @@ -1,6 +1,6 @@ package org.csanchez.jenkins.plugins.kubernetes.pipeline; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -10,14 +10,17 @@ import org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud; import org.csanchez.jenkins.plugins.kubernetes.KubernetesSlave; import org.jenkinsci.plugins.workflow.steps.StepContext; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; -@RunWith(MockitoJUnitRunner.class) -public class KubernetesNodeContextTest { +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +class KubernetesNodeContextTest { @Mock private StepContext context; @@ -31,15 +34,15 @@ public class KubernetesNodeContextTest { @Mock private PodResource podResource; - @Before - public void setup() { + @BeforeEach + void beforeEach() { when(slave.getKubernetesCloud()).thenReturn(cloud); when(slave.getPodName()).thenReturn("foo"); when(slave.getNamespace()).thenReturn("bar"); } @Test - public void createContext() throws Exception { + void createContext() throws Exception { when(cloud.getPodResource("bar", "foo")).thenReturn(podResource); when(context.get(Node.class)).thenReturn(slave); KubernetesNodeContext knc = new KubernetesNodeContext(context); @@ -50,14 +53,10 @@ public void createContext() throws Exception { } @Test - public void notKubernetesSlaveInstance() throws Exception { + void notKubernetesSlaveInstance() throws Exception { Node node = mock(Node.class); when(context.get(Node.class)).thenReturn(node); - try { - new KubernetesNodeContext(context); - fail("expected abort exception"); - } catch (AbortException ae) { - assertTrue(ae.getMessage().startsWith("Node is not a Kubernetes node")); - } + AbortException ae = assertThrows(AbortException.class, () -> new KubernetesNodeContext(context)); + assertTrue(ae.getMessage().startsWith("Node is not a Kubernetes node")); } } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineOverridenNamespaceTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineOverriddenNamespaceTest.java similarity index 84% rename from src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineOverridenNamespaceTest.java rename to src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineOverriddenNamespaceTest.java index b6ec70ae68..4b65548d9d 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineOverridenNamespaceTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineOverriddenNamespaceTest.java @@ -1,19 +1,19 @@ package org.csanchez.jenkins.plugins.kubernetes.pipeline; import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.testingNamespace; -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.util.HashMap; import java.util.Map; import org.csanchez.jenkins.plugins.kubernetes.KubernetesComputer; import org.jenkinsci.plugins.workflow.test.steps.SemaphoreStep; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class KubernetesPipelineOverridenNamespaceTest extends AbstractKubernetesPipelineTest { +class KubernetesPipelineOverriddenNamespaceTest extends AbstractKubernetesPipelineTest { @Test - public void runWithCloudOverriddenNamespace() throws Exception { + void runWithCloudOverriddenNamespace() throws Exception { String overriddenNamespace = testingNamespace + "-overridden-namespace"; cloud.setNamespace(overriddenNamespace); // Run in our own testing namespace @@ -36,7 +36,7 @@ public void runWithCloudOverriddenNamespace() throws Exception { * Step namespace should have priority over anything else. */ @Test - public void runWithStepOverriddenNamespace() throws Exception { + void runWithStepOverriddenNamespace() throws Exception { String overriddenNamespace = testingNamespace + "-overridden-namespace"; String stepNamespace = testingNamespace + "-overridden-namespace2"; cloud.setNamespace(overriddenNamespace); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineRJRTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineRJRTest.java index 71e4a484ef..5fa02969fe 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineRJRTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineRJRTest.java @@ -3,31 +3,31 @@ import io.fabric8.kubernetes.api.model.NodeBuilder; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.KubernetesClientBuilder; -import java.net.UnknownHostException; import org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil; import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.AssertBuildLogMessage; import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.AssertBuildStatusSuccess; import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.CreateWorkflowJobThenScheduleTask; import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.RunId; import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.SetupCloud; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class KubernetesPipelineRJRTest extends AbstractKubernetesPipelineRJRTest { - public KubernetesPipelineRJRTest() throws UnknownHostException { +class KubernetesPipelineRJRTest extends AbstractKubernetesPipelineRJRTest { + + public KubernetesPipelineRJRTest() throws Exception { super(new SetupCloud()); } @Test - public void basicPipeline() throws Throwable { + void basicPipeline() throws Throwable { RunId runId = createWorkflowJobThenScheduleRun(); rjr.runRemotely(new AssertBuildStatusSuccess(runId)); } @Test - public void restartDuringPodLaunch() throws Throwable { + void restartDuringPodLaunch() throws Throwable { // try to run something on a pod which is not schedulable (disktype=special) RunId build = rjr.runRemotely(new CreateWorkflowJobThenScheduleTask( - KubernetesTestUtil.loadPipelineScript(getClass(), name.getMethodName() + ".groovy"))); + KubernetesTestUtil.loadPipelineScript(getClass(), name + ".groovy"))); // the pod is created, but not connected yet rjr.runRemotely(new AssertBuildLogMessage("Created Pod", build)); // restart diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineTest.java index 9dae310081..ba164a3ee9 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineTest.java @@ -39,13 +39,8 @@ import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.oneOf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeNoException; -import static org.junit.Assume.assumeNotNull; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.assumeTrue; import edu.umd.cs.findbugs.annotations.NonNull; import hudson.model.Computer; @@ -88,44 +83,34 @@ import org.htmlunit.html.DomNodeUtil; import org.htmlunit.html.HtmlElement; import org.htmlunit.html.HtmlPage; -import org.jenkinsci.plugins.kubernetes.auth.KubernetesAuthException; import org.jenkinsci.plugins.workflow.flow.FlowDurabilityHint; import org.jenkinsci.plugins.workflow.flow.GlobalDefaultFlowDurabilityLevel; import org.jenkinsci.plugins.workflow.job.WorkflowRun; import org.jenkinsci.plugins.workflow.steps.durable_task.DurableTaskStep; import org.jenkinsci.plugins.workflow.test.steps.SemaphoreStep; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.jvnet.hudson.test.FlagRule; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.LoggerRule; +import org.jvnet.hudson.test.LogRecorder; import org.jvnet.hudson.test.MockAuthorizationStrategy; import org.jvnet.hudson.test.TestExtension; -public class KubernetesPipelineTest extends AbstractKubernetesPipelineTest { +class KubernetesPipelineTest extends AbstractKubernetesPipelineTest { private static final Logger LOGGER = Logger.getLogger(KubernetesPipelineTest.class.getName()); public static final String POD_DEADLINE_EXCEEDED_MESSAGE = "Pod just failed. Reason: DeadlineExceeded, Message: Pod was active on the node longer than the specified deadline."; - @Rule - public TemporaryFolder tmp = new TemporaryFolder(); + private final LogRecorder warnings = new LogRecorder().quiet(); - @Rule - public LoggerRule warnings = new LoggerRule().quiet(); + private boolean substituteEnv; - @Rule - public FlagRule substituteEnv = - new FlagRule<>(() -> PodTemplateUtils.SUBSTITUTE_ENV, x -> PodTemplateUtils.SUBSTITUTE_ENV = x); - - @Before - public void setUp() throws Exception { + @BeforeEach + void beforeEach() throws Exception { + substituteEnv = PodTemplateUtils.SUBSTITUTE_ENV; // Had some problems with FileChannel.close hangs from WorkflowRun.save: r.jenkins .getDescriptorByType(GlobalDefaultFlowDurabilityLevel.DescriptorImpl.class) @@ -137,8 +122,10 @@ public void setUp() throws Exception { /** * Ensure all builds are complete by the end of the test. */ - @After - public void allDead() throws Exception { + @AfterEach + void afterEach() throws Exception { + PodTemplateUtils.SUBSTITUTE_ENV = substituteEnv; + if (b != null && b.isLogUpdated()) { LOGGER.warning(() -> "Had to interrupt " + b); b.getExecutor().interrupt(); @@ -161,15 +148,15 @@ public void allDead() throws Exception { @Issue("JENKINS-57993") @Test - public void runInPod() throws Exception { + void runInPod() throws Exception { warnings.record("", Level.WARNING).capture(1000); SemaphoreStep.waitForStart("podTemplate/1", b); - List templates = podTemplatesWithLabel(name.getMethodName(), cloud.getAllTemplates()); + List templates = podTemplatesWithLabel(name, cloud.getAllTemplates()); assertThat(templates, hasSize(1)); SemaphoreStep.success("podTemplate/1", null); // check if build failed - assertTrue("Build has failed early: " + b.getResult(), b.isBuilding() || Result.SUCCESS.equals(b.getResult())); + assertTrue(b.isBuilding() || Result.SUCCESS.equals(b.getResult()), "Build has failed early: " + b.getResult()); LOGGER.log(Level.INFO, "Found templates with label runInPod: {0}", templates); for (PodTemplate template : cloud.getAllTemplates()) { @@ -204,7 +191,7 @@ public void runInPod() throws Exception { PodList pods = cloud.connect().pods().withLabels(labels).list(); assertThat( "Expected one pod with labels " + labels + " but got: " - + pods.getItems().stream().map(pod -> pod.getMetadata()).collect(Collectors.toList()), + + pods.getItems().stream().map(Pod::getMetadata).toList(), pods.getItems(), hasSize(1)); SemaphoreStep.success("pod/1", null); @@ -221,26 +208,23 @@ public void runInPod() throws Exception { } assertTrue(foundBuildUrl); assertEquals(Integer.MAX_VALUE, template.getInstanceCap()); - assertThat(template.getLabelsMap(), hasEntry("jenkins/label", name.getMethodName())); + assertThat(template.getLabelsMap(), hasEntry("jenkins/label", name)); Pod pod = pods.getItems().get(0); LOGGER.log(Level.INFO, "One pod found: {0}", pod); assertThat(pod.getMetadata().getLabels(), hasEntry("jenkins", "slave")); - assertThat( - "Pod labels are wrong: " + pod, - pod.getMetadata().getLabels(), - hasEntry("jenkins/label", name.getMethodName())); + assertThat("Pod labels are wrong: " + pod, pod.getMetadata().getLabels(), hasEntry("jenkins/label", name)); SemaphoreStep.waitForStart("after-podtemplate/1", b); - assertThat(podTemplatesWithLabel(name.getMethodName(), cloud.getAllTemplates()), hasSize(0)); + assertThat(podTemplatesWithLabel(name, cloud.getAllTemplates()), hasSize(0)); SemaphoreStep.success("after-podtemplate/1", null); r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogContains("container=busybox", b); r.assertLogContains("script file contents: ", b); assertFalse( - "There are pods leftover after test execution, see previous logs", - deletePods(cloud.connect(), getLabels(cloud, this, name), true)); + deletePods(cloud.connect(), getLabels(cloud, this, name), true), + "There are pods leftover after test execution, see previous logs"); assertThat( "routine build should not issue warnings", warnings.getRecords().stream() @@ -254,9 +238,9 @@ public void runInPod() throws Exception { } @Test - public void runIn2Pods() throws Exception { + void runIn2Pods() throws Exception { SemaphoreStep.waitForStart("podTemplate1/1", b); - String label1 = name.getMethodName() + "-1"; + String label1 = name + "-1"; PodTemplate template1 = podTemplatesWithLabel(label1, cloud.getAllTemplates()).get(0); SemaphoreStep.success("podTemplate1/1", null); @@ -270,13 +254,13 @@ public void runIn2Pods() throws Exception { SemaphoreStep.success("pod1/1", null); SemaphoreStep.waitForStart("podTemplate2/1", b); - String label2 = name.getMethodName() + "-2"; + String label2 = name + "-2"; PodTemplate template2 = podTemplatesWithLabel(label2, cloud.getAllTemplates()).get(0); SemaphoreStep.success("podTemplate2/1", null); assertEquals(Integer.MAX_VALUE, template2.getInstanceCap()); assertThat(template2.getLabelsMap(), hasEntry("jenkins/label", label2)); - assertNull(label2 + " should not inherit from anything", template2.getInheritFrom()); + assertNull(template2.getInheritFrom(), label2 + " should not inherit from anything"); SemaphoreStep.waitForStart("pod2/1", b); Map labels2 = getLabels(cloud, this, name); labels1.put("jenkins/label", label2); @@ -286,13 +270,13 @@ public void runIn2Pods() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogContains("script file contents: ", b); assertFalse( - "There are pods leftover after test execution, see previous logs", - deletePods(cloud.connect(), getLabels(cloud, this, name), true)); + deletePods(cloud.connect(), getLabels(cloud, this, name), true), + "There are pods leftover after test execution, see previous logs"); } @Issue({"JENKINS-57893", "SECURITY-3079"}) @Test - public void runInPodFromYaml() throws Exception { + void runInPodFromYaml() throws Exception { List templates = cloud.getTemplates(); while (templates.isEmpty()) { LOGGER.log(Level.INFO, "Waiting for template to be created"); @@ -310,8 +294,8 @@ public void runInPodFromYaml() throws Exception { + CONTAINER_ENV_VAR_FROM_SECRET_VALUE.toUpperCase(Locale.ROOT) + "\n", b); assertFalse( - "There are pods leftover after test execution, see previous logs", - deletePods(cloud.connect(), getLabels(cloud, this, name), true)); + deletePods(cloud.connect(), getLabels(cloud, this, name), true), + "There are pods leftover after test execution, see previous logs"); // SECURITY-3079 DurableTaskStep.USE_WATCHING = true; @@ -329,20 +313,20 @@ public void runInPodFromYaml() throws Exception { } @Test - public void runInPodWithDifferentShell() throws Exception { + void runInPodWithDifferentShell() throws Exception { r.assertBuildStatus(Result.FAILURE, r.waitForCompletion(b)); r.assertLogContains("ERROR: Process exited immediately after creation", b); // r.assertLogContains("/bin/bash: no such file or directory", b); // Not printed in CI for an unknown reason. } @Test - public void bourneShellElsewhereInPath() throws Exception { + void bourneShellElsewhereInPath() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogContains("/kaniko:/busybox", b); } @Test - public void inheritFrom() throws Exception { + void inheritFrom() throws Exception { PodTemplate standard = new PodTemplate(); standard.setName("standard"); cloud.addTemplate(standard); @@ -350,7 +334,7 @@ public void inheritFrom() throws Exception { } @Test - public void runInPodWithMultipleContainers() throws Exception { + void runInPodWithMultipleContainers() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogContains("image: \"maven:3.3.9-jdk-8-alpine\"", b); r.assertLogContains("image: \"golang:1.6.3-alpine\"", b); @@ -360,7 +344,7 @@ public void runInPodWithMultipleContainers() throws Exception { } @Test - public void runInPodNested() throws Exception { + void runInPodNested() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogContains("image: \"maven:3.3.9-jdk-8-alpine\"", b); r.assertLogContains("image: \"golang:1.6.3-alpine\"", b); @@ -370,7 +354,7 @@ public void runInPodNested() throws Exception { @Issue("JENKINS-57548") @Test - public void runInPodNestedExplicitInherit() throws Exception { + void runInPodNestedExplicitInherit() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogContains("image: \"maven:3.3.9-jdk-8-alpine\"", b); r.assertLogNotContains("image: \"golang:1.6.3-alpine\"", b); @@ -380,7 +364,7 @@ public void runInPodNestedExplicitInherit() throws Exception { @Issue({"JENKINS-57893", "JENKINS-58540"}) @Test - public void runInPodWithExistingTemplate() throws Exception { + void runInPodWithExistingTemplate() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogContains("outside container", b); r.assertLogContains("inside container", b); @@ -389,7 +373,7 @@ public void runInPodWithExistingTemplate() throws Exception { @Issue({"JENKINS-57893", "JENKINS-58540"}) @Test - public void runWithEnvVariables() throws Exception { + void runWithEnvVariables() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); assertEnvVars(r, b); r.assertLogContains("OUTSIDE_CONTAINER_BUILD_NUMBER = 1\n", b); @@ -414,7 +398,7 @@ public void runWithEnvVariables() throws Exception { } @Test - public void runWithEnvVariablesInContext() throws Exception { + void runWithEnvVariablesInContext() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogContains("The initial value of POD_ENV_VAR is pod-env-var-value", b); r.assertLogContains("The value of POD_ENV_VAR outside container is /bin/mvn:pod-env-var-value", b); @@ -461,7 +445,7 @@ private void assertEnvVars(JenkinsRule r2, WorkflowRun b) throws Exception { } @Test - public void runWithOverriddenEnvVariables() throws Exception { + void runWithOverriddenEnvVariables() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogContains("OUTSIDE_CONTAINER_HOME_ENV_VAR = /home/jenkins\n", b); r.assertLogContains("INSIDE_CONTAINER_HOME_ENV_VAR = /root\n", b); @@ -470,7 +454,7 @@ public void runWithOverriddenEnvVariables() throws Exception { } @Test - public void supportComputerEnvVars() throws Exception { + void supportComputerEnvVars() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogContains("OPENJDK_BUILD_NUMBER: 1\n", b); r.assertLogContains("JNLP_BUILD_NUMBER: 1\n", b); @@ -478,7 +462,7 @@ public void supportComputerEnvVars() throws Exception { } @Test - public void runDirContext() throws Exception { + void runDirContext() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); String workspace = "/home/jenkins/agent/workspace/" + getProjectName(); r.assertLogContains("initpwd is -" + workspace + "-", b); @@ -487,13 +471,13 @@ public void runDirContext() throws Exception { } @Test - public void runInPodWithLivenessProbe() throws Exception { + void runInPodWithLivenessProbe() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogContains("Still alive", b); } @Test - public void podTemplateWithMultipleLabels() throws Exception { + void podTemplateWithMultipleLabels() throws Exception { PodTemplate pt = new PodTemplate(); pt.setName("podTemplate"); pt.setLabel("label1 label2"); @@ -513,7 +497,7 @@ public void podTemplateWithMultipleLabels() throws Exception { + pods.getItems().stream() .map(Pod::getMetadata) .map(ObjectMeta::getName) - .collect(Collectors.toList()), + .toList(), pods.getItems(), hasSize(1)); SemaphoreStep.success("pod/1", null); @@ -521,10 +505,10 @@ public void podTemplateWithMultipleLabels() throws Exception { } @Test - public void runWithActiveDeadlineSeconds() throws Exception { + void runWithActiveDeadlineSeconds() throws Exception { SemaphoreStep.waitForStart("podTemplate/1", b); PodTemplate deadlineTemplate = cloud.getAllTemplates().stream() - .filter(x -> name.getMethodName().equals(x.getLabel())) + .filter(x -> name.equals(x.getLabel())) .findAny() .orElse(null); assertNotNull(deadlineTemplate); @@ -535,17 +519,17 @@ public void runWithActiveDeadlineSeconds() throws Exception { } @Test - public void runInPodWithRetention() throws Exception { + void runInPodWithRetention() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); System.out.println("Deleting leftover pods"); KubernetesClient client = cloud.connect(); Map labels = getLabels(this, name); - assertTrue(client.pods().withLabels(labels).delete().size() > 0); + assertFalse(client.pods().withLabels(labels).delete().isEmpty()); } @Issue("JENKINS-49707") @Test - public void terminatedPod() throws Exception { + void terminatedPod() throws Exception { logs.record(KubernetesAgentErrorCondition.class, Level.FINE); r.waitForMessage("+ sleep", b); deletePods(cloud.connect(), getLabels(this, name), false); @@ -558,7 +542,7 @@ public void terminatedPod() throws Exception { @Issue("JENKINS-59340") @Test - public void containerTerminated() throws Exception { + void containerTerminated() throws Exception { assertBuildStatus(r.waitForCompletion(b), Result.FAILURE, Result.ABORTED); r.waitForMessage("Container stress-ng was terminated", b); /* TODO sometimes instead get: Container stress-ng was terminated (Exit Code: 0, Reason: Completed) @@ -567,7 +551,7 @@ public void containerTerminated() throws Exception { } @Test - public void errorPod() throws Exception { + void errorPod() throws Exception { r.waitForMessage("jnlp -- terminated (1)", b); r.waitForMessage("Foo", b); r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b)); @@ -575,13 +559,13 @@ public void errorPod() throws Exception { @Issue("JENKINS-59340") @Test - public void podDeadlineExceeded() throws Exception { + void podDeadlineExceeded() throws Exception { r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b)); r.waitForMessage(POD_DEADLINE_EXCEEDED_MESSAGE, b); } @Test - public void podDeadlineExceededGlobalTemplate() throws Exception { + void podDeadlineExceededGlobalTemplate() throws Exception { PodTemplate podTemplate = new PodTemplate("podDeadlineExceededGlobalTemplate"); podTemplate.setLabel("podDeadlineExceededGlobalTemplate"); podTemplate.setActiveDeadlineSeconds(30); @@ -592,7 +576,7 @@ public void podDeadlineExceededGlobalTemplate() throws Exception { } @Test - public void interruptedPod() throws Exception { + void interruptedPod() throws Exception { r.waitForMessage("starting to sleep", b); b.getExecutor().interrupt(); r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b)); @@ -601,18 +585,20 @@ public void interruptedPod() throws Exception { @Issue("JENKINS-58306") @Test - public void cascadingDelete() throws Exception { + void cascadingDelete() throws Exception { try { cloud.connect().apps().deployments().withName("cascading-delete").delete(); - assumeNotNull(cloud.connect().serviceAccounts().withName("jenkins").get()); + assumeTrue(cloud.connect().serviceAccounts().withName("jenkins").get() != null); } catch (KubernetesClientException x) { // Failure executing: DELETE at: // https://…/apis/apps/v1/namespaces/kubernetes-plugin-test/deployments/cascading-delete. Message: // Forbidden!Configured service account doesn't have access. Service account may have been revoked. // deployments.apps "cascading-delete" is forbidden: User "system:serviceaccount:…:…" cannot delete resource // "deployments" in API group "apps" in the namespace "kubernetes-plugin-test". - assumeNoException( - "was not permitted to clean up any previous deployment, so presumably cannot run test either", x); + assumeTrue( + false, + "was not permitted to clean up any previous deployment, so presumably cannot run test either: " + + x); } cloud.connect() .apps() @@ -624,8 +610,8 @@ public void cascadingDelete() throws Exception { } @Test - @Ignore - public void computerCantBeConfigured() throws Exception { + @Disabled + void computerCantBeConfigured() throws Exception { r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); r.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy() .grant(Jenkins.MANAGE) @@ -652,39 +638,39 @@ public void computerCantBeConfigured() throws Exception { private void assertNotXPath(HtmlPage page, String xpath) { HtmlElement documentElement = page.getDocumentElement(); assertNull( - "There should not be an object that matches XPath:" + xpath, - DomNodeUtil.selectSingleNode(documentElement, xpath)); + DomNodeUtil.selectSingleNode(documentElement, xpath), + "There should not be an object that matches XPath:" + xpath); } @Issue("JENKINS-57717") @Test - public void runInPodWithShowRawYamlFalse() throws Exception { + void runInPodWithShowRawYamlFalse() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogNotContains("value: \"container-env-var-value\"", b); } @Issue("JENKINS-58574") @Test - public void showRawYamlFalseInherited() throws Exception { + void showRawYamlFalseInherited() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); r.assertLogNotContains("value: \"container-env-var-value\"", b); } @Test @Issue("JENKINS-58405") - public void overrideYaml() throws Exception { + void overrideYaml() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); } @Test @Issue("JENKINS-58405") - public void mergeYaml() throws Exception { + void mergeYaml() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); } @Test @Issue("JENKINS-58602") - public void jenkinsSecretHidden() throws Exception { + void jenkinsSecretHidden() throws Exception { SemaphoreStep.waitForStart("pod/1", b); Optional scOptional = Arrays.stream(r.jenkins.getComputers()) .filter(SlaveComputer.class::isInstance) @@ -698,19 +684,19 @@ public void jenkinsSecretHidden() throws Exception { } @Test - public void jnlpWorkingDir() throws Exception { + void jnlpWorkingDir() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); } @Issue("JENKINS-61178") @Test - public void sidecarWorkingDir() throws Exception { + void sidecarWorkingDir() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); } @Issue("JENKINS-60517") @Test - public void runInDynamicallyCreatedContainer() throws Exception { + void runInDynamicallyCreatedContainer() throws Exception { List templates = cloud.getTemplates(); while (templates.isEmpty()) { LOGGER.log(Level.INFO, "Waiting for template to be created"); @@ -727,7 +713,7 @@ public void runInDynamicallyCreatedContainer() throws Exception { @Issue("JENKINS-57256") @Test - public void basicWindows() throws Exception { + void basicWindows() throws Exception { assumeWindows(WINDOWS_1809_BUILD); cloud.setDirectConnection(false); // not yet supported by // https://github.com/jenkinsci/docker-inbound-agent/blob/517ccd68fd1ce420e7526ca6a40320c9a47a2c18/jenkins-agent.ps1 @@ -738,7 +724,7 @@ public void basicWindows() throws Exception { @Issue("JENKINS-53500") @Test - public void windowsContainer() throws Exception { + void windowsContainer() throws Exception { assumeWindows(WINDOWS_1809_BUILD); cloud.setDirectConnection(false); r.assertBuildStatusSuccess(r.waitForCompletion(b)); @@ -747,9 +733,9 @@ public void windowsContainer() throws Exception { r.assertLogContains("got stuff: some value", b); } + @Disabled("Does not appear fixable: https://github.com/jenkinsci/kubernetes-plugin/pull/1724#discussion_r2287512410") @Test - @Ignore("Does not appear fixable: https://github.com/jenkinsci/kubernetes-plugin/pull/1724#discussion_r2287512410") - public void interruptedPodWindows() throws Exception { + void interruptedPodWindows() throws Exception { assumeWindows(WINDOWS_1809_BUILD); cloud.setDirectConnection(false); r.waitForMessage("starting to sleep", b); @@ -764,7 +750,7 @@ public void interruptedPodWindows() throws Exception { // and hence files blocked. The test is a bit unrealistic as I want it // to be fast and deterministic, but imagine that instead of the ping we execute // a big checkout that locks some files and prevents next steps to execute - public void killsProcessesWindows() throws Exception { + void killsProcessesWindows() throws Exception { assumeWindows(WINDOWS_1809_BUILD); cloud.setDirectConnection(false); r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b)); @@ -772,7 +758,7 @@ public void killsProcessesWindows() throws Exception { } @Test - public void secretMaskingWindows() throws Exception { + void secretMaskingWindows() throws Exception { assumeWindows(WINDOWS_1809_BUILD); cloud.setDirectConnection(false); r.assertBuildStatusSuccess(r.waitForCompletion(b)); @@ -788,12 +774,12 @@ public void secretMaskingWindows() throws Exception { } @Test - public void dynamicPVCWorkspaceVolume() throws Exception { + void dynamicPVCWorkspaceVolume() throws Exception { dynamicPVC(); } @Test - public void dynamicPVCVolume() throws Exception { + void dynamicPVCVolume() throws Exception { dynamicPVC(); } @@ -834,26 +820,26 @@ private void dynamicPVC() throws Exception { return KubernetesTestUtil.getLabels(cloud, this, name); } - private void assumePvcAccess() throws KubernetesAuthException, IOException { + private void assumePvcAccess() throws Exception { try { cloud.connect().persistentVolumeClaims().list(); } catch (KubernetesClientException x) { // Error from server (Forbidden): persistentvolumeclaims is forbidden: User // "system:serviceaccount:kubernetes-plugin-test:default" cannot list resource "persistentvolumeclaims" in // API group "" in the namespace "kubernetes-plugin-test" - assumeNoException("was not permitted to list pvcs, so presumably cannot run test either", x); + assumeTrue(false, "was not permitted to list pvcs, so presumably cannot run test either: " + x); } } @Test - public void invalidPodGetsCancelled() throws Exception { + void invalidPodGetsCancelled() throws Exception { r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b)); r.assertLogContains("ERROR: Unable to create pod", b); r.assertLogContains("Queue task was cancelled", b); } @Test - public void invalidImageGetsCancelled() throws Exception { + void invalidImageGetsCancelled() throws Exception { Reaper.TerminateAgentOnImagePullBackOff.BACKOFF_EVENTS_LIMIT = 2; r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b)); r.assertLogContains("Image pull backoff detected, waiting for image to be available.", b); @@ -862,10 +848,10 @@ public void invalidImageGetsCancelled() throws Exception { @Issue("SECURITY-1646") @Test - public void substituteEnv() throws Exception { + void substituteEnv() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); String home = System.getenv("HOME"); - assumeNotNull(home); + assumeTrue(home != null); r.assertLogContains("hack: \"xxx${HOME}xxx\"", b); r.assertLogNotContains("xxx" + home + "xxx", b); PodTemplateUtils.SUBSTITUTE_ENV = true; @@ -874,7 +860,7 @@ public void substituteEnv() throws Exception { } @Test - public void octalPermissions() throws Exception { + void octalPermissions() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(b)); } @@ -890,7 +876,7 @@ private R assertBuildStatus(R run, Result... status) throws Exce } @Test - public void cancelOnlyRelevantQueueItem() throws Exception { + void cancelOnlyRelevantQueueItem() throws Exception { r.waitForMessage("cancelled pod item by now", b); r.createOnlineSlave(Label.get("special-agent")); r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b)); @@ -898,7 +884,7 @@ public void cancelOnlyRelevantQueueItem() throws Exception { } @Test - public void garbageCollection() throws Exception { + void garbageCollection() throws Exception { // Pod exists, need to kill the build, delete the agent without deleting the pod. // Wait for the timeout to expire and check that the pod is deleted. var garbageCollection = new GarbageCollection(); @@ -912,7 +898,7 @@ public void garbageCollection() throws Exception { if (c instanceof KubernetesComputer) { var node = (KubernetesSlave) c.getNode(); pod = node.getPod().get(); - Assert.assertNotNull(pod); + assertNotNull(pod); b.doKill(); r.jenkins.removeNode(node); break; @@ -927,7 +913,7 @@ public void garbageCollection() throws Exception { } @Test - public void handleEviction() throws Exception { + void handleEviction() throws Exception { SemaphoreStep.waitForStart("pod/1", b); var client = cloud.connect(); var pod = client.pods() @@ -944,7 +930,7 @@ public void handleEviction() throws Exception { } @Test - public void decoratorFailure() throws Exception { + void decoratorFailure() throws Exception { r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b)); r.assertLogContains("I always fail", b); assertThat("Node should have been removed", r.jenkins.getNodes(), empty()); @@ -960,12 +946,12 @@ public Pod decorate(@NonNull KubernetesCloud kubernetesCloud, @NonNull Pod pod) } @Test - public void imageWithoutAgent() throws Exception { + void imageWithoutAgent() throws Exception { r.assertBuildStatus(Result.SUCCESS, r.waitForCompletion(b)); } @Test - public void imageWithoutAgentNoJava() throws Exception { + void imageWithoutAgentNoJava() throws Exception { r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b)); r.assertLogContains("java: not found", b); } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineWebsocketRJRTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineWebsocketRJRTest.java index 6536ee8e6a..3ae9ecd7e3 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineWebsocketRJRTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineWebsocketRJRTest.java @@ -1,19 +1,18 @@ package org.csanchez.jenkins.plugins.kubernetes.pipeline; -import java.net.UnknownHostException; import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.AssertBuildStatusSuccess; import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.RunId; import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.SetupCloud; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class KubernetesPipelineWebsocketRJRTest extends AbstractKubernetesPipelineRJRTest { +class KubernetesPipelineWebsocketRJRTest extends AbstractKubernetesPipelineRJRTest { - public KubernetesPipelineWebsocketRJRTest() throws UnknownHostException { + public KubernetesPipelineWebsocketRJRTest() throws Exception { super(new SetupCloud(true)); } @Test - public void basicPipeline() throws Throwable { + void basicPipeline() throws Throwable { RunId runId = createWorkflowJobThenScheduleRun(); rjr.runRemotely(new AssertBuildStatusSuccess(runId)); } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesSamplesTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesSamplesTest.java index c0916c85d2..a6ea80ed20 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesSamplesTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesSamplesTest.java @@ -19,31 +19,26 @@ import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.*; import hudson.ExtensionList; +import java.util.concurrent.TimeUnit; import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.cps.GroovySample; import org.jenkinsci.plugins.workflow.job.WorkflowJob; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ErrorCollector; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; -public class KubernetesSamplesTest extends AbstractKubernetesPipelineTest { +@Timeout(value = 2, unit = TimeUnit.MINUTES) +class KubernetesSamplesTest extends AbstractKubernetesPipelineTest { - // TODO tried without success to use Parameterized here (need to construct parameters _after_ JenkinsRule starts) - @Rule - public ErrorCollector errors = new ErrorCollector(); - - { - r.timeout *= 2; // again, without Parameterized we are running a bunch of builds in one test case - } - - @Before - public void setUp() throws Exception { + @BeforeEach + void beforeEach() throws Exception { deletePods(cloud.connect(), getLabels(cloud, this, name), false); } @Test - public void smokes() throws Exception { + void smokes() throws Exception { + // TODO tried without success to use Parameterized here (need to construct parameters _after_ JenkinsRule + // starts) for (GroovySample gs : ExtensionList.lookup(GroovySample.class)) { if (gs.name().equals("kubernetes-windows") && !isWindows(null)) { System.err.println("==== Skipping " + gs.title() + " ===="); @@ -52,7 +47,7 @@ public void smokes() throws Exception { System.err.println("==== " + gs.title() + " ===="); p = r.createProject(WorkflowJob.class, gs.name()); p.setDefinition(new CpsFlowDefinition(gs.script(), true)); - errors.checkSucceeds(() -> r.buildAndAssertSuccess(p)); + r.buildAndAssertSuccess(p); } } } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/NoDelayProvisionerStrategyTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/NoDelayProvisionerStrategyTest.java index 298f243ea9..9d6a8c12fd 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/NoDelayProvisionerStrategyTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/NoDelayProvisionerStrategyTest.java @@ -2,7 +2,7 @@ import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.deletePods; import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.getLabels; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; @@ -19,20 +19,21 @@ import hudson.slaves.CloudProvisioningListener; import hudson.slaves.NodeProvisioner; import java.util.Collection; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.jvnet.hudson.test.TestExtension; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class NoDelayProvisionerStrategyTest extends AbstractKubernetesPipelineTest { -@RunWith(MockitoJUnitRunner.class) -public class NoDelayProvisionerStrategyTest extends AbstractKubernetesPipelineTest { @Mock - CloudProvisioningListener cloudProvisioningListener; + private CloudProvisioningListener cloudProvisioningListener; - @Before - public void setUp() throws Exception { + @BeforeEach + void beforeEach() throws Exception { CloudProvisionerListenerImpl instance = ExtensionList.lookupSingleton(CloudProvisionerListenerImpl.class); instance.setDelegate(cloudProvisioningListener); deletePods(cloud.connect(), getLabels(cloud, this, name), false); @@ -80,7 +81,7 @@ public CauseOfBlockage canProvision(Cloud cloud, Label label, int numExecutors) } @Test - public void noDelayProvisionerCallsListener() throws Exception { + void noDelayProvisionerCallsListener() throws Exception { when(cloudProvisioningListener.canProvision(any(Cloud.class), any(Label.class), anyInt())) .thenReturn(null); r.assertBuildStatusSuccess(r.waitForCompletion(b)); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodNameTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodNameTest.java index db818ce901..8ba4ce0e9a 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodNameTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodNameTest.java @@ -21,18 +21,18 @@ import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class PodNameTest extends AbstractKubernetesPipelineTest { +class PodNameTest extends AbstractKubernetesPipelineTest { - @Before - public void setUp() throws Exception { + @BeforeEach + void beforeEach() throws Exception { deletePods(cloud.connect(), getLabels(cloud, this, name), false); } @Test - public void multipleDots() throws Exception { + void multipleDots() throws Exception { WorkflowJob p = r.createProject(WorkflowJob.class, "whatever...man"); p.setDefinition(new CpsFlowDefinition("podTemplate {node(POD_LABEL) {sh 'echo ok'}}", true)); r.buildAndAssertSuccess(p); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodProvisioningStatusLogsTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodProvisioningStatusLogsTest.java index 6a4be2d3ed..efe4200ced 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodProvisioningStatusLogsTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodProvisioningStatusLogsTest.java @@ -1,14 +1,14 @@ package org.csanchez.jenkins.plugins.kubernetes.pipeline; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotNull; import hudson.model.Result; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class PodProvisioningStatusLogsTest extends AbstractKubernetesPipelineTest { +class PodProvisioningStatusLogsTest extends AbstractKubernetesPipelineTest { @Test - public void podStatusErrorLogs() throws Exception { + void podStatusErrorLogs() throws Exception { assertNotNull(createJobThenScheduleRun()); // pod not schedulable // build never finishes, so just checking the message and killing @@ -18,7 +18,7 @@ public void podStatusErrorLogs() throws Exception { } @Test - public void podStatusNoErrorLogs() throws Exception { + void podStatusNoErrorLogs() throws Exception { assertNotNull(createJobThenScheduleRun()); r.assertBuildStatusSuccess(r.waitForCompletion(b)); // regular logs when starting containers @@ -27,7 +27,7 @@ public void podStatusNoErrorLogs() throws Exception { } @Test - public void containerStatusErrorLogs() throws Exception { + void containerStatusErrorLogs() throws Exception { assertNotNull(createJobThenScheduleRun()); r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b)); // error starting container diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStepExecutionTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStepExecutionTest.java index 04187d72e8..451536835d 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStepExecutionTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStepExecutionTest.java @@ -25,7 +25,7 @@ package org.csanchez.jenkins.plugins.kubernetes.pipeline; import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.*; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.assertNotNull; import hudson.model.Result; import org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud; @@ -34,27 +34,28 @@ 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.Test; +import org.junit.jupiter.api.BeforeAll; +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; -public class PodTemplateStepExecutionTest { +@WithJenkins +class PodTemplateStepExecutionTest { - @Rule - public JenkinsRule r = new JenkinsRule(); + private JenkinsRule r; protected KubernetesCloud cloud; - @Before - public void configureCloud() throws Exception { + @BeforeEach + void beforeEach(JenkinsRule rule) { + r = rule; cloud = new KubernetesCloud("kubernetes"); r.jenkins.clouds.add(cloud); } - @BeforeClass - public static void isKubernetesConfigured() throws Exception { + @BeforeAll + static void beforeAll() { assumeKubernetes(); } @@ -63,7 +64,7 @@ private String loadPipelineScript(String name) { } @Test - public void testBadNameDetection() throws Exception { + void testBadNameDetection() throws Exception { WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "bad_container_name"); p.setDefinition(new CpsFlowDefinition(loadPipelineScript("badcontainername.groovy"), true)); WorkflowRun b = p.scheduleBuild2(0).waitForStart(); @@ -73,7 +74,7 @@ public void testBadNameDetection() throws Exception { } @Test - public void testBadNameYamlDetection() throws Exception { + void testBadNameYamlDetection() throws Exception { WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "bad_container_name_yaml"); p.setDefinition(new CpsFlowDefinition(loadPipelineScript("badcontainernameyaml.groovy"), true)); WorkflowRun b = p.scheduleBuild2(0).waitForStart(); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStepTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStepTest.java index e8c26f737c..b8e963b099 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStepTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStepTest.java @@ -5,19 +5,26 @@ import org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.DynamicPVCWorkspaceVolume; import org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.EmptyDirWorkspaceVolume; import org.jenkinsci.plugins.workflow.cps.SnippetizerTester; -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; -public class PodTemplateStepTest { - @Rule - public JenkinsRule rule = new JenkinsRule(); +@WithJenkins +class PodTemplateStepTest { + + private JenkinsRule r; + + @BeforeEach + void beforeEach(JenkinsRule rule) { + r = rule; + } @Issue("JENKINS-57828") @Test - public void configRoundTrip() throws Exception { - SnippetizerTester st = new SnippetizerTester(rule); + void configRoundTrip() throws Exception { + SnippetizerTester st = new SnippetizerTester(r); PodTemplateStep step = new PodTemplateStep(); st.assertRoundTrip(step, "podTemplate {\n // some block\n}"); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ResourcesTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ResourcesTest.java index 9be9ce3eff..d3fc5cfcd5 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ResourcesTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ResourcesTest.java @@ -8,12 +8,12 @@ import java.io.IOException; import org.jenkinsci.plugins.workflow.steps.BodyExecutionCallback; import org.jenkinsci.plugins.workflow.steps.StepContext; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class ResourcesTest { +class ResourcesTest { @Test - public void testCloseQuietly() throws Exception { + void testCloseQuietly() throws Exception { StepContext ctx = mock(StepContext.class); TaskListener listener = mock(TaskListener.class); when(ctx.get(TaskListener.class)) @@ -42,7 +42,7 @@ public void testCloseQuietly() throws Exception { } @Test - public void testCloseQuietlyCallbackOnSuccess() throws Exception { + void testCloseQuietlyCallbackOnSuccess() throws Exception { StepContext ctx = mock(StepContext.class); Closeable c1 = mock(Closeable.class); doThrow(IOException.class).when(c1).close(); @@ -58,7 +58,7 @@ public void testCloseQuietlyCallbackOnSuccess() throws Exception { } @Test - public void testCloseQuietlyCallbackOnFailure() throws Exception { + void testCloseQuietlyCallbackOnFailure() throws Exception { StepContext ctx = mock(StepContext.class); Closeable c1 = mock(Closeable.class); doThrow(IOException.class).when(c1).close(); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/RestartPipelineTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/RestartPipelineTest.java index c38f8add45..7908f24b57 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/RestartPipelineTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/RestartPipelineTest.java @@ -26,12 +26,13 @@ import static java.util.Arrays.*; import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.*; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertTrue; import hudson.model.Node; import hudson.model.Result; import hudson.slaves.DumbSlave; import hudson.slaves.JNLPLauncher; +import java.io.File; import java.io.IOException; import java.util.Collections; import java.util.Optional; @@ -39,7 +40,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import jenkins.model.Jenkins; -import org.apache.commons.io.IOUtils; import org.csanchez.jenkins.plugins.kubernetes.ContainerEnvVar; import org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate; import org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud; @@ -53,50 +53,53 @@ import org.jenkinsci.plugins.workflow.job.WorkflowRun; import org.jenkinsci.plugins.workflow.steps.durable_task.DurableTaskStep; import org.jenkinsci.plugins.workflow.support.steps.ExecutorStepDynamicContext; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.junit.rules.TestName; -import org.jvnet.hudson.test.BuildWatcher; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.JenkinsSessionRule; -import org.jvnet.hudson.test.LoggerRule; +import org.jvnet.hudson.test.LogRecorder; +import org.jvnet.hudson.test.junit.jupiter.BuildWatcherExtension; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; -public class RestartPipelineTest { - protected static final String CONTAINER_ENV_VAR_VALUE = "container-env-var-value"; - protected static final String POD_ENV_VAR_VALUE = "pod-env-var-value"; - protected static final String SECRET_KEY = "password"; - protected static final String CONTAINER_ENV_VAR_FROM_SECRET_VALUE = "container-pa55w0rd"; - protected static final String POD_ENV_VAR_FROM_SECRET_VALUE = "pod-pa55w0rd"; - protected KubernetesCloud cloud; +class RestartPipelineTest { - @Rule - public JenkinsSessionRule story = new JenkinsSessionRule(); + private static final String CONTAINER_ENV_VAR_VALUE = "container-env-var-value"; + private static final String POD_ENV_VAR_VALUE = "pod-env-var-value"; + private static final String SECRET_KEY = "password"; - @Rule - public TemporaryFolder tmp = new TemporaryFolder(); + private KubernetesCloud cloud; - @ClassRule - public static BuildWatcher buildWatcher = new BuildWatcher(); + @RegisterExtension + private final JenkinsSessionExtension story = new JenkinsSessionExtension(); - @Rule - public LoggerRule logs = new LoggerRule() + @TempDir + private File tmp; + + @SuppressWarnings("unused") + private static final BuildWatcherExtension BUILD_WATCHER = new BuildWatcherExtension(); + + private final LogRecorder logs = new LogRecorder() .record(Logger.getLogger(KubernetesCloud.class.getPackage().getName()), Level.ALL); // .record("org.jenkinsci.plugins.durabletask", // Level.ALL).record("org.jenkinsci.plugins.workflow.support.concurrent", // Level.ALL).record("org.csanchez.jenkins.plugins.kubernetes.pipeline", Level.ALL); - @Rule - public TestName name = new TestName(); + private String name; - @BeforeClass - public static void isKubernetesConfigured() throws Exception { + @BeforeAll + static void beforeAll() { assumeKubernetes(); } + @BeforeEach + void beforeEach(TestInfo info) { + name = info.getTestMethod().orElseThrow().getName(); + } + private static void setEnvVariables(PodTemplate podTemplate) { TemplateEnvVar podSecretEnvVar = new SecretEnvVar("POD_ENV_VAR_FROM_SECRET", "pod-secret", SECRET_KEY, false); TemplateEnvVar podSimpleEnvVar = new KeyValueEnvVar("POD_ENV_VAR", POD_ENV_VAR_VALUE); @@ -125,7 +128,7 @@ private PodTemplate buildBusyboxTemplate(String label) { return podTemplate; } - public void configureCloud() throws Exception { + private void configureCloud() throws Exception { cloud = setupCloud(this, name); createSecret(cloud.connect(), cloud.getNamespace()); cloud.getTemplates().clear(); @@ -136,22 +139,14 @@ public void configureCloud() throws Exception { Jenkins.get().clouds.add(cloud); } - public void configureAgentListener() throws IOException { + private void configureAgentListener() throws Exception { // Take random port and fix it, to be the same after Jenkins restart int fixedPort = Jenkins.get().getTcpSlaveAgentListener().getAdvertisedPort(); Jenkins.get().setSlaveAgentPort(fixedPort); } - protected String loadPipelineScript(String name) { - try { - return new String(IOUtils.toByteArray(getClass().getResourceAsStream(name))); - } catch (Throwable t) { - throw new RuntimeException("Could not read resource:[" + name + "]."); - } - } - @Test - public void nullLabelSupportsRestart() throws Throwable { + void nullLabelSupportsRestart() throws Throwable { AtomicReference projectName = new AtomicReference<>(); story.then(r -> { configureAgentListener(); @@ -179,12 +174,12 @@ public void nullLabelSupportsRestart() throws Throwable { } @Test - public void runInPodWithRestartWithMultipleContainerCalls() throws Exception, Throwable { + void runInPodWithRestartWithMultipleContainerCalls() throws Throwable { AtomicReference projectName = new AtomicReference<>(); story.then(r -> { configureAgentListener(); configureCloud(); - r.jenkins.addNode(new DumbSlave("slave", tmp.newFolder("remoteFS").getPath(), new JNLPLauncher(false))); + r.jenkins.addNode(new DumbSlave("slave", newFolder(tmp, "remoteFS").getPath(), new JNLPLauncher(false))); WorkflowRun b = getPipelineJobThenScheduleRun(r); projectName.set(b.getParent().getFullName()); // we need to wait until we are sure that the sh @@ -200,12 +195,12 @@ public void runInPodWithRestartWithMultipleContainerCalls() throws Exception, Th } @Test - public void runInPodWithRestartWithLongSleep() throws Exception, Throwable { + void runInPodWithRestartWithLongSleep() throws Throwable { AtomicReference projectName = new AtomicReference<>(); story.then(r -> { configureAgentListener(); configureCloud(); - r.jenkins.addNode(new DumbSlave("slave", tmp.newFolder("remoteFS").getPath(), new JNLPLauncher(false))); + r.jenkins.addNode(new DumbSlave("slave", newFolder(tmp, "remoteFS").getPath(), new JNLPLauncher(false))); WorkflowRun b = getPipelineJobThenScheduleRun(r); projectName.set(b.getParent().getFullName()); // we need to wait until we are sure that the sh @@ -221,7 +216,7 @@ public void runInPodWithRestartWithLongSleep() throws Exception, Throwable { } @Test - public void windowsRestart() throws Throwable { + void windowsRestart() throws Throwable { assumeWindows(WINDOWS_1809_BUILD); AtomicReference projectName = new AtomicReference<>(); story.then(r -> { @@ -243,7 +238,7 @@ public void windowsRestart() throws Throwable { @Issue("JENKINS-49707") @Test - public void terminatedPodAfterRestart() throws Exception, Throwable { + void terminatedPodAfterRestart() throws Throwable { AtomicReference projectName = new AtomicReference<>(); story.then(r -> { configureAgentListener(); @@ -268,7 +263,7 @@ public void terminatedPodAfterRestart() throws Exception, Throwable { } @Test - public void taskListenerAfterRestart() throws Throwable { + void taskListenerAfterRestart() throws Throwable { AtomicReference projectName = new AtomicReference<>(); story.then(r -> { configureAgentListener(); @@ -284,7 +279,7 @@ public void taskListenerAfterRestart() throws Throwable { Optional first = r.jenkins.getNodes().stream() .filter(KubernetesSlave.class::isInstance) .findFirst(); - assertTrue("Kubernetes node should be present after restart", first.isPresent()); + assertTrue(first.isPresent(), "Kubernetes node should be present after restart"); KubernetesSlave node = (KubernetesSlave) first.get(); r.waitForMessage("Ready to run", b); waitForTemplate(node).getListener().getLogger().println("This got printed"); @@ -295,7 +290,7 @@ public void taskListenerAfterRestart() throws Throwable { } @Test - public void taskListenerAfterRestart_multipleLabels() throws Throwable { + void taskListenerAfterRestart_multipleLabels() throws Throwable { AtomicReference projectName = new AtomicReference<>(); story.then(r -> { configureAgentListener(); @@ -311,7 +306,7 @@ public void taskListenerAfterRestart_multipleLabels() throws Throwable { Optional first = r.jenkins.getNodes().stream() .filter(KubernetesSlave.class::isInstance) .findFirst(); - assertTrue("Kubernetes node should be present after restart", first.isPresent()); + assertTrue(first.isPresent(), "Kubernetes node should be present after restart"); KubernetesSlave node = (KubernetesSlave) first.get(); r.waitForMessage("Ready to run", b); waitForTemplate(node).getListener().getLogger().println("This got printed"); @@ -321,7 +316,7 @@ public void taskListenerAfterRestart_multipleLabels() throws Throwable { }); } - private PodTemplate waitForTemplate(KubernetesSlave node) throws InterruptedException { + private PodTemplate waitForTemplate(KubernetesSlave node) throws Exception { while (node.getTemplateOrNull() == null) { Thread.sleep(100L); } @@ -329,12 +324,12 @@ private PodTemplate waitForTemplate(KubernetesSlave node) throws InterruptedExce } @Test - public void getContainerLogWithRestart() throws Exception, Throwable { + void getContainerLogWithRestart() throws Throwable { AtomicReference projectName = new AtomicReference<>(); story.then(r -> { configureAgentListener(); configureCloud(); - r.jenkins.addNode(new DumbSlave("slave", tmp.newFolder("remoteFS").getPath(), new JNLPLauncher(false))); + r.jenkins.addNode(new DumbSlave("slave", newFolder(tmp, "remoteFS").getPath(), new JNLPLauncher(false))); WorkflowRun b = getPipelineJobThenScheduleRun(r); projectName.set(b.getParent().getFullName()); // we need to wait until we are sure that the sh @@ -352,6 +347,15 @@ public void getContainerLogWithRestart() throws Exception, Throwable { } private WorkflowRun getPipelineJobThenScheduleRun(JenkinsRule r) throws Exception { - return createPipelineJobThenScheduleRun(r, getClass(), name.getMethodName()); + return createPipelineJobThenScheduleRun(r, getClass(), name); + } + + private static File newFolder(File root, String... subDirs) throws Exception { + String subFolder = String.join("/", subDirs); + File result = new File(root, subFolder); + if (!result.mkdirs()) { + throw new IOException("Couldn't create folders " + root); + } + return result; } } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/WebSocketTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/WebSocketTest.java index 207d44e502..affead33de 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/WebSocketTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/WebSocketTest.java @@ -20,15 +20,15 @@ import java.util.logging.Level; import jenkins.agents.WebSocketAgents; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.Issue; @Issue("JEP-222") -public class WebSocketTest extends AbstractKubernetesPipelineTest { +class WebSocketTest extends AbstractKubernetesPipelineTest { - @Before - public void setUp() throws Exception { + @BeforeEach + void beforeEach() throws Exception { deletePods(cloud.connect(), getLabels(cloud, this, name), false); r.jenkins.setSlaveAgentPort(-1); cloud.setWebSocket(true); @@ -36,7 +36,7 @@ public void setUp() throws Exception { } @Test - public void webSocketAgent() throws Exception { + void webSocketAgent() throws Exception { r.assertBuildStatusSuccess(r.waitForCompletion(createJobThenScheduleRun())); } } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/AssertBuildLogMessage.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/AssertBuildLogMessage.java index 9adf22084c..577d06d0d0 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/AssertBuildLogMessage.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/AssertBuildLogMessage.java @@ -3,9 +3,9 @@ import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.RealJenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension; -public class AssertBuildLogMessage implements RealJenkinsRule.Step { +public class AssertBuildLogMessage implements RealJenkinsExtension.Step { private final String message; private final RunId runId; diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/AssertBuildStatusSuccess.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/AssertBuildStatusSuccess.java index 496751a9a2..fbd70b0068 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/AssertBuildStatusSuccess.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/AssertBuildStatusSuccess.java @@ -3,9 +3,9 @@ import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.RealJenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension; -public class AssertBuildStatusSuccess implements RealJenkinsRule.Step { +public class AssertBuildStatusSuccess implements RealJenkinsExtension.Step { private RunId runId; public AssertBuildStatusSuccess(RunId runId) { diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/CreateWorkflowJobThenScheduleRun.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/CreateWorkflowJobThenScheduleRun.java index b17f437f62..0210cfc0ca 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/CreateWorkflowJobThenScheduleRun.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/CreateWorkflowJobThenScheduleRun.java @@ -4,12 +4,12 @@ import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.RealJenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension; /** * Creates a workflow job using the specified script, then schedules it and returns a reference to the run. */ -public class CreateWorkflowJobThenScheduleRun implements RealJenkinsRule.Step2 { +public class CreateWorkflowJobThenScheduleRun implements RealJenkinsExtension.Step2 { private String script; public CreateWorkflowJobThenScheduleRun(String script) { diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/CreateWorkflowJobThenScheduleTask.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/CreateWorkflowJobThenScheduleTask.java index 882fad33ef..69000abd20 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/CreateWorkflowJobThenScheduleTask.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/CreateWorkflowJobThenScheduleTask.java @@ -4,12 +4,12 @@ import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.RealJenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension; /** * Creates a workflow job using the specified script, then schedules it and returns a reference to the run. */ -public class CreateWorkflowJobThenScheduleTask implements RealJenkinsRule.Step2 { +public class CreateWorkflowJobThenScheduleTask implements RealJenkinsExtension.Step2 { private String script; public CreateWorkflowJobThenScheduleTask(String script) { diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/SetupCloud.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/SetupCloud.java index 63da6fda7c..43adb8ceda 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/SetupCloud.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/SetupCloud.java @@ -2,23 +2,22 @@ import java.net.InetAddress; import java.net.URL; -import java.net.UnknownHostException; import jenkins.model.JenkinsLocationConfiguration; import org.apache.commons.lang3.StringUtils; import org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.RealJenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension; /** * Sets up a Kubernetes cloud instance named kubernetes. */ -public class SetupCloud implements RealJenkinsRule.Step { +public class SetupCloud implements RealJenkinsExtension.Step { private String hostAddress; private Integer agentPort; private boolean websocket; - public SetupCloud(boolean websocket) throws UnknownHostException { + public SetupCloud(boolean websocket) throws Exception { hostAddress = StringUtils.defaultIfBlank( System.getProperty("jenkins.host.address"), InetAddress.getLocalHost().getHostAddress()); @@ -26,7 +25,7 @@ public SetupCloud(boolean websocket) throws UnknownHostException { this.websocket = websocket; } - public SetupCloud() throws UnknownHostException { + public SetupCloud() throws Exception { this(false); } diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/decorator/PodDecoratorTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/decorator/PodDecoratorTest.java index faea739150..0791ec87a2 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/decorator/PodDecoratorTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/decorator/PodDecoratorTest.java @@ -1,6 +1,6 @@ package org.csanchez.jenkins.plugins.kubernetes.pod.decorator; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.when; import edu.umd.cs.findbugs.annotations.NonNull; @@ -10,29 +10,29 @@ import org.csanchez.jenkins.plugins.kubernetes.KubernetesSlave; import org.csanchez.jenkins.plugins.kubernetes.PodTemplate; import org.csanchez.jenkins.plugins.kubernetes.PodTemplateBuilder; -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.junit.jupiter.api.extension.ExtendWith; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; +import org.mockito.junit.jupiter.MockitoExtension; -public class PodDecoratorTest { - @Rule - public JenkinsRule j = new JenkinsRule(); +@WithJenkins +@ExtendWith(MockitoExtension.class) +class PodDecoratorTest { - @Rule - public MockitoRule mockitoRule = MockitoJUnit.rule(); + private JenkinsRule j; @Mock private KubernetesSlave slave; private KubernetesCloud cloud = new KubernetesCloud("test"); - @Before - public void setUp() { + @BeforeEach + void beforeEach(JenkinsRule rule) { + j = rule; when(slave.getKubernetesCloud()).thenReturn(cloud); } @@ -52,7 +52,7 @@ public Pod decorate(@NonNull KubernetesCloud kubernetesCloud, @NonNull Pod pod) } @Test - public void activeDecorator() { + void activeDecorator() { PodTemplate podTemplate = new PodTemplate(); PodTemplateBuilder podTemplateBuilder = new PodTemplateBuilder(podTemplate, slave); Pod pod = podTemplateBuilder.build(); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/PodRetentionTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/PodRetentionTest.java index 3e032f5e38..4ceafa6be9 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/PodRetentionTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/PodRetentionTest.java @@ -1,41 +1,42 @@ package org.csanchez.jenkins.plugins.kubernetes.pod.retention; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import io.fabric8.kubernetes.api.model.Pod; import io.fabric8.kubernetes.api.model.PodStatus; import io.fabric8.kubernetes.api.model.PodStatusBuilder; import java.util.function.Supplier; import org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class PodRetentionTest { +class PodRetentionTest { private KubernetesCloud cloud; private Pod pod; private Supplier podS = () -> pod; - @Before - public void setUp() { + @BeforeEach + void beforeEach() { this.cloud = new KubernetesCloud("kubernetes"); this.pod = new Pod(); } @Test - public void testAlwaysPodRetention() { + void testAlwaysPodRetention() { PodRetention subject = new Always(); assertFalse(subject.shouldDeletePod(cloud, podS)); } @Test - public void testNeverPodRetention() { + void testNeverPodRetention() { PodRetention subject = new Never(); assertTrue(subject.shouldDeletePod(cloud, podS)); } @Test - public void testDefaultPodRetention() { + void testDefaultPodRetention() { PodRetention subject = new Default(); cloud.setPodRetention(new Always()); assertFalse(subject.shouldDeletePod(cloud, podS)); @@ -48,7 +49,7 @@ public void testDefaultPodRetention() { } @Test - public void testOnFailurePodRetention() { + void testOnFailurePodRetention() { PodRetention subject = new OnFailure(); pod.setStatus(buildStatus("Failed")); assertFalse(subject.shouldDeletePod(cloud, podS)); @@ -61,7 +62,7 @@ public void testOnFailurePodRetention() { } @Test - public void testOnEvictedPodRetention() { + void testOnEvictedPodRetention() { PodRetention subject = new Evicted(); pod.setStatus(buildStatus("Failed", "Evicted")); assertFalse(subject.shouldDeletePod(cloud, podS)); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/ReaperTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/ReaperTest.java index 5aaebdb99f..76bd480f3d 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/ReaperTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/ReaperTest.java @@ -26,70 +26,66 @@ import static org.awaitility.Awaitility.await; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; import edu.umd.cs.findbugs.annotations.NonNull; -import hudson.Extension; +import hudson.ExtensionList; import hudson.model.TaskListener; import hudson.slaves.ComputerLauncher; import hudson.util.StreamTaskListener; import io.fabric8.kubernetes.api.model.*; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.Watcher; +import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; import io.fabric8.kubernetes.client.utils.Utils; import io.fabric8.mockwebserver.http.RecordedRequest; -import java.io.IOException; import java.net.HttpURLConnection; -import java.net.InetAddress; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; import java.util.stream.Collectors; -import jenkins.model.Jenkins; import org.csanchez.jenkins.plugins.kubernetes.*; import org.csanchez.jenkins.plugins.kubernetes.PodTemplate; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExternalResource; +import org.hamcrest.Description; +import org.hamcrest.TypeSafeMatcher; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.TestExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; -public class ReaperTest { +@WithJenkins +@EnableKubernetesMockClient +class ReaperTest { private static final Long EVENT_WAIT_PERIOD_MS = 10L; - @Rule - public JenkinsRule j = new JenkinsRule(); - - @Rule - public CapturingReaperListener listener = new CapturingReaperListener(); + private JenkinsRule j; private KubernetesMockServer server; private KubernetesClient client; - @Before - public void setUp() { - // TODO: remove when moving to junit 5 - server = new KubernetesMockServer(); - server.init(InetAddress.getLoopbackAddress(), 0); - client = server.createClient(); + @BeforeEach + void beforeEach(JenkinsRule rule) { + j = rule; } - @After - public void tearDown() { + @AfterEach + void afterEach() { KubernetesClientProvider.invalidateAll(); - server.destroy(); - client.close(); } @Test - public void testMaybeActivate() throws IOException, InterruptedException { + void testMaybeActivate() throws Exception { KubernetesCloud cloud = addCloud("k8s", "foo"); String watchPodsPath = "/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true"; server.expect() @@ -101,14 +97,14 @@ public void testMaybeActivate() throws IOException, InterruptedException { // add node that does not exist in k8s so it get's removed KubernetesSlave podNotRunning = addNode(cloud, "k8s-node-123", "k8s-node"); - assertEquals("node added to jenkins", j.jenkins.getNodes().size(), 1); + assertEquals(1, j.jenkins.getNodes().size(), "node added to jenkins"); // activate reaper Reaper r = Reaper.getInstance(); r.maybeActivate(); // k8s node which no pod should be deleted on activation - assertEquals("node removed from jenkins", j.jenkins.getNodes().size(), 0); + assertEquals(0, j.jenkins.getNodes().size(), "node removed from jenkins"); // watch was created assertShouldBeWatching(r, cloud); @@ -122,18 +118,18 @@ public void testMaybeActivate() throws IOException, InterruptedException { // create new node to verify activate is not run again KubernetesSlave newNode = addNode(cloud, "new-123", "new"); j.jenkins.addNode(newNode); - assertEquals("node added to jenkins", j.jenkins.getNodes().size(), 1); + assertEquals(1, j.jenkins.getNodes().size(), "node added to jenkins"); // call again should not add any more calls r.maybeActivate(); kubeClientRequests() // expect not to be called .assertRequestCount("/api/v1/namespaces/foo/pods/new-123", 0); - assertEquals("node not removed from jenkins", j.jenkins.getNodes().size(), 1); + assertEquals(1, j.jenkins.getNodes().size(), "node not removed from jenkins"); } @Test - public void testWatchFailOnActivate() throws IOException, InterruptedException { + void testWatchFailOnActivate() throws Exception { KubernetesCloud cloud = addCloud("k8s", "foo"); // activate reaper Reaper r = Reaper.getInstance(); @@ -147,7 +143,7 @@ public void testWatchFailOnActivate() throws IOException, InterruptedException { } @Test - public void testActivateOnNewComputer() throws IOException, InterruptedException { + void testActivateOnNewComputer() throws Exception { server.expect() .withPath("/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true") .andUpgradeToWebSocket() @@ -176,8 +172,9 @@ public void testActivateOnNewComputer() throws IOException, InterruptedException .assertRequestCountAtLeast("/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true", 1); } - @Test(timeout = 10_000) - public void testReconnectOnNewComputer() throws InterruptedException, IOException { + @Test + @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS) + void testReconnectOnNewComputer() throws Exception { KubernetesCloud cloud = addCloud("k8s", "foo"); String watchPodsPath = "/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true"; server.expect() @@ -210,7 +207,7 @@ public void testReconnectOnNewComputer() throws InterruptedException, IOExceptio waitForKubeClientRequests(2).assertRequestCount(watchPodsPath, 2); // error status event should be filtered out - listener.expectNoEvents(); + getReaperListener().expectNoEvents(); // wait until watch is removed System.out.println("Waiting for watch to be removed"); @@ -229,8 +226,13 @@ public void testReconnectOnNewComputer() throws InterruptedException, IOExceptio System.out.println("Watch started"); } - @Test(timeout = 10_000) - public void testAddWatchWhenCloudAdded() throws InterruptedException, IOException { + private CapturingReaperListener getReaperListener() { + return ExtensionList.lookupSingleton(CapturingReaperListener.class); + } + + @Test + @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS) + void testAddWatchWhenCloudAdded() throws Exception { String watchPodsPath = "/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true"; server.expect() .withPath(watchPodsPath) @@ -244,7 +246,7 @@ public void testAddWatchWhenCloudAdded() throws InterruptedException, IOExceptio r.maybeActivate(); String cloudName = "k8s"; - assertFalse("should not be watching cloud", r.isWatchingCloud(cloudName)); + assertFalse(r.isWatchingCloud(cloudName), "should not be watching cloud"); KubernetesCloud cloud = addCloud(cloudName, "foo"); @@ -256,8 +258,9 @@ public void testAddWatchWhenCloudAdded() throws InterruptedException, IOExceptio kubeClientRequests().assertRequestCountAtLeast(watchPodsPath, 1); } - @Test(timeout = 10_000) - public void testRemoveWatchWhenCloudRemoved() throws InterruptedException, IOException { + @Test + @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS) + void testRemoveWatchWhenCloudRemoved() { KubernetesCloud cloud = addCloud("k8s", "foo"); String watchPodsPath = "/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true"; server.expect() @@ -283,8 +286,9 @@ public void testRemoveWatchWhenCloudRemoved() throws InterruptedException, IOExc assertShouldNotBeWatching(r, cloud); } - @Test(timeout = 10_000) - public void testReplaceWatchWhenCloudUpdated() throws InterruptedException, IOException { + @Test + @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS) + void testReplaceWatchWhenCloudUpdated() throws Exception { KubernetesCloud cloud = addCloud("k8s", "foo"); Pod node123 = new PodBuilder() .withNewStatus() @@ -334,12 +338,13 @@ public void testReplaceWatchWhenCloudUpdated() throws InterruptedException, IOEx // watch is still active assertShouldBeWatching(r, cloud); - listener.waitForEvents().expectEvent(Watcher.Action.MODIFIED, node); + getReaperListener().expectEvent(Watcher.Action.MODIFIED, node); kubeClientRequests().assertRequestCountAtLeast(watchBarPodsPath, 1); } - @Test(timeout = 10_000) - public void testStopWatchingOnCloseException() throws InterruptedException { + @Test + @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS) + void testStopWatchingOnCloseException() throws Exception { KubernetesCloud cloud = addCloud("k8s", "foo"); String watchPodsPath = "/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true"; server.expect() @@ -365,14 +370,15 @@ public void testStopWatchingOnCloseException() throws InterruptedException { waitForKubeClientRequests(2).assertRequestCount(watchPodsPath, 2); // error status event should be filtered out - listener.expectNoEvents(); + getReaperListener().expectNoEvents(); // watch is removed assertShouldNotBeWatching(r, cloud); } - @Test(timeout = 10_000) - public void testKeepWatchingOnKubernetesApiServerError() throws InterruptedException { + @Test + @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS) + void testKeepWatchingOnKubernetesApiServerError() throws Exception { KubernetesCloud cloud = addCloud("k8s", "foo"); String watchPodsPath = "/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true"; server.expect() @@ -406,14 +412,15 @@ public void testKeepWatchingOnKubernetesApiServerError() throws InterruptedExcep waitForKubeClientRequests(3).assertRequestCount(watchPodsPath, 3); // error status event should be filtered out - listener.expectNoEvents(); + getReaperListener().expectNoEvents(); // watch is still active assertShouldBeWatching(r, cloud); } - @Test(timeout = 10_000) - public void testKeepWatchingOnStatusWatchEvent() throws InterruptedException { + @Test + @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS) + void testKeepWatchingOnStatusWatchEvent() throws Exception { KubernetesCloud cloud = addCloud("k8s", "foo"); String watchPodsPath = "/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true"; server.expect().withPath(watchPodsPath).andReturnChunked(200).once(); @@ -437,14 +444,14 @@ public void testKeepWatchingOnStatusWatchEvent() throws InterruptedException { waitForKubeClientRequests(2).assertRequestCount(watchPodsPath, 2); // error status event should be filtered out - listener.expectNoEvents(); + getReaperListener().expectNoEvents(); // watch is still active assertShouldBeWatching(r, cloud); } @Test - public void testCloseWatchersOnShutdown() throws InterruptedException { + void testCloseWatchersOnShutdown() { String watchPodsPath = "/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true"; server.expect() @@ -473,8 +480,9 @@ public void testCloseWatchersOnShutdown() throws InterruptedException { assertShouldNotBeWatching(r, cloud, cloud2, cloud3); } - @Test(timeout = 10_000) - public void testDeleteNodeOnPodDelete() throws IOException, InterruptedException { + @Test + @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS) + void testDeleteNodeOnPodDelete() throws Exception { KubernetesCloud cloud = addCloud("k8s", "foo"); KubernetesSlave node = addNode(cloud, "node-123", "node"); Pod node123 = createPod(node); @@ -500,24 +508,25 @@ public void testDeleteNodeOnPodDelete() throws IOException, InterruptedException r.maybeActivate(); // verify node is still registered - assertEquals("jenkins nodes", j.jenkins.getNodes().size(), 1); + assertEquals(1, j.jenkins.getNodes().size(), "jenkins nodes"); // wait for the delete event to be processed waitForKubeClientRequests(6) .assertRequestCountAtLeast("/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true", 3); // verify listener got notified - listener.expectEvent(Watcher.Action.DELETED, node); + getReaperListener().expectEvent(Watcher.Action.DELETED, node); // verify computer disconnected with offline cause verify(node.getComputer()).disconnect(isA(PodOfflineCause.class)); // expect node to be removed - assertEquals("jenkins nodes", j.jenkins.getNodes().size(), 0); + assertEquals(0, j.jenkins.getNodes().size(), "jenkins nodes"); } - @Test(timeout = 10_000) - public void testTerminateAgentOnContainerTerminated() throws IOException, InterruptedException { + @Test + @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS) + void testTerminateAgentOnContainerTerminated() throws Exception { KubernetesCloud cloud = addCloud("k8s", "foo"); KubernetesSlave node = addNode(cloud, "node-123", "node"); Pod node123 = withContainerStatusTerminated(createPod(node)); @@ -559,21 +568,22 @@ public void testTerminateAgentOnContainerTerminated() throws IOException, Interr r.maybeActivate(); // verify node is still registered - assertEquals("jenkins nodes", j.jenkins.getNodes().size(), 1); + assertEquals(1, j.jenkins.getNodes().size(), "jenkins nodes"); // verify listener got notified - listener.waitForEvents().expectEvent(Watcher.Action.MODIFIED, node); + getReaperListener().expectEvent(Watcher.Action.MODIFIED, node); // expect node to be terminated verify(node, atLeastOnce()).terminate(); // verify computer disconnected with offline cause verify(node.getComputer(), atLeastOnce()).disconnect(isA(PodOfflineCause.class)); // verify node is still registered (will be removed when pod deleted) - assertEquals("jenkins nodes", j.jenkins.getNodes().size(), 1); + assertEquals(1, j.jenkins.getNodes().size(), "jenkins nodes"); } - @Test(timeout = 10_000) - public void testTerminateAgentOnPodFailed() throws IOException, InterruptedException { + @Test + @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS) + void testTerminateAgentOnPodFailed() throws Exception { System.out.println(server.getPort()); KubernetesCloud cloud = addCloud("k8s", "foo"); KubernetesSlave node = addNode(cloud, "node-123", "node"); @@ -601,21 +611,22 @@ public void testTerminateAgentOnPodFailed() throws IOException, InterruptedExcep r.maybeActivate(); // verify node is still registered - assertEquals("jenkins nodes", j.jenkins.getNodes().size(), 1); + assertEquals(1, j.jenkins.getNodes().size(), "jenkins nodes"); // verify listener got notified - listener.waitForEvents().expectEvent(Watcher.Action.MODIFIED, node); + getReaperListener().expectEvent(Watcher.Action.MODIFIED, node); // expect node to be terminated verify(node, atLeastOnce()).terminate(); // verify computer disconnected with offline cause verify(node.getComputer()).disconnect(isA(PodOfflineCause.class)); // verify node is still registered (will be removed when pod deleted) - assertEquals("jenkins nodes", j.jenkins.getNodes().size(), 1); + assertEquals(1, j.jenkins.getNodes().size(), "jenkins nodes"); } - @Test(timeout = 10_000) - public void testTerminateAgentOnImagePullBackoff() throws IOException, InterruptedException { + @Test + @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS) + void testTerminateAgentOnImagePullBackoff() throws Exception { KubernetesCloud cloud = addCloud("k8s", "foo"); KubernetesSlave node = addNode(cloud, "node-123", "node"); Pod node123 = withContainerImagePullBackoff(createPod(node)); @@ -647,20 +658,20 @@ public void testTerminateAgentOnImagePullBackoff() throws IOException, Interrupt r.maybeActivate(); // verify node is still registered - assertEquals("jenkins nodes", j.jenkins.getNodes().size(), 1); + assertEquals(1, j.jenkins.getNodes().size(), "jenkins nodes"); // wait for the delete event to be processed waitForKubeClientRequests(6).assertRequestCountAtLeast(watchPodsPath, 3); // verify listener got notified - listener.expectEvent(Watcher.Action.MODIFIED, node); + getReaperListener().expectEvent(Watcher.Action.MODIFIED, node); // expect node to be terminated verify(node, atLeastOnce()).terminate(); // verify computer disconnected with offline cause verify(node.getComputer(), atLeastOnce()).disconnect(isA(PodOfflineCause.class)); // verify node is still registered (will be removed when pod deleted) - assertEquals("jenkins nodes", j.jenkins.getNodes().size(), 1); + assertEquals(1, j.jenkins.getNodes().size(), "jenkins nodes"); } private Pod withContainerImagePullBackoff(Pod pod) { @@ -708,7 +719,7 @@ private Pod createPod(KubernetesSlave node) { .build(); } - private KubernetesSlave addNode(KubernetesCloud cld, String podName, String nodeName) throws IOException { + private KubernetesSlave addNode(KubernetesCloud cld, String podName, String nodeName) throws Exception { KubernetesSlave node = mock(KubernetesSlave.class); when(node.getNodeName()).thenReturn(nodeName); when(node.getNamespace()).thenReturn(cld.getNamespace()); @@ -742,7 +753,7 @@ private KubernetesCloud addCloud(String name, String namespace) { * @return captured kube client requests so far * @throws InterruptedException interrupted exception */ - private CapturedRequests kubeClientRequests() throws InterruptedException { + private CapturedRequests kubeClientRequests() throws Exception { int count = server.getRequestCount(); List requests = new LinkedList<>(); while (count-- > 0) { @@ -760,7 +771,7 @@ private CapturedRequests kubeClientRequests() throws InterruptedException { * @return captured requests * @throws InterruptedException interrupted exception */ - private CapturedRequests waitForKubeClientRequests(int count) throws InterruptedException { + private CapturedRequests waitForKubeClientRequests(int count) throws Exception { List requests = new LinkedList<>(); while (count-- > 0) { requests.add(server.takeRequest()); @@ -768,23 +779,6 @@ private CapturedRequests waitForKubeClientRequests(int count) throws Interrupted return new CapturedRequests(requests); } - /** - * Wait until the specified request is captured. - * @param path number of requests to wait for - * @return captured requests - * @throws InterruptedException interrupted exception - */ - private CapturedRequests waitForKubeClientRequests(String path) throws InterruptedException { - List requests = new LinkedList<>(); - while (true) { - RecordedRequest rr = server.takeRequest(); - requests.add(rr); - if (rr.getPath().equals(path)) { - return new CapturedRequests(requests); - } - } - } - private static class CapturedRequests { private final Map countByPath; @@ -795,7 +789,7 @@ private static class CapturedRequests { } CapturedRequests assertRequestCount(String path, long count) { - assertEquals(path + " count", count, (long) countByPath.getOrDefault(path, 0L)); + assertEquals(count, (long) countByPath.getOrDefault(path, 0L), path + " count"); return this; } @@ -805,88 +799,67 @@ CapturedRequests assertRequestCountAtLeast(String path, long count) { } } - @Extension - public static class CapturingReaperListener extends ExternalResource implements Reaper.Listener { + @TestExtension + public static class CapturingReaperListener implements Reaper.Listener { - private static final List CAPTURED_EVENTS = new LinkedList<>(); + private final List capturedEvents = new CopyOnWriteArrayList<>(); + + private static final Logger LOGGER = Logger.getLogger(CapturingReaperListener.class.getName()); @Override public synchronized void onEvent( @NonNull Watcher.Action action, @NonNull KubernetesSlave node, @NonNull Pod pod, - @NonNull Set terminationReaons) - throws IOException, InterruptedException { - CAPTURED_EVENTS.add(new ReaperListenerWatchEvent(action, node, pod)); - notifyAll(); + @NonNull Set terminationReasons) { + LOGGER.info(this + " capturing event: " + action + " for node: " + node + " pod: " + pod); + capturedEvents.add(new ReaperListenerWatchEvent(action, node, pod)); } - /** - * Test should use {@link #waitForEvents()}, not this method - */ - private synchronized CapturingReaperListener waitForEventsOnJenkinsExtensionInstance() - throws InterruptedException { - while (CAPTURED_EVENTS.isEmpty()) { - wait(); + private static class ReaperListenerWatchEventMatcher extends TypeSafeMatcher { + private final Watcher.Action action; + private final KubernetesSlave node; + + public ReaperListenerWatchEventMatcher(Watcher.Action action, KubernetesSlave node) { + this.action = action; + this.node = node; } - return this; - } - /** - * Tests should use this method to wait for events to be processed by the Reaper cloud watcher. - * @return jenkins extension instance - * @throws InterruptedException if wait was interrupted - */ - public CapturingReaperListener waitForEvents() throws InterruptedException { - // find the instance that Jenkins created and wait on that one - CapturingReaperListener l = - Jenkins.get().getExtensionList(Reaper.Listener.class).get(CapturingReaperListener.class); - if (l == null) { - throw new RuntimeException("CapturingReaperListener not registered in Jenkins"); + @Override + protected boolean matchesSafely(ReaperListenerWatchEvent event) { + return event.action == action && event.node == node; } - return l.waitForEventsOnJenkinsExtensionInstance(); + @Override + public void describeTo(Description description) { + description + .appendText("event with action ") + .appendValue(action) + .appendText(" and node ") + .appendValue(node); + } + + @Override + protected void describeMismatchSafely(ReaperListenerWatchEvent item, Description mismatchDescription) { + mismatchDescription.appendText("was ").appendValue(item); + } } - /** - * Verify that the watcher received an event of the given action and target node. - * @param action action to match - * @param node target node - */ - public synchronized void expectEvent(Watcher.Action action, KubernetesSlave node) { - boolean found = CAPTURED_EVENTS.stream().anyMatch(e -> e.action == action && e.node == node); - assertTrue("expected event: " + action + ", " + node, found); + public void expectEvent(Watcher.Action action, KubernetesSlave node) { + await().until( + () -> capturedEvents, + hasItem(new CapturingReaperListener.ReaperListenerWatchEventMatcher(action, node))); } /** * Expect not event to have been received. */ - public synchronized void expectNoEvents() { - assertEquals("no watcher events", 0, CAPTURED_EVENTS.size()); - } - - @Override - protected void after() { - CAPTURED_EVENTS.clear(); + public void expectNoEvents() { + assertThat("no watcher events", capturedEvents, empty()); } } - private static class ReaperListenerWatchEvent { - final Watcher.Action action; - final KubernetesSlave node; - final Pod pod; - - private ReaperListenerWatchEvent(Watcher.Action action, KubernetesSlave node, Pod pod) { - this.action = action; - this.node = node; - this.pod = pod; - } - - @Override - public String toString() { - return "[" + action + ", " + node + ", " + pod + "]"; - } - } + private record ReaperListenerWatchEvent(Watcher.Action action, KubernetesSlave node, Pod pod) {} private static WatchEvent outdatedEvent() { return new WatchEventBuilder() diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/volumes/GenericEphemeralVolumeTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/volumes/GenericEphemeralVolumeTest.java index 2d62083a96..18b771e623 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/volumes/GenericEphemeralVolumeTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/volumes/GenericEphemeralVolumeTest.java @@ -1,14 +1,14 @@ package org.csanchez.jenkins.plugins.kubernetes.volumes; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import io.fabric8.kubernetes.api.model.Volume; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class GenericEphemeralVolumeTest { +class GenericEphemeralVolumeTest { @Test - public void testCreatesVolumeCorrectly() { + void testCreatesVolumeCorrectly() { GenericEphemeralVolume genericEphemeralVolume = new GenericEphemeralVolume(); genericEphemeralVolume.setAccessModes("ReadWriteOnce"); diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/volumes/workspace/GenericEphemeralWorkspaceVolumeTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/volumes/workspace/GenericEphemeralWorkspaceVolumeTest.java index 3652732275..9d30e75a5e 100644 --- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/volumes/workspace/GenericEphemeralWorkspaceVolumeTest.java +++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/volumes/workspace/GenericEphemeralWorkspaceVolumeTest.java @@ -1,14 +1,14 @@ package org.csanchez.jenkins.plugins.kubernetes.volumes.workspace; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import io.fabric8.kubernetes.api.model.Volume; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class GenericEphemeralWorkspaceVolumeTest { +class GenericEphemeralWorkspaceVolumeTest { @Test - public void testCreatesVolumeCorrectly() { + void testCreatesVolumeCorrectly() { GenericEphemeralWorkspaceVolume genericEphemeralWorkspaceVolume = new GenericEphemeralWorkspaceVolume(); genericEphemeralWorkspaceVolume.setStorageClassName("test-storageclass");