diff --git a/test/pom.xml b/test/pom.xml index a0ecb62a445692bbc8e8fd3d5932ef7685a868df..931dbb0562236aef65304b315a10115e341fb09b 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -224,6 +224,31 @@ THE SOFTWARE. true + + maven-dependency-plugin + + + old-remoting-for-test + generate-test-resources + + + copy + + + + + org.jenkins-ci.main + remoting + ${remoting.minimal.supported.version} + jar + ${project.build.outputDirectory}/old-remoting + remoting-minimal-supported.jar + + + + + + org.apache.maven.plugins maven-surefire-plugin diff --git a/test/src/test/java/jenkins/slaves/OldRemotingAgentTest.java b/test/src/test/java/jenkins/slaves/OldRemotingAgentTest.java new file mode 100644 index 0000000000000000000000000000000000000000..adb17cf9ce02eb1012d560ad1cb9dbd465522460 --- /dev/null +++ b/test/src/test/java/jenkins/slaves/OldRemotingAgentTest.java @@ -0,0 +1,140 @@ +/* + * The MIT License + * + * Copyright (c) 2018, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.slaves; + +import hudson.EnvVars; +import hudson.model.Computer; +import hudson.model.FreeStyleProject; +import hudson.model.Label; +import hudson.model.Slave; +import hudson.model.labels.LabelAtom; +import hudson.node_monitors.AbstractAsyncNodeMonitorDescriptor; +import hudson.node_monitors.AbstractNodeMonitorDescriptor; +import hudson.node_monitors.NodeMonitor; +import hudson.slaves.ComputerLauncher; +import hudson.tasks.BatchFile; +import hudson.tasks.Shell; +import org.codehaus.plexus.util.FileUtils; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.jvnet.hudson.test.Issue; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.SimpleCommandLauncher; + +import javax.annotation.CheckForNull; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Method; +import java.net.URISyntaxException; +import java.util.Collection; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.assertThat; + +/** + * Tests for old Remoting agent versions + */ +public class OldRemotingAgentTest { + + @Rule + public JenkinsRule j = new JenkinsRuleWithOldAgent(); + + @Rule + public TemporaryFolder tmpDir = new TemporaryFolder(); + + private File agentJar; + + @Before + public void extractAgent() throws Exception { + agentJar = new File(tmpDir.getRoot(), "old-agent.jar"); + FileUtils.copyURLToFile(getClass().getResource("/old-remoting/remoting-minimal-supported.jar"), agentJar); + } + + @Test + @Issue("JENKINS-48761") + public void shouldBeAbleToConnectAgentWithMinimalSupportedVersion() throws Exception { + Label agentLabel = new LabelAtom("old-agent"); + Slave agent = j.createOnlineSlave(agentLabel); + boolean isUnix = agent.getComputer().isUnix(); + assertThat("Received wrong agent version. A minimal supported version is expected", + agent.getComputer().getSlaveVersion(), + equalTo(RemotingVersionInfo.getMinimalSupportedVersion().toString())); + + // Just ensure we are able to run something on the agent + FreeStyleProject project = j.createFreeStyleProject("foo"); + project.setAssignedLabel(agentLabel); + project.getBuildersList().add(isUnix ? new Shell("echo Hello") : new BatchFile("echo 'hello'")); + j.buildAndAssertSuccess(project); + + // Run agent monitors + NodeMonitorAssert.assertMonitors(NodeMonitor.getAll(), agent.getComputer()); + } + + //TODO: move the logic to JTH + private class JenkinsRuleWithOldAgent extends JenkinsRule { + + @Override + public ComputerLauncher createComputerLauncher(EnvVars env) throws URISyntaxException, IOException { + + // EnvVars are ignored, simple Command Launcher does not offer this API in public + int sz = this.jenkins.getNodes().size(); + return new SimpleCommandLauncher(String.format("\"%s/bin/java\" %s -jar \"%s\"", + System.getProperty("java.home"), + SLAVE_DEBUG_PORT > 0 ? " -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=" + (SLAVE_DEBUG_PORT + sz) : "", + agentJar.getAbsolutePath())); + } + } + + private static class NodeMonitorAssert extends NodeMonitor { + + static void assertMonitors(Collection toCheck, Computer c) throws AssertionError { + for (NodeMonitor monitor : toCheck) { + assertMonitor(monitor, c); + } + } + + static void assertMonitor(NodeMonitor monitor, Computer c) throws AssertionError { + AbstractNodeMonitorDescriptor descriptor = monitor.getDescriptor(); + final Method monitorMethod; + try { + monitorMethod = AbstractAsyncNodeMonitorDescriptor.class.getDeclaredMethod("monitor", Computer.class); + } catch (NoSuchMethodException ex) { + System.out.println("Cannot invoke monitor " + monitor + ", no monitor(Computer.class) method in the Descriptor. It will be ignored. " + ex.getMessage()); + return; + } + try { + monitorMethod.setAccessible(true); + Object res = monitorMethod.invoke(descriptor, c); + System.out.println("Successfully executed monitor " + monitor); + } catch (Exception ex) { + throw new AssertionError("Failed to run monitor " + monitor + " for computer " + c, ex); + } finally { + monitorMethod.setAccessible(false); + } + } + } + +}