From 15ce24ae4dac23a732f193f29b6423bc03be7a49 Mon Sep 17 00:00:00 2001 From: peppelan Date: Sun, 29 May 2016 12:38:32 +0200 Subject: [PATCH] [JENKINS-35198] - DelegatingComputerLauncher should accept child classes in its hooks (#2384) * JENKINS-35198 Add failing test for clear identification of the issue and future regression test * JENKINS-35198 Fix DelegatingComputerLauncher logic for filtering out subclasses as possible delegates this logic is by default, and subclasses can still allow the selection of other DelegatingComputerLauncher instances as delegates. --- .../slaves/DelegatingComputerLauncher.java | 2 +- .../DelegatingComputerLauncherTest.java | 71 +++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 core/src/test/java/hudson/slaves/DelegatingComputerLauncherTest.java diff --git a/core/src/main/java/hudson/slaves/DelegatingComputerLauncher.java b/core/src/main/java/hudson/slaves/DelegatingComputerLauncher.java index 34f8154ead..47a9b0815b 100644 --- a/core/src/main/java/hudson/slaves/DelegatingComputerLauncher.java +++ b/core/src/main/java/hudson/slaves/DelegatingComputerLauncher.java @@ -74,7 +74,7 @@ public abstract class DelegatingComputerLauncher extends ComputerLauncher { public List> getApplicableDescriptors() { List> r = new ArrayList>(); for (Descriptor d : Functions.getComputerLauncherDescriptors()) { - if (DelegatingComputerLauncher.class.isInstance(d)) continue; + if (DelegatingComputerLauncher.class.isAssignableFrom(d.getKlass().toJavaClass())) continue; r.add(d); } return r; diff --git a/core/src/test/java/hudson/slaves/DelegatingComputerLauncherTest.java b/core/src/test/java/hudson/slaves/DelegatingComputerLauncherTest.java new file mode 100644 index 0000000000..3b76651562 --- /dev/null +++ b/core/src/test/java/hudson/slaves/DelegatingComputerLauncherTest.java @@ -0,0 +1,71 @@ +package hudson.slaves; + +import hudson.DescriptorExtensionList; +import hudson.model.Descriptor; +import jenkins.model.Jenkins; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; + +import static org.junit.Assert.*; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.powermock.api.mockito.PowerMockito.mock; +import static org.powermock.api.mockito.PowerMockito.when; + +/** + * @author peppelan + */ +@RunWith(PowerMockRunner.class) +public class DelegatingComputerLauncherTest { + + public static class DummyOne extends DelegatingComputerLauncher { + + public DummyOne() { + super(null); + } + + public static class DummyOneDescriptor extends DescriptorImpl { + } + } + + + public static class DummyTwo extends DelegatingComputerLauncher { + + public DummyTwo() { + super(null); + } + + public static class DummyTwoDescriptor extends DescriptorImpl { + } + } + + // Ensure that by default a DelegatingComputerLauncher subclass doesn't advertise the option to delegate another + // DelegatingComputerLauncher + @Test + @PrepareForTest(Jenkins.class) + public void testRecursionAvoidance() { + PowerMockito.mockStatic(Jenkins.class); + Jenkins mockJenkins = mock(Jenkins.class); + PowerMockito.when(Jenkins.getInstance()).thenReturn(mockJenkins); + + DescriptorExtensionList> mockList = + mock(DescriptorExtensionList.class); + doReturn(mockList).when(mockJenkins).getDescriptorList(eq(ComputerLauncher.class)); + ArrayList> returnedList = new ArrayList<>(); + + returnedList.add(new DummyOne.DummyOneDescriptor()); + returnedList.add(new DummyTwo.DummyTwoDescriptor()); + + when(mockList.iterator()).thenReturn(returnedList.iterator()); + + assertTrue("DelegatingComputerLauncher should filter out other DelegatingComputerLauncher instances " + + "from its descriptor's getApplicableDescriptors() method", + new DummyTwo.DummyTwoDescriptor().getApplicableDescriptors().isEmpty()); + } + +} -- GitLab