Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove brittle tests, simplify VersionMonitorTest #293

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 54 additions & 98 deletions src/test/java/hudson/plugin/versioncolumn/VersionMonitorTest.java
Original file line number Diff line number Diff line change
@@ -1,123 +1,96 @@
package hudson.plugin.versioncolumn;

import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.*;

import hudson.Proc;
import hudson.Util;
import hudson.model.Computer;
import hudson.remoting.Launcher;
import hudson.remoting.VirtualChannel;
import hudson.slaves.DumbSlave;
import hudson.slaves.OfflineCause;
import java.io.IOException;
import jenkins.security.MasterToSlaveCallable;
import jenkins.slaves.RemotingVersionInfo;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.jvnet.hudson.test.FakeLauncher;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.PretendSlave;
import org.mockito.ArgumentMatchers;

public class VersionMonitorTest {

@Test
public void testConstructor() {
VersionMonitor versionMonitor = new VersionMonitor();
assertNotNull("VersionMonitor instance should not be null", versionMonitor);
@ClassRule
public static JenkinsRule j = new JenkinsRule();

private VersionMonitor versionMonitor;
private VersionMonitor.DescriptorImpl descriptor;

@Before
public void createVersionMonitor() {
versionMonitor = new VersionMonitor();
descriptor = (VersionMonitor.DescriptorImpl) versionMonitor.getDescriptor();
}

@Test
public void testToHtml_NullVersion() {
VersionMonitor versionMonitor = new VersionMonitor();
String result = versionMonitor.toHtml(null);
assertEquals("N/A", result);
assertEquals("N/A", versionMonitor.toHtml(null));
}

@Test
public void testToHtml_SameVersion() {
VersionMonitor versionMonitor = new VersionMonitor();
String version = Launcher.VERSION;
String result = versionMonitor.toHtml(version);
assertEquals(version, result);
String remotingVersion = RemotingVersionInfo.getEmbeddedVersion().toString();
assertEquals(Launcher.VERSION, remotingVersion);
assertEquals(Launcher.VERSION, versionMonitor.toHtml(remotingVersion));
}

@Test
public void testToHtml_DifferentVersion() {
VersionMonitor versionMonitor = new VersionMonitor();
String version = "different-version";
String result = versionMonitor.toHtml(version);
String expected = Util.wrapToErrorSpan(version);
assertEquals(expected, result);
String version = RemotingVersionInfo.getMinimumSupportedVersion().toString();
assertEquals(Util.wrapToErrorSpan(version), versionMonitor.toHtml(version));
}

@Test
public void testDescriptorImplConstructor() {
VersionMonitor.DescriptorImpl descriptor = new VersionMonitor.DescriptorImpl();
assertNotNull("DescriptorImpl instance should not be null", descriptor);
assertSame("DESCRIPTOR should be set to this instance", VersionMonitor.DESCRIPTOR, descriptor);
VersionMonitor.DescriptorImpl descriptorImpl = new VersionMonitor.DescriptorImpl();
assertSame("DESCRIPTOR should be set to this instance", VersionMonitor.DESCRIPTOR, descriptorImpl);
}

@Test
public void testGetDisplayName() {
VersionMonitor.DescriptorImpl descriptor = new VersionMonitor.DescriptorImpl();
String displayName = descriptor.getDisplayName();
assertNotNull("Display name should not be null", displayName);
}

@Test
public void testMonitor_NullChannel() throws IOException, InterruptedException {
VersionMonitor.DescriptorImpl descriptor = new VersionMonitor.DescriptorImpl();
Computer computer = mock(Computer.class);

when(computer.getChannel()).thenReturn(null);

String result = descriptor.monitor(computer);

assertEquals("unknown-version", result);
verify(computer, never()).setTemporarilyOffline(anyBoolean(), any());
assertEquals("Remoting Version", descriptor.getDisplayName());
}

@Test
public void testMonitor_SameVersion() throws IOException, InterruptedException {
VersionMonitor.DescriptorImpl descriptor = new VersionMonitor.DescriptorImpl();
Computer computer = mock(Computer.class);
VirtualChannel channel = mock(VirtualChannel.class);

when(computer.getChannel()).thenReturn(channel);
when(channel.call(ArgumentMatchers.<MasterToSlaveCallable<String, IOException>>any()))
.thenReturn(Launcher.VERSION);
when(computer.isOffline()).thenReturn(false);

String result = descriptor.monitor(computer);

assertEquals(Launcher.VERSION, result);
verify(computer, never()).setTemporarilyOffline(anyBoolean(), any());
public void testMonitor_NullChannel() throws Exception {
PretendSlave pretendAgent = j.createPretendSlave(new TestLauncher());
Computer computer = pretendAgent.createComputer();
assertNull(computer.getChannel()); // Pre-condition for next assertion
assertEquals("unknown-version", descriptor.monitor(computer));
}

@Test
public void testMonitor_DifferentVersion_NotIgnored() throws IOException, InterruptedException {
VersionMonitor.DescriptorImpl descriptor = spy(new VersionMonitor.DescriptorImpl());
doReturn(false).when(descriptor).isIgnored(); // Ensure isIgnored returns false

Computer computer = mock(Computer.class);
VirtualChannel channel = mock(VirtualChannel.class);
String differentVersion = "different-version";

when(computer.getChannel()).thenReturn(channel);
when(channel.call(ArgumentMatchers.<MasterToSlaveCallable<String, IOException>>any()))
.thenReturn(differentVersion);
when(computer.isOffline()).thenReturn(false);
when(computer.getName()).thenReturn("TestComputer");

String result = descriptor.monitor(computer);

assertEquals(differentVersion, result);
verify(computer).setTemporarilyOffline(eq(true), any(VersionMonitor.RemotingVersionMismatchCause.class));
public void testMonitor_SameVersion() throws Exception {
DumbSlave agent = j.createOnlineSlave();
Computer computer = agent.getComputer();
assertNotNull(computer.getChannel());
assertEquals(Launcher.VERSION, descriptor.monitor(computer));
}

@Test
public void testMonitor_DifferentVersion_Ignored() throws IOException, InterruptedException {
VersionMonitor.DescriptorImpl descriptor = spy(new VersionMonitor.DescriptorImpl());
doReturn(true).when(descriptor).isIgnored(); // Ensure isIgnored returns true.
VersionMonitor.DescriptorImpl mockDescriptor = spy(new VersionMonitor.DescriptorImpl());
doReturn(true).when(mockDescriptor).isIgnored(); // Ensure isIgnored returns true.

Computer computer = mock(Computer.class);
VirtualChannel channel = mock(VirtualChannel.class);
Expand All @@ -128,36 +101,16 @@ public void testMonitor_DifferentVersion_Ignored() throws IOException, Interrupt
.thenReturn(differentVersion);
when(computer.isOffline()).thenReturn(false);

String result = descriptor.monitor(computer);
String result = mockDescriptor.monitor(computer);

assertEquals(differentVersion, result);
verify(computer, never()).setTemporarilyOffline(anyBoolean(), any());
}

@Test
public void testMonitor_VersionIsNull_NotIgnored() throws IOException, InterruptedException {
VersionMonitor.DescriptorImpl descriptor = spy(new VersionMonitor.DescriptorImpl());
doReturn(false).when(descriptor).isIgnored(); // Ensure isIgnored returns false

Computer computer = mock(Computer.class);
VirtualChannel channel = mock(VirtualChannel.class);

when(computer.getChannel()).thenReturn(channel);
when(channel.call(ArgumentMatchers.<MasterToSlaveCallable<String, IOException>>any()))
.thenReturn(null);
when(computer.isOffline()).thenReturn(false);
when(computer.getName()).thenReturn("TestComputer");

String result = descriptor.monitor(computer);

assertNull(result);
verify(computer).setTemporarilyOffline(eq(true), any(VersionMonitor.RemotingVersionMismatchCause.class));
}

@Test
public void testMonitor_VersionIsNull_Ignored() throws IOException, InterruptedException {
VersionMonitor.DescriptorImpl descriptor = spy(new VersionMonitor.DescriptorImpl());
doReturn(true).when(descriptor).isIgnored(); // Ensure isIgnored returns true.
VersionMonitor.DescriptorImpl mockDescriptor = spy(new VersionMonitor.DescriptorImpl());
doReturn(true).when(mockDescriptor).isIgnored(); // Ensure isIgnored returns true.

Computer computer = mock(Computer.class);
VirtualChannel channel = mock(VirtualChannel.class);
Expand All @@ -169,15 +122,14 @@ public void testMonitor_VersionIsNull_Ignored() throws IOException, InterruptedE
when(computer.isOffline()).thenReturn(true);
when(computer.getOfflineCause()).thenReturn(cause);

String result = descriptor.monitor(computer);
String result = mockDescriptor.monitor(computer);

assertNull(result);
verify(computer).setTemporarilyOffline(eq(false), isNull());
}

@Test
public void testMonitor_OfflineDueToMismatch_VersionsMatch() throws IOException, InterruptedException {
VersionMonitor.DescriptorImpl descriptor = new VersionMonitor.DescriptorImpl();
Computer computer = mock(Computer.class);
VirtualChannel channel = mock(VirtualChannel.class);
VersionMonitor.RemotingVersionMismatchCause cause = new VersionMonitor.RemotingVersionMismatchCause("Mismatch");
Expand All @@ -196,7 +148,6 @@ public void testMonitor_OfflineDueToMismatch_VersionsMatch() throws IOException,

@Test
public void testMonitor_OfflineDueToOtherCause() throws IOException, InterruptedException {
VersionMonitor.DescriptorImpl descriptor = new VersionMonitor.DescriptorImpl();
Computer computer = mock(Computer.class);
VirtualChannel channel = mock(VirtualChannel.class);
OfflineCause otherCause = mock(OfflineCause.class);
Expand All @@ -222,6 +173,11 @@ public void testRemotingVersionMismatchCause() {
assertEquals(VersionMonitor.class, cause.getTrigger());
}

// Since SlaveVersion is private, we cannot test it directly.
// However, we can test its behavior indirectly through the monitor method.
private class TestLauncher implements FakeLauncher {

@Override
public Proc onLaunch(hudson.Launcher.ProcStarter p) throws IOException {
throw new UnsupportedOperationException("Unsupported run.");
}
}
}
Loading