Migrate tests to JUnit5 (core / hudson / 2) (#10577)

This commit is contained in:
Kris Stern 2025-05-28 23:15:57 +08:00 committed by GitHub
commit 330a32faf9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
47 changed files with 1460 additions and 1266 deletions

View File

@ -24,18 +24,18 @@
package hudson;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import hudson.model.Saveable;
import java.io.IOException;
import org.junit.Test;
import org.junit.jupiter.api.Test;
/**
* Tests {@link BulkChange}.
*
* @author Kohsuke Kawaguchi
*/
public class BulkChangeTest {
class BulkChangeTest {
private static class Point implements Saveable {
/**
@ -72,7 +72,7 @@ public class BulkChangeTest {
* If there is no BulkChange, we should see two saves.
*/
@Test
public void noBulkChange() throws Exception {
void noBulkChange() throws Exception {
Point pt = new Point();
pt.set(0, 0);
assertEquals(2, pt.saveCount);
@ -82,7 +82,7 @@ public class BulkChangeTest {
* With a {@link BulkChange}, this will become just one save.
*/
@Test
public void bulkChange() throws Exception {
void bulkChange() throws Exception {
Point pt = new Point();
BulkChange bc = new BulkChange(pt);
try {
@ -97,7 +97,7 @@ public class BulkChangeTest {
* {@link BulkChange}s can be nested.
*/
@Test
public void nestedBulkChange() throws Exception {
void nestedBulkChange() throws Exception {
Point pt = new Point();
Point pt2 = new Point();
BulkChange bc1 = new BulkChange(pt);

View File

@ -1,64 +0,0 @@
package hudson;
import hudson.remoting.Channel;
import hudson.remoting.ChannelBuilder;
import hudson.remoting.FastPipedInputStream;
import hudson.remoting.FastPipedOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.junit.rules.ExternalResource;
/**
* Test that uses a connected channel.
*
* @author Kohsuke Kawaguchi
*/
public final class ChannelRule extends ExternalResource {
/**
* Two channels that are connected to each other, but shares the same classloader.
*/
public Channel french;
public Channel british;
private ExecutorService executors;
@Override protected void before() throws Exception {
executors = Executors.newCachedThreadPool();
final FastPipedInputStream p1i = new FastPipedInputStream();
final FastPipedInputStream p2i = new FastPipedInputStream();
final FastPipedOutputStream p1o = new FastPipedOutputStream(p1i);
final FastPipedOutputStream p2o = new FastPipedOutputStream(p2i);
Future<Channel> f1 = executors.submit(new Callable<>() {
@Override
public Channel call() throws Exception {
return new ChannelBuilder("This side of the channel", executors).withMode(Channel.Mode.BINARY).build(p1i, p2o);
}
});
Future<Channel> f2 = executors.submit(new Callable<>() {
@Override
public Channel call() throws Exception {
return new ChannelBuilder("The other side of the channel", executors).withMode(Channel.Mode.BINARY).build(p2i, p1o);
}
});
french = f1.get();
british = f2.get();
}
@Override protected void after() {
try {
french.close(); // this will automatically initiate the close on the other channel, too.
french.join();
british.join();
} catch (IOException e) {
throw new UncheckedIOException(e);
} catch (InterruptedException x) {
throw new AssertionError(x);
}
executors.shutdownNow();
}
}

View File

@ -37,10 +37,10 @@ import org.junit.jupiter.api.Test;
/**
* @author <a href="mailto:tom.fennelly@gmail.com">tom.fennelly@gmail.com</a>
*/
public class ClassicPluginStrategyTest {
class ClassicPluginStrategyTest {
@Test
public void test_getDetachedPlugins() {
void test_getDetachedPlugins() {
List<DetachedPlugin> list = DetachedPluginsUtil.getDetachedPlugins(new VersionNumber("1.296"));
assertTrue(list.size() >= 14); // There were 14 at the time of writing this test

View File

@ -41,17 +41,17 @@ import org.junit.jupiter.api.Test;
/**
* @author Kohsuke Kawaguchi
*/
public class EnvVarsTest {
class EnvVarsTest {
@Test
public void caseInsensitive() {
void caseInsensitive() {
EnvVars ev = new EnvVars(Map.of("Path", "A:B:C"));
assertTrue(ev.containsKey("PATH"));
assertEquals("A:B:C", ev.get("PATH"));
}
@Test
public void overrideExpandingAll() {
void overrideExpandingAll() {
EnvVars env = new EnvVars();
env.put("PATH", "orig");
env.put("A", "Value1");
@ -71,7 +71,7 @@ public class EnvVarsTest {
}
@Test
public void overrideOrderCalculatorSimple() {
void overrideOrderCalculatorSimple() {
EnvVars env = new EnvVars();
EnvVars overrides = new EnvVars();
overrides.put("A", "NoReference");
@ -87,7 +87,7 @@ public class EnvVarsTest {
}
@Test
public void overrideOrderCalculatorInOrder() {
void overrideOrderCalculatorInOrder() {
EnvVars env = new EnvVars();
EnvVars overrides = new EnvVars();
overrides.put("A", "NoReference");
@ -102,7 +102,7 @@ public class EnvVarsTest {
}
@Test
public void overrideOrderCalculatorMultiple() {
void overrideOrderCalculatorMultiple() {
EnvVars env = new EnvVars();
EnvVars overrides = new EnvVars();
overrides.put("A", "Noreference");
@ -115,7 +115,7 @@ public class EnvVarsTest {
}
@Test
public void overrideOrderCalculatorSelfReference() {
void overrideOrderCalculatorSelfReference() {
EnvVars env = new EnvVars();
EnvVars overrides = new EnvVars();
overrides.put("PATH", "some;${PATH}");
@ -126,7 +126,7 @@ public class EnvVarsTest {
}
@Test
public void overrideOrderCalculatorCyclic() {
void overrideOrderCalculatorCyclic() {
EnvVars env = new EnvVars();
env.put("C", "Existing");
EnvVars overrides = new EnvVars();
@ -144,7 +144,7 @@ public class EnvVarsTest {
}
@Test
public void putIfNotNull() {
void putIfNotNull() {
EnvVars env = new EnvVars();
env.putIfNotNull("foo", null);
assertTrue(env.isEmpty());
@ -153,7 +153,7 @@ public class EnvVarsTest {
}
@Test
public void putAllNonNull() {
void putAllNonNull() {
EnvVars env = new EnvVars();
TreeMap<String, String> map = new TreeMap<>();
map.put("A", "a");

View File

@ -26,14 +26,14 @@ package hudson;
import static org.hamcrest.MatcherAssert.assertThat;
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.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ -41,6 +41,10 @@ import static org.mockito.Mockito.when;
import hudson.FilePath.TarCompression;
import hudson.model.TaskListener;
import hudson.os.WindowsUtil;
import hudson.remoting.Channel;
import hudson.remoting.ChannelBuilder;
import hudson.remoting.FastPipedInputStream;
import hudson.remoting.FastPipedOutputStream;
import hudson.remoting.VirtualChannel;
import hudson.slaves.WorkspaceList;
import hudson.util.StreamTaskListener;
@ -51,6 +55,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.io.UncheckedIOException;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
@ -79,29 +84,66 @@ import java.util.zip.ZipOutputStream;
import org.apache.commons.io.FileUtils;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Chmod;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
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.junit.jupiter.api.io.TempDir;
import org.jvnet.hudson.test.Issue;
import org.mockito.Mockito;
/**
* @author Kohsuke Kawaguchi
*/
public class FilePathTest {
class FilePathTest {
@Rule public ChannelRule channels = new ChannelRule();
@Rule public TemporaryFolder temp = new TemporaryFolder();
@TempDir
private File temp;
@Test public void copyTo() throws Exception {
File tmp = temp.newFile();
FilePath f = new FilePath(channels.french, tmp.getPath());
/**
* Two channels that are connected to each other, but shares the same classloader.
*/
private Channel french;
private Channel british;
private ExecutorService executors;
@BeforeEach
void setUp() throws Exception {
executors = Executors.newCachedThreadPool();
final FastPipedInputStream p1i = new FastPipedInputStream();
final FastPipedInputStream p2i = new FastPipedInputStream();
final FastPipedOutputStream p1o = new FastPipedOutputStream(p1i);
final FastPipedOutputStream p2o = new FastPipedOutputStream(p2i);
Future<Channel> f1 = executors.submit(() -> new ChannelBuilder("This side of the channel", executors).withMode(Channel.Mode.BINARY).build(p1i, p2o));
Future<Channel> f2 = executors.submit(() -> new ChannelBuilder("The other side of the channel", executors).withMode(Channel.Mode.BINARY).build(p2i, p1o));
french = f1.get();
british = f2.get();
}
@AfterEach
void tearDown() {
try {
french.close(); // this will automatically initiate the close on the other channel, too.
french.join();
british.join();
} catch (IOException e) {
throw new UncheckedIOException(e);
} catch (InterruptedException x) {
throw new AssertionError(x);
}
executors.shutdownNow();
}
@Test
void copyTo() throws Exception {
File tmp = File.createTempFile("junit", null, temp);
FilePath f = new FilePath(french, tmp.getPath());
try (OutputStream out = OutputStream.nullOutputStream()) {
f.copyTo(out);
}
assertTrue("target does not exist", tmp.exists());
assertTrue("could not delete target " + tmp.getPath(), tmp.delete());
assertTrue(tmp.exists(), "target does not exist");
assertTrue(tmp.delete(), "could not delete target " + tmp.getPath());
}
/**
@ -110,12 +152,13 @@ public class FilePathTest {
*/
// TODO: this test is much too slow to be a traditional unit test. Should be extracted into some stress test
// which is no part of the default test harness?
@Test public void noFileLeakInCopyTo() throws Exception {
@Test
void noFileLeakInCopyTo() throws Exception {
for (int j = 0; j < 2500; j++) {
File tmp = temp.newFile();
File tmp = File.createTempFile("junit", null, temp);
FilePath f = new FilePath(tmp);
File tmp2 = temp.newFile();
FilePath f2 = new FilePath(channels.british, tmp2.getPath());
File tmp2 = File.createTempFile("junit", null, temp);
FilePath f2 = new FilePath(british, tmp2.getPath());
f.copyTo(f2);
@ -137,8 +180,9 @@ public class FilePathTest {
* Also see JENKINS-7897
*/
@Issue("JENKINS-7871")
@Test public void noRaceConditionInCopyTo() throws Exception {
final File tmp = temp.newFile();
@Test
void noRaceConditionInCopyTo() throws Exception {
final File tmp = File.createTempFile("junit", null, temp);
int fileSize = 90000;
@ -197,7 +241,7 @@ public class FilePathTest {
}
}
FilePath f = new FilePath(channels.french, file.getPath());
FilePath f = new FilePath(french, file.getPath());
Sink sink = new Sink();
f.copyTo(sink);
return sink.count.get();
@ -212,11 +256,12 @@ public class FilePathTest {
}
}
@Test public void repeatCopyRecursiveTo() throws Exception {
@Test
void repeatCopyRecursiveTo() throws Exception {
// local->local copy used to return 0 if all files were "up to date"
// should return number of files processed, whether or not they were copied or already current
File src = temp.newFolder("src");
File dst = temp.newFolder("dst");
File src = newFolder(temp, "src");
File dst = newFolder(temp, "dst");
File.createTempFile("foo", ".tmp", src);
FilePath fp = new FilePath(src);
assertEquals(1, fp.copyRecursiveTo(new FilePath(dst)));
@ -225,11 +270,12 @@ public class FilePathTest {
}
@Issue("JENKINS-9540")
@Test public void errorMessageInRemoteCopyRecursive() throws Exception {
File src = temp.newFolder("src");
File dst = temp.newFolder("dst");
@Test
void errorMessageInRemoteCopyRecursive() throws Exception {
File src = newFolder(temp, "src");
File dst = newFolder(temp, "dst");
FilePath from = new FilePath(src);
FilePath to = new FilePath(channels.british, dst.getAbsolutePath());
FilePath to = new FilePath(british, dst.getAbsolutePath());
for (int i = 0; i < 10000; i++) {
// TODO is there a simpler way to force the TarOutputStream to be flushed and the reader to start?
// Have not found a way to make the failure guaranteed.
@ -257,8 +303,9 @@ public class FilePathTest {
}
@Issue("JENKINS-4039")
@Test public void archiveBug() throws Exception {
FilePath d = new FilePath(channels.french, temp.getRoot().getPath());
@Test
void archiveBug() throws Exception {
FilePath d = new FilePath(french, temp.getPath());
d.child("test").touch(0);
try (OutputStream out = OutputStream.nullOutputStream()) {
d.zip(out);
@ -268,7 +315,8 @@ public class FilePathTest {
}
}
@Test public void normalization() {
@Test
void normalization() {
compare("abc/def\\ghi", "abc/def\\ghi"); // allow mixed separators
{ // basic '.' trimming
@ -322,7 +370,8 @@ public class FilePathTest {
}
@Issue("JENKINS-6494")
@Test public void getParent() {
@Test
void getParent() {
FilePath fp = new FilePath((VirtualChannel) null, "/abc/def");
assertEquals("/abc", (fp = fp.getParent()).getRemote());
assertEquals("/", (fp = fp.getParent()).getRemote());
@ -352,7 +401,8 @@ public class FilePathTest {
* Performs round-trip archiving for Tar handling methods.
* @throws Exception test failure
*/
@Test public void compressTarUntarRoundTrip() throws Exception {
@Test
void compressTarUntarRoundTrip() throws Exception {
checkTarUntarRoundTrip("compressTarUntarRoundTrip_zero", 0);
checkTarUntarRoundTrip("compressTarUntarRoundTrip_small", 100);
checkTarUntarRoundTrip("compressTarUntarRoundTrip_medium", 50000);
@ -365,15 +415,16 @@ public class FilePathTest {
* @throws Exception test failure
*/
@Issue("JENKINS-10629")
@Ignore
@Test public void archiveBigFile() throws Exception {
@Disabled
@Test
void archiveBigFile() throws Exception {
final long largeFileSize = 9000000000L; // >8589934591 bytes
final String filePrefix = "JENKINS-10629";
checkTarUntarRoundTrip(filePrefix, largeFileSize);
}
private void checkTarUntarRoundTrip(String filePrefix, long fileSize) throws Exception {
final File tmpDir = temp.newFolder(filePrefix);
final File tmpDir = newFolder(temp, filePrefix);
final File tempFile = new File(tmpDir, filePrefix + ".log");
RandomAccessFile file = new RandomAccessFile(tempFile, "rw");
final File tarFile = new File(tmpDir, filePrefix + ".tar");
@ -385,18 +436,18 @@ public class FilePathTest {
// Compress archive
final FilePath tmpDirPath = new FilePath(tmpDir);
int tar = tmpDirPath.tar(Files.newOutputStream(tarFile.toPath()), tempFile.getName());
assertEquals("One file should have been compressed", 1, tar);
assertEquals(1, tar, "One file should have been compressed");
// Decompress
FilePath outDir = new FilePath(temp.newFolder(filePrefix + "_out"));
FilePath outDir = new FilePath(newFolder(temp, filePrefix + "_out"));
final FilePath outFile = outDir.child(tempFile.getName());
tmpDirPath.child(tarFile.getName()).untar(outDir, TarCompression.NONE);
assertEquals("Result file after the roundtrip differs from the initial file",
new FilePath(tempFile).digest(), outFile.digest());
assertEquals(new FilePath(tempFile).digest(), outFile.digest(), "Result file after the roundtrip differs from the initial file");
}
@Test public void list() throws Exception {
File baseDir = temp.getRoot();
@Test
void list() throws Exception {
File baseDir = temp;
final Set<FilePath> expected = new HashSet<>();
expected.add(createFilePath(baseDir, "top", "sub", "app.log"));
expected.add(createFilePath(baseDir, "top", "sub", "trace.log"));
@ -406,8 +457,9 @@ public class FilePathTest {
assertEquals(expected, new HashSet<>(Arrays.asList(result)));
}
@Test public void listWithExcludes() throws Exception {
File baseDir = temp.getRoot();
@Test
void listWithExcludes() throws Exception {
File baseDir = temp;
final Set<FilePath> expected = new HashSet<>();
expected.add(createFilePath(baseDir, "top", "sub", "app.log"));
createFilePath(baseDir, "top", "sub", "trace.log");
@ -417,8 +469,9 @@ public class FilePathTest {
assertEquals(expected, new HashSet<>(Arrays.asList(result)));
}
@Test public void listWithDefaultExcludes() throws Exception {
File baseDir = temp.getRoot();
@Test
void listWithDefaultExcludes() throws Exception {
File baseDir = temp;
final Set<FilePath> expected = new HashSet<>();
expected.add(createFilePath(baseDir, "top", "sub", "backup~"));
expected.add(createFilePath(baseDir, "top", "CVS", "somefile,v"));
@ -430,7 +483,8 @@ public class FilePathTest {
}
@Issue("JENKINS-11073")
@Test public void isUnix() {
@Test
void isUnix() {
VirtualChannel dummy = Mockito.mock(VirtualChannel.class);
FilePath winPath = new FilePath(dummy,
" c:\\app\\hudson\\workspace\\3.8-jelly-db\\jdk/jdk1.6.0_21/label/sqlserver/profile/sqlserver\\acceptance-tests\\distribution.zip");
@ -453,8 +507,9 @@ public class FilePathTest {
* Also tries to check that a problem with setting the last-modified date on Windows doesn't fail the whole copy
* - well at least when running this test on a Windows OS. See JENKINS-11073
*/
@Test public void copyToWithPermission() throws IOException, InterruptedException {
File tmp = temp.getRoot();
@Test
void copyToWithPermission() throws IOException, InterruptedException {
File tmp = temp;
File child = new File(tmp, "child");
FilePath childP = new FilePath(child);
childP.touch(4711);
@ -465,7 +520,7 @@ public class FilePathTest {
chmodTask.setPerm("0400");
chmodTask.execute();
FilePath copy = new FilePath(channels.british, tmp.getPath()).child("copy");
FilePath copy = new FilePath(british, tmp.getPath()).child("copy");
childP.copyToWithPermission(copy);
assertEquals(childP.mode(), copy.mode());
@ -477,15 +532,16 @@ public class FilePathTest {
// Windows seems to have random failures when setting the timestamp on newly generated
// files. So test that:
for (int i = 0; i < 100; i++) {
copy = new FilePath(channels.british, tmp.getPath()).child("copy" + i);
copy = new FilePath(british, tmp.getPath()).child("copy" + i);
childP.copyToWithPermission(copy);
}
}
@Test public void symlinkInTar() throws Exception {
@Test
void symlinkInTar() throws Exception {
assumeFalse(Functions.isWindows());
FilePath tmp = new FilePath(temp.getRoot());
FilePath tmp = new FilePath(temp);
FilePath in = tmp.child("in");
in.mkdirs();
in.child("c").touch(0);
@ -501,7 +557,8 @@ public class FilePathTest {
}
@Issue("JENKINS-13649")
@Test public void multiSegmentRelativePaths() {
@Test
void multiSegmentRelativePaths() {
VirtualChannel d = Mockito.mock(VirtualChannel.class);
FilePath winPath = new FilePath(d, "c:\\app\\jenkins\\workspace");
FilePath nixPath = new FilePath(d, "/opt/jenkins/workspace");
@ -514,9 +571,10 @@ public class FilePathTest {
assertEquals("/opt/jenkins/workspace/foo/bar/manchu", new FilePath(nixPath, "foo/bar/manchu").getRemote());
}
@Test public void validateAntFileMask() throws Exception {
File tmp = temp.getRoot();
FilePath d = new FilePath(channels.french, tmp.getPath());
@Test
void validateAntFileMask() throws Exception {
File tmp = temp;
FilePath d = new FilePath(french, tmp.getPath());
d.child("d1/d2/d3").mkdirs();
d.child("d1/d2/d3/f.txt").touch(0);
d.child("d1/d2/d3/f.html").touch(0);
@ -537,9 +595,10 @@ public class FilePathTest {
@Issue("JENKINS-7214")
@SuppressWarnings("deprecation")
@Test public void validateAntFileMaskBounded() throws Exception {
File tmp = temp.getRoot();
FilePath d = new FilePath(channels.french, tmp.getPath());
@Test
void validateAntFileMaskBounded() throws Exception {
File tmp = temp;
FilePath d = new FilePath(french, tmp.getPath());
FilePath d2 = d.child("d1/d2");
d2.mkdirs();
for (int i = 0; i < 100; i++) {
@ -554,10 +613,11 @@ public class FilePathTest {
}
@Issue("JENKINS-5253")
@Test public void testValidateCaseSensitivity() throws Exception {
@Test
void testValidateCaseSensitivity() throws Exception {
File tmp = Util.createTempDir();
try {
FilePath d = new FilePath(channels.french, tmp.getPath());
FilePath d = new FilePath(french, tmp.getPath());
d.child("d1/d2/d3").mkdirs();
d.child("d1/d2/d3/f.txt").touch(0);
d.child("d1/d2/d3/f.html").touch(0);
@ -573,9 +633,10 @@ public class FilePathTest {
}
@Issue("JENKINS-15418")
@Test public void deleteLongPathOnWindows() throws Exception {
File tmp = temp.getRoot();
FilePath d = new FilePath(channels.french, tmp.getPath());
@Test
void deleteLongPathOnWindows() throws Exception {
File tmp = temp;
FilePath d = new FilePath(french, tmp.getPath());
// construct a very long path
StringBuilder sb = new StringBuilder();
@ -592,12 +653,13 @@ public class FilePathTest {
File firstDirectory = new File(tmp.getAbsolutePath() + "/very");
Util.deleteRecursive(firstDirectory);
assertFalse("Could not delete directory!", firstDirectory.exists());
assertFalse(firstDirectory.exists(), "Could not delete directory!");
}
@Issue("JENKINS-16215")
@Test public void installIfNecessaryAvoidsExcessiveDownloadsByUsingIfModifiedSince() throws Exception {
File tmp = temp.getRoot();
@Test
void installIfNecessaryAvoidsExcessiveDownloadsByUsingIfModifiedSince() throws Exception {
File tmp = temp;
final FilePath d = new FilePath(tmp);
d.child(".timestamp").touch(123000);
@ -614,8 +676,9 @@ public class FilePathTest {
}
@Issue("JENKINS-16215")
@Test public void installIfNecessaryPerformsInstallation() throws Exception {
File tmp = temp.getRoot();
@Test
void installIfNecessaryPerformsInstallation() throws Exception {
File tmp = temp;
final FilePath d = new FilePath(tmp);
final HttpURLConnection con = mock(HttpURLConnection.class);
@ -631,8 +694,9 @@ public class FilePathTest {
}
@Issue("JENKINS-26196")
@Test public void installIfNecessarySkipsDownloadWhenErroneous() throws Exception {
File tmp = temp.getRoot();
@Test
void installIfNecessarySkipsDownloadWhenErroneous() throws Exception {
File tmp = temp;
final FilePath d = new FilePath(tmp);
d.child(".timestamp").touch(123000);
final HttpURLConnection con = mock(HttpURLConnection.class);
@ -645,13 +709,14 @@ public class FilePathTest {
assertFalse(d.installIfNecessaryFrom(url, new StreamTaskListener(baos, Charset.defaultCharset()), message));
verify(con).setIfModifiedSince(123000);
String log = baos.toString(Charset.defaultCharset());
assertFalse(log, log.contains(message));
assertTrue(log, log.contains("504 Gateway Timeout"));
assertFalse(log.contains(message), log);
assertTrue(log.contains("504 Gateway Timeout"), log);
}
@Issue("JENKINS-23507")
@Test public void installIfNecessaryFollowsRedirects() throws Exception {
File tmp = temp.getRoot();
@Test
void installIfNecessaryFollowsRedirects() throws Exception {
File tmp = temp;
final FilePath d = new FilePath(tmp);
FilePath.UrlFactory urlFactory = mock(FilePath.UrlFactory.class);
d.setUrlFactory(urlFactory);
@ -671,13 +736,15 @@ public class FilePathTest {
}
@Issue("JENKINS-72469")
@Test public void installIfNecessaryWithoutLastModifiedStrongValidator() throws Exception {
@Test
void installIfNecessaryWithoutLastModifiedStrongValidator() throws Exception {
String strongValidator = "\"An-ETag-strong-validator\"";
installIfNecessaryWithoutLastModified(strongValidator);
}
@Issue("JENKINS-72469")
@Test public void installIfNecessaryWithoutLastModifiedStrongValidatorNoQuotes() throws Exception {
@Test
void installIfNecessaryWithoutLastModifiedStrongValidatorNoQuotes() throws Exception {
// This ETag is a violation of the spec at https://httpwg.org/specs/rfc9110.html#field.etag
// However, better safe to handle without quotes as well, just in case
String strongValidator = "An-ETag-strong-validator-without-quotes";
@ -685,20 +752,23 @@ public class FilePathTest {
}
@Issue("JENKINS-72469")
@Test public void installIfNecessaryWithoutLastModifiedWeakValidator() throws Exception {
@Test
void installIfNecessaryWithoutLastModifiedWeakValidator() throws Exception {
String weakValidator = "W/\"An-ETag-weak-validator\"";
installIfNecessaryWithoutLastModified(weakValidator);
}
@Issue("JENKINS-72469")
@Test public void installIfNecessaryWithoutLastModifiedStrongAndWeakValidators() throws Exception {
@Test
void installIfNecessaryWithoutLastModifiedStrongAndWeakValidators() throws Exception {
String strongValidator = "\"An-ETag-validator\"";
String weakValidator = "W/" + strongValidator;
installIfNecessaryWithoutLastModified(strongValidator, weakValidator);
}
@Issue("JENKINS-72469")
@Test public void installIfNecessaryWithoutLastModifiedWeakAndStrongValidators() throws Exception {
@Test
void installIfNecessaryWithoutLastModifiedWeakAndStrongValidators() throws Exception {
String strongValidator = "\"An-ETag-validator\"";
String weakValidator = "W/" + strongValidator;
installIfNecessaryWithoutLastModified(weakValidator, strongValidator);
@ -718,7 +788,7 @@ public class FilePathTest {
final URL url = someUrlToZipFile(con);
File tmp = temp.getRoot();
File tmp = temp;
final FilePath d = new FilePath(tmp);
/* Initial download expected to occur */
@ -764,8 +834,9 @@ public class FilePathTest {
}
@Issue("JENKINS-16846")
@Test public void moveAllChildrenTo() throws IOException, InterruptedException {
File tmp = temp.getRoot();
@Test
void moveAllChildrenTo() throws IOException, InterruptedException {
File tmp = temp;
final String dirname = "sub";
final File top = new File(tmp, "test");
final File sub = new File(top, dirname);
@ -787,8 +858,8 @@ public class FilePathTest {
@Issue("JENKINS-10629")
@Test
public void testEOFbrokenFlush() throws IOException, InterruptedException {
final File srcFolder = temp.newFolder("src");
void testEOFbrokenFlush() throws IOException, InterruptedException {
final File srcFolder = newFolder(temp, "src");
// simulate magic structure with magic sizes:
// |- dir/pom.xml (2049)
// |- pom.xml (2049)
@ -801,15 +872,15 @@ public class FilePathTest {
givenSomeContentInFile(pomFile, 2049);
FileUtils.copyFileToDirectory(pomFile, srcFolder);
final File archive = temp.newFile("archive.tar");
final File archive = File.createTempFile("archive.tar", null, temp);
// Compress archive
final FilePath tmpDirPath = new FilePath(srcFolder);
int tarred = tmpDirPath.tar(Files.newOutputStream(archive.toPath()), "**");
assertEquals("One file should have been compressed", 3, tarred);
assertEquals(3, tarred, "One file should have been compressed");
// Decompress
final File dstFolder = temp.newFolder("dst");
final File dstFolder = newFolder(temp, "dst");
dstFolder.mkdirs();
FilePath outDir = new FilePath(dstFolder);
// and now fail when flush is bad!
@ -817,9 +888,9 @@ public class FilePathTest {
}
@Test
public void chmod() throws Exception {
void chmod() throws Exception {
assumeFalse(Functions.isWindows());
File f = temp.newFile("file");
File f = File.createTempFile("file", null, temp);
FilePath fp = new FilePath(f);
int prevMode = fp.mode();
assertEquals(0400, chmodAndMode(fp, 0400));
@ -829,12 +900,12 @@ public class FilePathTest {
}
@Test
public void chmodInvalidPermissions() throws Exception {
void chmodInvalidPermissions() throws Exception {
assumeFalse(Functions.isWindows());
File f = temp.newFolder("folder");
File f = newFolder(temp, "folder");
FilePath fp = new FilePath(f);
int invalidMode = 01770; // Full permissions for owner and group plus sticky bit.
final IOException e = assertThrows("Setting sticky bit should fail", IOException.class, () -> chmodAndMode(fp, invalidMode));
final IOException e = assertThrows(IOException.class, () -> chmodAndMode(fp, invalidMode), "Setting sticky bit should fail");
assertEquals("Invalid mode: " + invalidMode, e.getMessage());
}
@ -845,41 +916,42 @@ public class FilePathTest {
@Issue("JENKINS-48227")
@Test
public void testCreateTempDir() throws IOException, InterruptedException {
final File srcFolder = temp.newFolder("src");
void testCreateTempDir() throws IOException, InterruptedException {
final File srcFolder = newFolder(temp, "src");
final FilePath filePath = new FilePath(srcFolder);
FilePath x = filePath.createTempDir("jdk", "dmg");
FilePath y = filePath.createTempDir("jdk", "pkg");
FilePath z = filePath.createTempDir("jdk", null);
assertNotNull("FilePath x should not be null", x);
assertNotNull("FilePath y should not be null", y);
assertNotNull("FilePath z should not be null", z);
assertNotNull(x, "FilePath x should not be null");
assertNotNull(y, "FilePath y should not be null");
assertNotNull(z, "FilePath z should not be null");
assertTrue(x.getName().contains("jdk.dmg"));
assertTrue(y.getName().contains("jdk.pkg"));
assertTrue(z.getName().contains("jdk.tmp"));
}
@Test public void deleteRecursiveOnUnix() throws Exception {
@Test
void deleteRecursiveOnUnix() throws Exception {
assumeFalse(Functions.isWindows());
Path targetDir = temp.newFolder("target").toPath();
Path targetDir = newFolder(temp, "target").toPath();
Path targetContents = Files.createFile(targetDir.resolve("contents.txt"));
Path toDelete = temp.newFolder("toDelete").toPath();
Path toDelete = newFolder(temp, "toDelete").toPath();
Util.createSymlink(toDelete.toFile(), "../targetDir", "link", TaskListener.NULL);
Files.createFile(toDelete.resolve("foo"));
Files.createFile(toDelete.resolve("bar"));
FilePath f = new FilePath(toDelete.toFile());
f.deleteRecursive();
assertTrue("symlink target should not be deleted", Files.exists(targetDir));
assertTrue("symlink target contents should not be deleted", Files.exists(targetContents));
assertFalse("could not delete target", Files.exists(toDelete));
assertTrue(Files.exists(targetDir), "symlink target should not be deleted");
assertTrue(Files.exists(targetContents), "symlink target contents should not be deleted");
assertFalse(Files.exists(toDelete), "could not delete target");
}
@Test
@Issue("JENKINS-44909")
public void deleteSuffixesRecursive() throws Exception {
File deleteSuffixesRecursiveFolder = temp.newFolder("deleteSuffixesRecursive");
void deleteSuffixesRecursive() throws Exception {
File deleteSuffixesRecursiveFolder = newFolder(temp, "deleteSuffixesRecursive");
FilePath filePath = new FilePath(deleteSuffixesRecursiveFolder);
FilePath suffix = filePath.withSuffix(WorkspaceList.COMBINATOR + "suffixed");
FilePath textTempFile = suffix.createTextTempFile("tmp", null, "dummy", true);
@ -890,55 +962,58 @@ public class FilePathTest {
assertThat(textTempFile.exists(), is(false));
}
@Test public void deleteRecursiveOnWindows() throws Exception {
assumeTrue("Uses Windows-specific features", Functions.isWindows());
Path targetDir = temp.newFolder("targetDir").toPath();
@Test
void deleteRecursiveOnWindows() throws Exception {
assumeTrue(Functions.isWindows(), "Uses Windows-specific features");
Path targetDir = newFolder(temp, "targetDir").toPath();
Path targetContents = Files.createFile(targetDir.resolve("contents.txt"));
Path toDelete = temp.newFolder("toDelete").toPath();
Path toDelete = newFolder(temp, "toDelete").toPath();
File junction = WindowsUtil.createJunction(toDelete.resolve("junction").toFile(), targetDir.toFile());
Files.createFile(toDelete.resolve("foo"));
Files.createFile(toDelete.resolve("bar"));
FilePath f = new FilePath(toDelete.toFile());
f.deleteRecursive();
assertTrue("junction target should not be deleted", Files.exists(targetDir));
assertTrue("junction target contents should not be deleted", Files.exists(targetContents));
assertFalse("could not delete junction", junction.exists());
assertFalse("could not delete target", Files.exists(toDelete));
assertTrue(Files.exists(targetDir), "junction target should not be deleted");
assertTrue(Files.exists(targetContents), "junction target contents should not be deleted");
assertFalse(junction.exists(), "could not delete junction");
assertFalse(Files.exists(toDelete), "could not delete target");
}
@Issue("JENKINS-13128")
@Test public void copyRecursivePreservesPosixFilePermissions() throws Exception {
@Test
void copyRecursivePreservesPosixFilePermissions() throws Exception {
assumeFalse(Functions.isWindows());
File src = temp.newFolder("src");
File dst = temp.newFolder("dst");
File src = newFolder(temp, "src");
File dst = newFolder(temp, "dst");
Path sourceFile = Files.createFile(src.toPath().resolve("test-file"));
Set<PosixFilePermission> allRWX = EnumSet.allOf(PosixFilePermission.class);
Files.setPosixFilePermissions(sourceFile, allRWX);
FilePath f = new FilePath(src);
f.copyRecursiveTo(new FilePath(dst));
Path destinationFile = dst.toPath().resolve("test-file");
assertTrue("file was not copied", Files.exists(destinationFile));
assertTrue(Files.exists(destinationFile), "file was not copied");
Set<PosixFilePermission> destinationPermissions = Files.getPosixFilePermissions(destinationFile);
assertEquals("file permissions not copied", allRWX, destinationPermissions);
assertEquals(allRWX, destinationPermissions, "file permissions not copied");
}
@Issue("JENKINS-13128")
@Test public void copyRecursivePreservesLastModifiedTime() throws Exception {
File src = temp.newFolder("src");
File dst = temp.newFolder("dst");
@Test
void copyRecursivePreservesLastModifiedTime() throws Exception {
File src = newFolder(temp, "src");
File dst = newFolder(temp, "dst");
Path sourceFile = Files.createFile(src.toPath().resolve("test-file"));
FileTime mtime = FileTime.from(42L, TimeUnit.SECONDS);
Files.setLastModifiedTime(sourceFile, mtime);
FilePath f = new FilePath(src);
f.copyRecursiveTo(new FilePath(dst));
Path destinationFile = dst.toPath().resolve("test-file");
assertTrue("file was not copied", Files.exists(destinationFile));
assertEquals("file mtime was not preserved", mtime, Files.getLastModifiedTime(destinationFile));
assertTrue(Files.exists(destinationFile), "file was not copied");
assertEquals(mtime, Files.getLastModifiedTime(destinationFile), "file mtime was not preserved");
}
@Test
@Issue("SECURITY-904")
public void isDescendant_regularFiles() throws IOException, InterruptedException {
void isDescendant_regularFiles() throws IOException, InterruptedException {
// root
// /workspace
// /sub
@ -946,7 +1021,7 @@ public class FilePathTest {
// regular.txt
// /protected
// secret.txt
FilePath rootFolder = new FilePath(temp.newFolder("root"));
FilePath rootFolder = new FilePath(newFolder(temp, "root"));
FilePath workspaceFolder = rootFolder.child("workspace");
FilePath subFolder = workspaceFolder.child("sub");
FilePath protectedFolder = rootFolder.child("protected");
@ -988,7 +1063,7 @@ public class FilePathTest {
@Test
@Issue("SECURITY-904")
public void isDescendant_regularSymlinks() throws IOException, InterruptedException {
void isDescendant_regularSymlinks() throws IOException, InterruptedException {
assumeFalse(Functions.isWindows());
// root
// /workspace
@ -1004,7 +1079,7 @@ public class FilePathTest {
// _secrettxt => symlink to ../protected/secret.txt (illegal)
// /protected
// secret.txt
FilePath rootFolder = new FilePath(temp.newFolder("root"));
FilePath rootFolder = new FilePath(newFolder(temp, "root"));
FilePath workspaceFolder = rootFolder.child("workspace");
FilePath aFolder = workspaceFolder.child("a");
FilePath bFolder = workspaceFolder.child("b");
@ -1052,7 +1127,7 @@ public class FilePathTest {
@Test
@Issue("SECURITY-904")
public void isDescendant_windowsSpecificSymlinks() throws Exception {
void isDescendant_windowsSpecificSymlinks() throws Exception {
assumeTrue(Functions.isWindows());
// root
// /workspace
@ -1067,7 +1142,7 @@ public class FilePathTest {
// _protected => junction to ../protected (illegal)
// /protected
// secret.txt
File root = temp.newFolder("root");
File root = newFolder(temp, "root");
FilePath rootFolder = new FilePath(root);
FilePath workspaceFolder = rootFolder.child("workspace");
FilePath aFolder = workspaceFolder.child("a");
@ -1118,7 +1193,7 @@ public class FilePathTest {
@Issue("SECURITY-904")
public void isDescendant_throwIfParentDoesNotExist_symlink() throws Exception {
assumeFalse(Functions.isWindows());
FilePath rootFolder = new FilePath(temp.newFolder("root"));
FilePath rootFolder = new FilePath(newFolder(temp, "root"));
FilePath aFolder = rootFolder.child("a");
aFolder.mkdirs();
FilePath linkToNonexistent = aFolder.child("linkToNonexistent");
@ -1129,22 +1204,22 @@ public class FilePathTest {
@Issue("SECURITY-904")
public void isDescendant_throwIfParentDoesNotExist_directNonexistent() throws Exception {
FilePath rootFolder = new FilePath(temp.newFolder("root"));
FilePath rootFolder = new FilePath(newFolder(temp, "root"));
FilePath nonexistent = rootFolder.child("nonexistent");
assertThat(nonexistent.isDescendant("."), is(false));
}
@Test
@Issue("SECURITY-904")
public void isDescendant_throwIfAbsolutePathGiven() throws Exception {
FilePath rootFolder = new FilePath(temp.newFolder("root"));
void isDescendant_throwIfAbsolutePathGiven() throws Exception {
FilePath rootFolder = new FilePath(newFolder(temp, "root"));
rootFolder.mkdirs();
assertThrows(IllegalArgumentException.class, () -> rootFolder.isDescendant(temp.newFile().getAbsolutePath()));
assertThrows(IllegalArgumentException.class, () -> rootFolder.isDescendant(File.createTempFile("junit", null, temp).getAbsolutePath()));
}
@Test
@Issue("SECURITY-904")
public void isDescendant_worksEvenInSymbolicWorkspace() throws Exception {
void isDescendant_worksEvenInSymbolicWorkspace() throws Exception {
assumeFalse(Functions.isWindows());
// root
// /w
@ -1162,7 +1237,7 @@ public class FilePathTest {
// _secrettxt => symlink to ../protected/secret.txt (illegal)
// /protected
// secret.txt
FilePath rootFolder = new FilePath(temp.newFolder("root"));
FilePath rootFolder = new FilePath(newFolder(temp, "root"));
FilePath workspaceFolder = rootFolder.child("workspace");
FilePath aFolder = workspaceFolder.child("a");
FilePath bFolder = workspaceFolder.child("b");
@ -1213,4 +1288,13 @@ public class FilePathTest {
assertFalse(symbolicWorkspace.isDescendant("./_secrettxt"));
assertFalse(symbolicWorkspace.isDescendant("_secrettxt2"));
}
private static File newFolder(File root, String... subDirs) throws IOException {
String subFolder = String.join("/", subDirs);
File result = new File(root, subFolder);
if (!result.mkdirs()) {
throw new IOException("Couldn't create folders " + root);
}
return result;
}
}

View File

@ -30,9 +30,9 @@ import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;
@ -56,17 +56,18 @@ import java.util.logging.LogRecord;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import jenkins.model.Jenkins;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.jvnet.hudson.test.Issue;
import org.kohsuke.stapler.Ancestor;
import org.kohsuke.stapler.Stapler;
import org.kohsuke.stapler.StaplerRequest2;
import org.mockito.MockedStatic;
public class FunctionsTest {
class FunctionsTest {
@Test
public void testGetActionUrl_absoluteUriWithAuthority() {
void testGetActionUrl_absoluteUriWithAuthority() {
String[] uris = {
"http://example.com/foo/bar",
"https://example.com/foo/bar",
@ -81,7 +82,7 @@ public class FunctionsTest {
@Test
@Issue("JENKINS-7725")
public void testGetActionUrl_absoluteUriWithoutAuthority() {
void testGetActionUrl_absoluteUriWithoutAuthority() {
String[] uris = {
"mailto:nobody@example.com",
"mailto:nobody@example.com?subject=hello",
@ -94,7 +95,7 @@ public class FunctionsTest {
}
@Test
public void testGetActionUrl_absolutePath() {
void testGetActionUrl_absolutePath() {
String contextPath = "/jenkins";
StaplerRequest2 req = createMockRequest(contextPath);
String[] paths = {
@ -112,7 +113,7 @@ public class FunctionsTest {
}
@Test
public void testGetActionUrl_relativePath() {
void testGetActionUrl_relativePath() {
String contextPath = "/jenkins";
String itUrl = "iturl/";
StaplerRequest2 req = createMockRequest(contextPath);
@ -131,7 +132,7 @@ public class FunctionsTest {
}
@Test
public void testGetRelativeLinkTo_JobContainedInView() {
void testGetRelativeLinkTo_JobContainedInView() {
String contextPath = "/jenkins";
StaplerRequest2 req = createMockRequest(contextPath);
try (
@ -153,7 +154,7 @@ public class FunctionsTest {
}
@Test
public void testGetRelativeLinkTo_JobFromComputer() {
void testGetRelativeLinkTo_JobFromComputer() {
String contextPath = "/jenkins";
StaplerRequest2 req = createMockRequest(contextPath);
try (
@ -171,9 +172,9 @@ public class FunctionsTest {
}
}
@Ignore("too expensive to make it correct")
@Disabled("too expensive to make it correct")
@Test
public void testGetRelativeLinkTo_JobNotContainedInView() {
void testGetRelativeLinkTo_JobNotContainedInView() {
String contextPath = "/jenkins";
StaplerRequest2 req = createMockRequest(contextPath);
try (
@ -196,7 +197,7 @@ public class FunctionsTest {
private interface TopLevelItemAndItemGroup<T extends TopLevelItem> extends TopLevelItem, ItemGroup<T>, ViewGroup {}
@Test
public void testGetRelativeLinkTo_JobContainedInViewWithinItemGroup() {
void testGetRelativeLinkTo_JobContainedInViewWithinItemGroup() {
String contextPath = "/jenkins";
StaplerRequest2 req = createMockRequest(contextPath);
try (
@ -219,7 +220,8 @@ public class FunctionsTest {
}
@Issue("JENKINS-17713")
@Test public void getRelativeLinkTo_MavenModules() {
@Test
void getRelativeLinkTo_MavenModules() {
StaplerRequest2 req = createMockRequest("/jenkins");
try (
MockedStatic<Stapler> mocked = mockStatic(Stapler.class);
@ -239,7 +241,7 @@ public class FunctionsTest {
}
@Test
public void testGetRelativeDisplayName() {
void testGetRelativeDisplayName() {
Item i = mock(Item.class);
when(i.getName()).thenReturn("jobName");
when(i.getFullDisplayName()).thenReturn("displayName");
@ -247,7 +249,7 @@ public class FunctionsTest {
}
@Test
public void testGetRelativeDisplayNameInsideItemGroup() {
void testGetRelativeDisplayNameInsideItemGroup() {
Item i = mock(Item.class);
when(i.getName()).thenReturn("jobName");
when(i.getDisplayName()).thenReturn("displayName");
@ -297,7 +299,7 @@ public class FunctionsTest {
}
@Test
public void testGetActionUrl_unparseable() {
void testGetActionUrl_unparseable() {
assertNull(Functions.getActionUrl(null, createMockAction("http://example.net/stuff?something=^woohoo")));
}
@ -315,7 +317,7 @@ public class FunctionsTest {
@Test
@Issue("JENKINS-16630")
public void testHumanReadableFileSize() {
void testHumanReadableFileSize() {
Locale defaultLocale = Locale.getDefault();
try {
Locale.setDefault(Locale.ENGLISH);
@ -335,7 +337,7 @@ public class FunctionsTest {
@Issue("JENKINS-17030")
@Test
public void testBreakableString() {
void testBreakableString() {
assertBrokenAs("Hello world!", "Hello world!");
assertBrokenAs("Hello-world!", "Hello", "-world!");
@ -363,110 +365,129 @@ public class FunctionsTest {
}
@Issue("JENKINS-20800")
@Test public void printLogRecordHtml() {
@Test
void printLogRecordHtml() {
LogRecord lr = new LogRecord(Level.INFO, "Bad input <xml/>");
lr.setLoggerName("test");
assertEquals("Bad input &lt;xml/&gt;\n", Functions.printLogRecordHtml(lr, null)[3]);
}
@Test public void printLogRecordHtmlNoLogger() {
@Test
void printLogRecordHtmlNoLogger() {
LogRecord lr = new LogRecord(Level.INFO, "<discarded/>");
assertEquals("&lt;discarded/&gt;\n", Functions.printLogRecordHtml(lr, null)[3]);
}
@Test
public void extractPluginNameFromIconSrcHandlesNull() {
void extractPluginNameFromIconSrcHandlesNull() {
String result = Functions.extractPluginNameFromIconSrc(null);
assertThat(result, is(emptyString()));
}
@Test
public void extractPluginNameFromIconSrcHandlesEmptyString() {
void extractPluginNameFromIconSrcHandlesEmptyString() {
String result = Functions.extractPluginNameFromIconSrc("");
assertThat(result, is(emptyString()));
}
@Test
public void extractPluginNameFromIconSrcOnlyReturnsPluginFromStart() {
void extractPluginNameFromIconSrcOnlyReturnsPluginFromStart() {
String result = Functions.extractPluginNameFromIconSrc("symbol-plugin-mailer plugin-design-library");
assertThat(result, is(equalTo("design-library")));
}
@Test
public void extractPluginNameFromIconSrcExtractsPlugin() {
void extractPluginNameFromIconSrcExtractsPlugin() {
String result = Functions.extractPluginNameFromIconSrc("symbol-padlock plugin-design-library");
assertThat(result, is(equalTo("design-library")));
}
@Test
public void extractPluginNameFromIconSrcWhichContainsPluginWordInThePluginName() {
void extractPluginNameFromIconSrcWhichContainsPluginWordInThePluginName() {
String result = Functions.extractPluginNameFromIconSrc("symbol-padlock plugin-design-library-plugin");
assertThat(result, is(equalTo("design-library-plugin")));
}
@Issue("JDK-6507809")
@Test public void printThrowable() {
@Test
void printThrowable() {
// Basics: a single exception. No change.
assertPrintThrowable(new Stack("java.lang.NullPointerException: oops", "p.C.method1:17", "m.Main.main:1"),
"java.lang.NullPointerException: oops\n" +
"\tat p.C.method1(C.java:17)\n" +
"\tat m.Main.main(Main.java:1)\n",
"java.lang.NullPointerException: oops\n" +
"\tat p.C.method1(C.java:17)\n" +
"\tat m.Main.main(Main.java:1)\n");
"""
java.lang.NullPointerException: oops
\tat p.C.method1(C.java:17)
\tat m.Main.main(Main.java:1)
""",
"""
java.lang.NullPointerException: oops
\tat p.C.method1(C.java:17)
\tat m.Main.main(Main.java:1)
""");
// try {} catch (Exception x) {throw new IllegalStateException(x);}
assertPrintThrowable(new Stack("java.lang.IllegalStateException: java.lang.NullPointerException: oops", "p.C.method1:19", "m.Main.main:1").
cause(new Stack("java.lang.NullPointerException: oops", "p.C.method2:23", "p.C.method1:17", "m.Main.main:1")),
"java.lang.IllegalStateException: java.lang.NullPointerException: oops\n" +
"\tat p.C.method1(C.java:19)\n" +
"\tat m.Main.main(Main.java:1)\n" +
"Caused by: java.lang.NullPointerException: oops\n" +
"\tat p.C.method2(C.java:23)\n" +
"\tat p.C.method1(C.java:17)\n" +
"\t... 1 more\n",
"java.lang.NullPointerException: oops\n" +
"\tat p.C.method2(C.java:23)\n" +
"\tat p.C.method1(C.java:17)\n" +
"Caused: java.lang.IllegalStateException\n" +
"\tat p.C.method1(C.java:19)\n" +
"\tat m.Main.main(Main.java:1)\n");
"""
java.lang.IllegalStateException: java.lang.NullPointerException: oops
\tat p.C.method1(C.java:19)
\tat m.Main.main(Main.java:1)
Caused by: java.lang.NullPointerException: oops
\tat p.C.method2(C.java:23)
\tat p.C.method1(C.java:17)
\t... 1 more
""",
"""
java.lang.NullPointerException: oops
\tat p.C.method2(C.java:23)
\tat p.C.method1(C.java:17)
Caused: java.lang.IllegalStateException
\tat p.C.method1(C.java:19)
\tat m.Main.main(Main.java:1)
""");
// try {} catch (Exception x) {throw new IllegalStateException("more info");}
assertPrintThrowable(new Stack("java.lang.IllegalStateException: more info", "p.C.method1:19", "m.Main.main:1").
cause(new Stack("java.lang.NullPointerException: oops", "p.C.method2:23", "p.C.method1:17", "m.Main.main:1")),
"java.lang.IllegalStateException: more info\n" +
"\tat p.C.method1(C.java:19)\n" +
"\tat m.Main.main(Main.java:1)\n" +
"Caused by: java.lang.NullPointerException: oops\n" +
"\tat p.C.method2(C.java:23)\n" +
"\tat p.C.method1(C.java:17)\n" +
"\t... 1 more\n",
"java.lang.NullPointerException: oops\n" +
"\tat p.C.method2(C.java:23)\n" +
"\tat p.C.method1(C.java:17)\n" +
"Caused: java.lang.IllegalStateException: more info\n" +
"\tat p.C.method1(C.java:19)\n" +
"\tat m.Main.main(Main.java:1)\n");
"""
java.lang.IllegalStateException: more info
\tat p.C.method1(C.java:19)
\tat m.Main.main(Main.java:1)
Caused by: java.lang.NullPointerException: oops
\tat p.C.method2(C.java:23)
\tat p.C.method1(C.java:17)
\t... 1 more
""",
"""
java.lang.NullPointerException: oops
\tat p.C.method2(C.java:23)
\tat p.C.method1(C.java:17)
Caused: java.lang.IllegalStateException: more info
\tat p.C.method1(C.java:19)
\tat m.Main.main(Main.java:1)
""");
// try {} catch (Exception x) {throw new IllegalStateException("more info: " + x);}
assertPrintThrowable(new Stack("java.lang.IllegalStateException: more info: java.lang.NullPointerException: oops", "p.C.method1:19", "m.Main.main:1").
cause(new Stack("java.lang.NullPointerException: oops", "p.C.method2:23", "p.C.method1:17", "m.Main.main:1")),
"java.lang.IllegalStateException: more info: java.lang.NullPointerException: oops\n" +
"\tat p.C.method1(C.java:19)\n" +
"\tat m.Main.main(Main.java:1)\n" +
"Caused by: java.lang.NullPointerException: oops\n" +
"\tat p.C.method2(C.java:23)\n" +
"\tat p.C.method1(C.java:17)\n" +
"\t... 1 more\n",
"java.lang.NullPointerException: oops\n" +
"\tat p.C.method2(C.java:23)\n" +
"\tat p.C.method1(C.java:17)\n" +
"Caused: java.lang.IllegalStateException: more info\n" +
"\tat p.C.method1(C.java:19)\n" +
"\tat m.Main.main(Main.java:1)\n");
"""
java.lang.IllegalStateException: more info: java.lang.NullPointerException: oops
\tat p.C.method1(C.java:19)
\tat m.Main.main(Main.java:1)
Caused by: java.lang.NullPointerException: oops
\tat p.C.method2(C.java:23)
\tat p.C.method1(C.java:17)
\t... 1 more
""",
"""
java.lang.NullPointerException: oops
\tat p.C.method2(C.java:23)
\tat p.C.method1(C.java:17)
Caused: java.lang.IllegalStateException: more info
\tat p.C.method1(C.java:19)
\tat m.Main.main(Main.java:1)
""");
// Synthetic stack showing an exception made elsewhere, such as happens with hudson.remoting.Channel.attachCallSiteStackTrace.
Throwable t = new Stack("remote.Exception: oops", "remote.Place.method:17", "remote.Service.run:9");
StackTraceElement[] callSite = new Stack("wrapped.Exception", "local.Side.call:11", "local.Main.main:1").getStackTrace();
@ -477,18 +498,22 @@ public class FunctionsTest {
System.arraycopy(callSite, 0, combined, original.length + 1, callSite.length);
t.setStackTrace(combined);
assertPrintThrowable(t,
"remote.Exception: oops\n" +
"\tat remote.Place.method(Place.java:17)\n" +
"\tat remote.Service.run(Service.java:9)\n" +
"\tat ......remote call(Native Method)\n" +
"\tat local.Side.call(Side.java:11)\n" +
"\tat local.Main.main(Main.java:1)\n",
"remote.Exception: oops\n" +
"\tat remote.Place.method(Place.java:17)\n" +
"\tat remote.Service.run(Service.java:9)\n" +
"\tat ......remote call(Native Method)\n" +
"\tat local.Side.call(Side.java:11)\n" +
"\tat local.Main.main(Main.java:1)\n");
"""
remote.Exception: oops
\tat remote.Place.method(Place.java:17)
\tat remote.Service.run(Service.java:9)
\tat ......remote call(Native Method)
\tat local.Side.call(Side.java:11)
\tat local.Main.main(Main.java:1)
""",
"""
remote.Exception: oops
\tat remote.Place.method(Place.java:17)
\tat remote.Service.run(Service.java:9)
\tat ......remote call(Native Method)
\tat local.Side.call(Side.java:11)
\tat local.Main.main(Main.java:1)
""");
// Same but now using a cause on the remote side.
t = new Stack("remote.Wrapper: remote.Exception: oops", "remote.Place.method2:19", "remote.Service.run:9").cause(new Stack("remote.Exception: oops", "remote.Place.method1:11", "remote.Place.method2:17", "remote.Service.run:9"));
callSite = new Stack("wrapped.Exception", "local.Side.call:11", "local.Main.main:1").getStackTrace();
@ -499,16 +524,18 @@ public class FunctionsTest {
System.arraycopy(callSite, 0, combined, original.length + 1, callSite.length);
t.setStackTrace(combined);
assertPrintThrowable(t,
"remote.Wrapper: remote.Exception: oops\n" +
"\tat remote.Place.method2(Place.java:19)\n" +
"\tat remote.Service.run(Service.java:9)\n" +
"\tat ......remote call(Native Method)\n" +
"\tat local.Side.call(Side.java:11)\n" +
"\tat local.Main.main(Main.java:1)\n" +
"Caused by: remote.Exception: oops\n" +
"\tat remote.Place.method1(Place.java:11)\n" +
"\tat remote.Place.method2(Place.java:17)\n" +
"\tat remote.Service.run(Service.java:9)\n",
"""
remote.Wrapper: remote.Exception: oops
\tat remote.Place.method2(Place.java:19)
\tat remote.Service.run(Service.java:9)
\tat ......remote call(Native Method)
\tat local.Side.call(Side.java:11)
\tat local.Main.main(Main.java:1)
Caused by: remote.Exception: oops
\tat remote.Place.method1(Place.java:11)
\tat remote.Place.method2(Place.java:17)
\tat remote.Service.run(Service.java:9)
""",
"remote.Exception: oops\n" +
"\tat remote.Place.method1(Place.java:11)\n" +
"\tat remote.Place.method2(Place.java:17)\n" +
@ -525,40 +552,44 @@ public class FunctionsTest {
suppressed(new Stack("java.io.IOException: could not close", "p.C.close:99", "p.C.method1:18", "m.Main.main:1"),
new Stack("java.io.IOException: java.lang.NullPointerException", "p.C.flush:77", "p.C.method1:18", "m.Main.main:1").
cause(new Stack("java.lang.NullPointerException", "p.C.findFlushee:70", "p.C.flush:75", "p.C.method1:18", "m.Main.main:1"))),
"java.lang.IllegalStateException: java.lang.NullPointerException: oops\n" +
"\tat p.C.method1(C.java:19)\n" +
"\tat m.Main.main(Main.java:1)\n" +
"\tSuppressed: java.io.IOException: could not close\n" +
"\t\tat p.C.close(C.java:99)\n" +
"\t\tat p.C.method1(C.java:18)\n" +
"\t\t... 1 more\n" +
"\tSuppressed: java.io.IOException: java.lang.NullPointerException\n" +
"\t\tat p.C.flush(C.java:77)\n" +
"\t\tat p.C.method1(C.java:18)\n" +
"\t\t... 1 more\n" +
"\tCaused by: java.lang.NullPointerException\n" +
"\t\tat p.C.findFlushee(C.java:70)\n" +
"\t\tat p.C.flush(C.java:75)\n" +
"\t\t... 2 more\n" +
"Caused by: java.lang.NullPointerException: oops\n" +
"\tat p.C.method2(C.java:23)\n" +
"\tat p.C.method1(C.java:17)\n" +
"\t... 1 more\n",
"java.lang.NullPointerException: oops\n" +
"\tat p.C.method2(C.java:23)\n" +
"\tat p.C.method1(C.java:17)\n" +
"Also: java.io.IOException: could not close\n" +
"\t\tat p.C.close(C.java:99)\n" +
"\t\tat p.C.method1(C.java:18)\n" +
"Also: java.lang.NullPointerException\n" +
"\t\tat p.C.findFlushee(C.java:70)\n" +
"\t\tat p.C.flush(C.java:75)\n" +
"\tCaused: java.io.IOException\n" +
"\t\tat p.C.flush(C.java:77)\n" +
"\t\tat p.C.method1(C.java:18)\n" +
"Caused: java.lang.IllegalStateException\n" +
"\tat p.C.method1(C.java:19)\n" +
"\tat m.Main.main(Main.java:1)\n");
"""
java.lang.IllegalStateException: java.lang.NullPointerException: oops
\tat p.C.method1(C.java:19)
\tat m.Main.main(Main.java:1)
\tSuppressed: java.io.IOException: could not close
\t\tat p.C.close(C.java:99)
\t\tat p.C.method1(C.java:18)
\t\t... 1 more
\tSuppressed: java.io.IOException: java.lang.NullPointerException
\t\tat p.C.flush(C.java:77)
\t\tat p.C.method1(C.java:18)
\t\t... 1 more
\tCaused by: java.lang.NullPointerException
\t\tat p.C.findFlushee(C.java:70)
\t\tat p.C.flush(C.java:75)
\t\t... 2 more
Caused by: java.lang.NullPointerException: oops
\tat p.C.method2(C.java:23)
\tat p.C.method1(C.java:17)
\t... 1 more
""",
"""
java.lang.NullPointerException: oops
\tat p.C.method2(C.java:23)
\tat p.C.method1(C.java:17)
Also: java.io.IOException: could not close
\t\tat p.C.close(C.java:99)
\t\tat p.C.method1(C.java:18)
Also: java.lang.NullPointerException
\t\tat p.C.findFlushee(C.java:70)
\t\tat p.C.flush(C.java:75)
\tCaused: java.io.IOException
\t\tat p.C.flush(C.java:77)
\t\tat p.C.method1(C.java:18)
Caused: java.lang.IllegalStateException
\tat p.C.method1(C.java:19)
\tat m.Main.main(Main.java:1)
""");
// Custom printStackTrace implementations:
assertPrintThrowable(new Throwable() {
@Override
@ -576,28 +607,36 @@ public class FunctionsTest {
if (getVersion().isNewerThanOrEqualTo(new VersionNumber("11.0.9")) ||
(getVersion().getDigitAt(0) == 8 && getVersion().isNewerThanOrEqualTo(new VersionNumber("8.0.272")))) {
assertPrintThrowable(stack1,
"p.Exc1\n" +
"\tat p.C.method1(C.java:17)\n" +
"Caused by: p.Exc2\n" +
"\tat p.C.method2(C.java:27)\n" +
"Caused by: [CIRCULAR REFERENCE: p.Exc1]\n",
"<cycle to p.Exc1>\n" +
"Caused: p.Exc2\n" +
"\tat p.C.method2(C.java:27)\n" +
"Caused: p.Exc1\n" +
"\tat p.C.method1(C.java:17)\n");
"""
p.Exc1
\tat p.C.method1(C.java:17)
Caused by: p.Exc2
\tat p.C.method2(C.java:27)
Caused by: [CIRCULAR REFERENCE: p.Exc1]
""",
"""
<cycle to p.Exc1>
Caused: p.Exc2
\tat p.C.method2(C.java:27)
Caused: p.Exc1
\tat p.C.method1(C.java:17)
""");
} else {
assertPrintThrowable(stack1,
"p.Exc1\n" +
"\tat p.C.method1(C.java:17)\n" +
"Caused by: p.Exc2\n" +
"\tat p.C.method2(C.java:27)\n" +
"\t[CIRCULAR REFERENCE:p.Exc1]\n",
"<cycle to p.Exc1>\n" +
"Caused: p.Exc2\n" +
"\tat p.C.method2(C.java:27)\n" +
"Caused: p.Exc1\n" +
"\tat p.C.method1(C.java:17)\n");
"""
p.Exc1
\tat p.C.method1(C.java:17)
Caused by: p.Exc2
\tat p.C.method2(C.java:27)
\t[CIRCULAR REFERENCE:p.Exc1]
""",
"""
<cycle to p.Exc1>
Caused: p.Exc2
\tat p.C.method2(C.java:27)
Caused: p.Exc1
\tat p.C.method1(C.java:17)
""");
}
}
@ -651,42 +690,42 @@ public class FunctionsTest {
}
@Test
public void tryGetIcon_shouldReturnNullForNull() throws Exception {
void tryGetIcon_shouldReturnNullForNull() {
assertThat(Functions.tryGetIcon(null), is(nullValue()));
}
@Test
public void tryGetIcon_shouldReturnNullForSymbol() throws Exception {
void tryGetIcon_shouldReturnNullForSymbol() {
assertThat(Functions.tryGetIcon("symbol-search"), is(nullValue()));
}
@Test
public void tryGetIcon_shouldReturnMetadataForExactSpec() throws Exception {
void tryGetIcon_shouldReturnMetadataForExactSpec() {
assertThat(Functions.tryGetIcon("icon-help icon-sm"), is(not(nullValue())));
}
@Test
public void tryGetIcon_shouldReturnMetadataForExtraSpec() throws Exception {
void tryGetIcon_shouldReturnMetadataForExtraSpec() {
assertThat(Functions.tryGetIcon("icon-help icon-sm extra-class"), is(not(nullValue())));
}
@Test
public void tryGetIcon_shouldReturnMetadataForFilename() throws Exception {
void tryGetIcon_shouldReturnMetadataForFilename() {
assertThat(Functions.tryGetIcon("help.svg"), is(not(nullValue())));
}
@Test
public void tryGetIcon_shouldReturnMetadataForUrl() throws Exception {
void tryGetIcon_shouldReturnMetadataForUrl() {
assertThat(Functions.tryGetIcon("48x48/green.gif"), is(not(nullValue())));
}
@Test
public void tryGetIcon_shouldReturnNullForUnknown() throws Exception {
void tryGetIcon_shouldReturnNullForUnknown() {
assertThat(Functions.tryGetIcon("icon-nosuchicon"), is(nullValue()));
}
@Test
public void guessIcon() throws Exception {
void guessIcon() {
Jenkins.RESOURCE_PATH = "/static/12345678";
assertEquals("/jenkins/static/12345678/images/48x48/green.gif", Functions.guessIcon("jenkins/images/48x48/green.gif", "/jenkins"));
assertEquals("/jenkins/static/12345678/images/48x48/green.gif", Functions.guessIcon("/jenkins/images/48x48/green.gif", "/jenkins"));

View File

@ -40,10 +40,10 @@ import org.jvnet.hudson.test.Issue;
import org.kohsuke.stapler.StaplerRequest2;
import org.kohsuke.stapler.lang.Klass;
public class GetLocaleStaticHelpUrlTest {
class GetLocaleStaticHelpUrlTest {
@Test
public void getStaticHelpUrlAcceptEnResDefault() {
void getStaticHelpUrlAcceptEnResDefault() {
// Accept-Language: en
StaplerRequest2 req = mockStaplerRequest2(
Locale.ENGLISH
@ -58,7 +58,7 @@ public class GetLocaleStaticHelpUrlTest {
}
@Test
public void getStaticHelpUrlAcceptDeResDeNoCountry() {
void getStaticHelpUrlAcceptDeResDeNoCountry() {
// Accept-Language: de-DE,de;q=0.9,en;q=0.8
StaplerRequest2 req = mockStaplerRequest2(
Locale.GERMANY,
@ -76,7 +76,7 @@ public class GetLocaleStaticHelpUrlTest {
}
@Test
public void getStaticHelpUrlAcceptDeResDeCountry() {
void getStaticHelpUrlAcceptDeResDeCountry() {
// Accept-Language: de-DE,de;q=0.9,en;q=0.8
StaplerRequest2 req = mockStaplerRequest2(
Locale.GERMANY,
@ -94,7 +94,7 @@ public class GetLocaleStaticHelpUrlTest {
}
@Test
public void getStaticHelpUrlAcceptDeResBoth() {
void getStaticHelpUrlAcceptDeResBoth() {
// Accept-Language: de-DE,de;q=0.9,en;q=0.8
StaplerRequest2 req = mockStaplerRequest2(
Locale.GERMANY,
@ -113,7 +113,7 @@ public class GetLocaleStaticHelpUrlTest {
}
@Test
public void getStaticHelpUrlAcceptZhResDefault() {
void getStaticHelpUrlAcceptZhResDefault() {
// Accept-Language: zh,zh-CN;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6
StaplerRequest2 req = mockStaplerRequest2(
Locale.CHINESE,
@ -132,7 +132,7 @@ public class GetLocaleStaticHelpUrlTest {
}
@Test
public void getStaticHelpUrlAcceptZhResZhCountry() {
void getStaticHelpUrlAcceptZhResZhCountry() {
// Accept-Language: zh,zh-CN;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6
StaplerRequest2 req = mockStaplerRequest2(
Locale.CHINESE,
@ -152,7 +152,7 @@ public class GetLocaleStaticHelpUrlTest {
}
@Test
public void getStaticHelpUrlAcceptZhResBoth() {
void getStaticHelpUrlAcceptZhResBoth() {
// Accept-Language: zh,zh-CN;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6
StaplerRequest2 req = mockStaplerRequest2(
Locale.CHINESE,
@ -172,7 +172,7 @@ public class GetLocaleStaticHelpUrlTest {
}
@Test
public void getStaticHelpUrlAcceptZhResMore() {
void getStaticHelpUrlAcceptZhResMore() {
// Accept-Language: zh,zh-CN;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6
StaplerRequest2 req = mockStaplerRequest2(
Locale.CHINESE,
@ -194,7 +194,7 @@ public class GetLocaleStaticHelpUrlTest {
@Issue("JENKINS-73246")
@Test
public void getStaticHelpUrlAcceptEnFirst() {
void getStaticHelpUrlAcceptEnFirst() {
// Accept-Language: en-US,en;q=0.9,de;q=0.8
StaplerRequest2 req = mockStaplerRequest2(
Locale.US,

View File

@ -24,39 +24,85 @@
package hudson;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import hudson.model.StreamBuildListener;
import hudson.model.TaskListener;
import hudson.remoting.Channel;
import hudson.remoting.ChannelBuilder;
import hudson.remoting.FastPipedInputStream;
import hudson.remoting.FastPipedOutputStream;
import hudson.util.ProcessTree;
import hudson.util.StreamTaskListener;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import jenkins.security.MasterToSlaveCallable;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.jvnet.hudson.test.Issue;
public class LauncherTest {
class LauncherTest {
@Rule public ChannelRule channels = new ChannelRule();
@Rule public TemporaryFolder temp = new TemporaryFolder();
@TempDir
private File temp;
/**
* Two channels that are connected to each other, but shares the same classloader.
*/
private Channel french;
private Channel british;
private ExecutorService executors;
@BeforeEach
void setUp() throws Exception {
executors = Executors.newCachedThreadPool();
final FastPipedInputStream p1i = new FastPipedInputStream();
final FastPipedInputStream p2i = new FastPipedInputStream();
final FastPipedOutputStream p1o = new FastPipedOutputStream(p1i);
final FastPipedOutputStream p2o = new FastPipedOutputStream(p2i);
Future<Channel> f1 = executors.submit(() -> new ChannelBuilder("This side of the channel", executors).withMode(Channel.Mode.BINARY).build(p1i, p2o));
Future<Channel> f2 = executors.submit(() -> new ChannelBuilder("The other side of the channel", executors).withMode(Channel.Mode.BINARY).build(p2i, p1o));
french = f1.get();
british = f2.get();
}
@AfterEach
void tearDown() {
try {
french.close(); // this will automatically initiate the close on the other channel, too.
french.join();
british.join();
} catch (IOException e) {
throw new UncheckedIOException(e);
} catch (InterruptedException x) {
throw new AssertionError(x);
}
executors.shutdownNow();
}
@Issue("JENKINS-4611")
@Test public void remoteKill() throws Exception {
@Test
void remoteKill() throws Exception {
assumeFalse(Functions.isWindows());
File tmp = temp.newFile();
File tmp = File.createTempFile("junit", null, temp);
FilePath f = new FilePath(channels.french, tmp.getPath());
FilePath f = new FilePath(french, tmp.getPath());
Launcher l = f.createLauncher(StreamTaskListener.fromStderr());
Proc p = l.launch().cmds("sh", "-c", "echo $$$$ > " + tmp + "; sleep 30").stdout(System.out).stderr(System.err).start();
while (!tmp.exists())
@ -66,10 +112,10 @@ public class LauncherTest {
assertNotEquals(0, p.join());
long end = System.currentTimeMillis();
long terminationTime = end - start;
assertTrue("Join did not finish promptly. The completion time (" + terminationTime + "ms) is longer than expected 15s", terminationTime < 15000);
channels.french.call(new NoopCallable()); // this only returns after the other side of the channel has finished executing cancellation
assertTrue(terminationTime < 15000, "Join did not finish promptly. The completion time (" + terminationTime + "ms) is longer than expected 15s");
french.call(new NoopCallable()); // this only returns after the other side of the channel has finished executing cancellation
Thread.sleep(2000); // more delay to make sure it's gone
assertNull("process should be gone", ProcessTree.get().get(Integer.parseInt(Files.readString(tmp.toPath(), Charset.defaultCharset()).trim())));
assertNull(ProcessTree.get().get(Integer.parseInt(Files.readString(tmp.toPath(), Charset.defaultCharset()).trim())), "process should be gone");
// Manual version of test: set up instance w/ one agent. Now in script console
// new hudson.FilePath(new java.io.File("/tmp")).createLauncher(new hudson.util.StreamTaskListener(System.err)).
@ -88,7 +134,8 @@ public class LauncherTest {
}
@Issue("JENKINS-15733")
@Test public void decorateByEnv() throws Exception {
@Test
void decorateByEnv() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
TaskListener l = new StreamBuildListener(baos, Charset.defaultCharset());
Launcher base = new Launcher.LocalLauncher(l);
@ -96,12 +143,13 @@ public class LauncherTest {
Launcher decorated = base.decorateByEnv(env);
int res = decorated.launch().envs("key2=val2").cmds(Functions.isWindows() ? new String[] {"cmd", "/q", "/c", "echo %key1% %key2%"} : new String[] {"sh", "-c", "echo $key1 $key2"}).stdout(l).join();
String log = baos.toString(Charset.defaultCharset());
assertEquals(log, 0, res);
assertTrue(log, log.contains("val1 val2"));
assertEquals(0, res, log);
assertTrue(log.contains("val1 val2"), log);
}
@Issue("JENKINS-18368")
@Test public void decoratedByEnvMaintainsIsUnix() {
@Test
void decoratedByEnvMaintainsIsUnix() {
ByteArrayOutputStream output = new ByteArrayOutputStream();
TaskListener listener = new StreamBuildListener(output, Charset.defaultCharset());
Launcher remoteLauncher = new Launcher.RemoteLauncher(listener, FilePath.localChannel, false);
@ -113,7 +161,8 @@ public class LauncherTest {
}
@Issue("JENKINS-18368")
@Test public void decoratedByPrefixMaintainsIsUnix() {
@Test
void decoratedByPrefixMaintainsIsUnix() {
ByteArrayOutputStream output = new ByteArrayOutputStream();
TaskListener listener = new StreamBuildListener(output, Charset.defaultCharset());
Launcher remoteLauncher = new Launcher.RemoteLauncher(listener, FilePath.localChannel, false);

View File

@ -34,10 +34,10 @@ import org.junit.jupiter.api.Test;
/**
* @author Kohsuke Kawaguchi
*/
public class MarkupTextTest {
class MarkupTextTest {
@Test
public void test1() {
void test1() {
MarkupText t = new MarkupText("I fixed issue #155. The rest is trick text: xissue #155 issue #123x");
for (SubText st : t.findTokens(pattern)) {
assertEquals(1, st.groupCount());
@ -48,7 +48,7 @@ public class MarkupTextTest {
}
@Test
public void boundary() {
void boundary() {
MarkupText t = new MarkupText("issue #155---issue #123");
for (SubText st : t.findTokens(pattern))
st.surroundWith("<$1>", "<$1>");
@ -57,7 +57,7 @@ public class MarkupTextTest {
}
@Test
public void findTokensOnSubText() {
void findTokensOnSubText() {
MarkupText t = new MarkupText("Fixed 2 issues in this commit, fixing issue 155, 145");
List<SubText> tokens = t.findTokens(Pattern.compile("issue .*"));
assertEquals(1, tokens.size(), "Expected one token");
@ -69,7 +69,7 @@ public class MarkupTextTest {
}
@Test
public void literalTextSurround() {
void literalTextSurround() {
MarkupText text = new MarkupText("AAA test AAA");
for (SubText token : text.findTokens(Pattern.compile("AAA"))) {
token.surroundWithLiteral("$9", "$9");
@ -81,7 +81,7 @@ public class MarkupTextTest {
* Start/end tag nesting should be correct regardless of the order tags are added.
*/
@Test
public void addMarkupInOrder() {
void addMarkupInOrder() {
MarkupText text = new MarkupText("abcdef");
text.addMarkup(0, 3, "$", "$");
text.addMarkup(3, 6, "#", "#");
@ -89,7 +89,7 @@ public class MarkupTextTest {
}
@Test
public void addMarkupInReversedOrder() {
void addMarkupInReversedOrder() {
MarkupText text = new MarkupText("abcdef");
text.addMarkup(3, 6, "#", "#");
text.addMarkup(0, 3, "$", "$");
@ -97,7 +97,7 @@ public class MarkupTextTest {
}
@Test
public void escape() {
void escape() {
MarkupText text = new MarkupText("&&&");
assertEquals("&amp;&amp;&amp;", text.toString(false));
@ -107,7 +107,7 @@ public class MarkupTextTest {
}
@Test
public void preEscape() {
void preEscape() {
MarkupText text = new MarkupText("Line\n2 & 3\n<End>\n");
assertEquals("Line\n2 &amp; 3\n&lt;End&gt;\n", text.toString(true));
text.addMarkup(4, "<hr/>");
@ -116,7 +116,7 @@ public class MarkupTextTest {
/* @Issue("JENKINS-6252") */
@Test
public void subTextSubText() {
void subTextSubText() {
MarkupText text = new MarkupText("abcdefgh");
SubText sub = text.subText(2, 7);
assertEquals("cdefg", sub.getText());

View File

@ -58,12 +58,13 @@ import org.xml.sax.SAXException;
/**
* Tests of {@link PluginManager}.
*/
public class PluginManagerTest {
class PluginManagerTest {
@TempDir Path tmp;
@TempDir
private Path tmp;
@Test
public void parseRequestedPlugins() throws Exception {
void parseRequestedPlugins() throws Exception {
Path output = Files.createFile(
tmp.resolve("output.txt")
);
@ -73,17 +74,19 @@ public class PluginManagerTest {
@Issue("SECURITY-167")
@Test
public void parseInvalidRequestedPlugins() throws Exception {
String evilXML = "<?xml version='1.0' encoding='UTF-8'?>\n" +
"<!DOCTYPE project[<!ENTITY foo SYSTEM \"file:///\">]>\n" +
"<root>\n" +
" <stuff plugin='stuff@1.0'>\n" +
"&foo;" +
" <more plugin='other@2.0'>\n" +
" <things plugin='stuff@1.2'/>\n" +
" </more>\n" +
" </stuff>\n" +
"</root>\n";
void parseInvalidRequestedPlugins() throws Exception {
String evilXML = """
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE project[<!ENTITY foo SYSTEM "file:///">]>
<root>
<stuff plugin='stuff@1.0'>
&foo;\
<more plugin='other@2.0'>
<things plugin='stuff@1.2'/>
</more>
</stuff>
</root>
""";
PluginManager pluginManager = new LocalPluginManager(Util.createTempDir());
final IOException ex = assertThrows(IOException.class,
@ -95,7 +98,7 @@ public class PluginManagerTest {
}
@Test
public void shouldProperlyParseManifestFromJar() throws IOException {
void shouldProperlyParseManifestFromJar() throws IOException {
File jar = createHpiWithManifest();
final Manifest manifest = PluginManager.parsePluginManifest(jar.toURI().toURL());
@ -112,7 +115,7 @@ public class PluginManagerTest {
}
@Test
public void shouldProperlyRetrieveModificationDate() throws IOException {
void shouldProperlyRetrieveModificationDate() throws IOException {
File jar = createHpiWithManifest();
URL url = toManifestUrl(jar);
assertThat("Manifest last modified date should be equal to the file date",
@ -123,7 +126,7 @@ public class PluginManagerTest {
@Test
@Issue("JENKINS-70420")
public void updateSiteURLCheckValidation() throws Exception {
void updateSiteURLCheckValidation() throws Exception {
LocalPluginManager pm = new LocalPluginManager(tmp.toFile());
assertThat("ftp urls are not acceptable", pm.checkUpdateSiteURL("ftp://foo/bar"),
@ -163,29 +166,30 @@ public class PluginManagerTest {
}
private static final String SAMPLE_MANIFEST_FILE = "Manifest-Version: 1.0\n" +
"Archiver-Version: Plexus Archiver\n" +
"Created-By: Apache Maven\n" +
"Built-By: jglick\n" +
"Build-Jdk: 1.8.0_92\n" +
"Extension-Name: matrix-auth\n" +
"Specification-Title: \n" +
" Offers matrix-based security \n" +
" authorization strate\n" +
" gies (global and per-project).\n" +
"Implementation-Title: matrix-auth\n" +
"Implementation-Version: 1.4\n" +
"Group-Id: org.jenkins-ci.plugins\n" +
"Short-Name: matrix-auth\n" +
"Long-Name: Matrix Authorization Strategy Plugin\n" +
"Url: http://wiki.jenkins-ci.org/display/JENKINS/Matrix+Authorization+S\n" +
" trategy+Plugin\n" +
"Plugin-Version: 1.4\n" +
"Hudson-Version: 1.609.1\n" +
"Jenkins-Version: 1.609.1\n" +
"Plugin-Dependencies: icon-shim:2.0.3,cloudbees-folder:5.2.2;resolution\n" +
" :=optional\n" +
"Plugin-Developers: ";
private static final String SAMPLE_MANIFEST_FILE = """
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: jglick
Build-Jdk: 1.8.0_92
Extension-Name: matrix-auth
Specification-Title:\s
Offers matrix-based security\s
authorization strate
gies (global and per-project).
Implementation-Title: matrix-auth
Implementation-Version: 1.4
Group-Id: org.jenkins-ci.plugins
Short-Name: matrix-auth
Long-Name: Matrix Authorization Strategy Plugin
Url: http://wiki.jenkins-ci.org/display/JENKINS/Matrix+Authorization+S
trategy+Plugin
Plugin-Version: 1.4
Hudson-Version: 1.609.1
Jenkins-Version: 1.609.1
Plugin-Dependencies: icon-shim:2.0.3,cloudbees-folder:5.2.2;resolution
:=optional
Plugin-Developers:\s""";
private File createHpiWithManifest() throws IOException {
Path metaInf = tmp.resolve("META-INF");

View File

@ -32,26 +32,26 @@ import org.junit.jupiter.api.Test;
import org.jvnet.hudson.test.Issue;
import org.mockito.stubbing.Answer;
public class PluginWrapperTest {
class PluginWrapperTest {
private static Locale loc;
@BeforeAll
public static void before() {
static void before() {
Jenkins.VERSION = "2.0"; // Some value needed - tests will overwrite if necessary
loc = Locale.getDefault();
Locale.setDefault(new Locale("en", "GB"));
}
@AfterAll
public static void after() {
static void after() {
if (loc != null) {
Locale.setDefault(loc);
}
}
@Test
public void dependencyTest() {
void dependencyTest() {
String version = "plugin:0.0.2";
PluginWrapper.Dependency dependency = new PluginWrapper.Dependency(version);
assertEquals("plugin", dependency.shortName);
@ -60,7 +60,7 @@ public class PluginWrapperTest {
}
@Test
public void optionalDependencyTest() {
void optionalDependencyTest() {
String version = "plugin:0.0.2;resolution:=optional";
PluginWrapper.Dependency dependency = new PluginWrapper.Dependency(version);
assertEquals("plugin", dependency.shortName);
@ -69,7 +69,7 @@ public class PluginWrapperTest {
}
@Test
public void jenkinsCoreTooOld() {
void jenkinsCoreTooOld() {
PluginWrapper pw = pluginWrapper("fake").requiredCoreVersion("3.0").buildLoaded();
final IOException ex = assertThrows(IOException.class, pw::resolvePluginDependencies);
@ -77,7 +77,7 @@ public class PluginWrapperTest {
}
@Test
public void dependencyNotInstalled() {
void dependencyNotInstalled() {
PluginWrapper pw = pluginWrapper("dependee").deps("dependency:42").buildLoaded();
final IOException ex = assertThrows(IOException.class, pw::resolvePluginDependencies);
@ -85,7 +85,7 @@ public class PluginWrapperTest {
}
@Test
public void dependencyOutdated() {
void dependencyOutdated() {
pluginWrapper("dependency").version("3").buildLoaded();
PluginWrapper pw = pluginWrapper("dependee").deps("dependency:5").buildLoaded();
@ -94,7 +94,7 @@ public class PluginWrapperTest {
}
@Test
public void dependencyFailedToLoad() {
void dependencyFailedToLoad() {
pluginWrapper("dependency").version("5").buildFailed();
PluginWrapper pw = pluginWrapper("dependee").deps("dependency:3").buildLoaded();
@ -104,7 +104,7 @@ public class PluginWrapperTest {
@Issue("JENKINS-66563")
@Test
public void insertJarsIntoClassPath() throws Exception {
void insertJarsIntoClassPath() throws Exception {
try (URLClassLoader2 cl = new URLClassLoader2("Test", new URL[0])) {
assertInjectingJarsWorks(cl);
}
@ -210,7 +210,7 @@ public class PluginWrapperTest {
@Issue("JENKINS-52665")
@Test
public void isSnapshot() {
void isSnapshot() {
assertFalse(PluginWrapper.isSnapshot("1.0"));
assertFalse(PluginWrapper.isSnapshot("1.0-alpha-1"));
assertFalse(PluginWrapper.isSnapshot("1.0-rc9999.abc123def456"));

View File

@ -29,10 +29,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import java.net.Proxy;
import org.junit.jupiter.api.Test;
public class ProxyConfigurationTest {
class ProxyConfigurationTest {
@Test
public void noProxyHost() {
void noProxyHost() {
String noProxyHost = "*.example.com|192.168.*";
assertEquals(Proxy.Type.HTTP, ProxyConfiguration.createProxy("test.example.co.jp", "proxy.example.com", 8080, noProxyHost).type());
assertEquals(Proxy.Type.DIRECT, ProxyConfiguration.createProxy("test.example.com", "proxy.example.com", 8080, noProxyHost).type());

View File

@ -4,40 +4,50 @@
package hudson;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import hudson.os.WindowsUtil;
import java.io.File;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.IOException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.jvnet.hudson.test.For;
import org.jvnet.hudson.test.Issue;
@For(Util.class)
// https://superuser.com/q/343074
public class RemoveWindowsDirectoryJunctionTest {
@Rule
public TemporaryFolder tmp = new TemporaryFolder();
class RemoveWindowsDirectoryJunctionTest {
@Before
public void windowsOnly() {
@TempDir
private File tmp;
@BeforeEach
void windowsOnly() {
assumeTrue(Functions.isWindows());
}
@Test
@Issue("JENKINS-2995")
public void testJunctionIsRemovedButNotContents() throws Exception {
File subdir1 = tmp.newFolder("notJunction");
void testJunctionIsRemovedButNotContents() throws Exception {
File subdir1 = newFolder(tmp, "notJunction");
File f1 = new File(subdir1, "testfile1.txt");
assertTrue("Unable to create temporary file in notJunction directory", f1.createNewFile());
File j1 = WindowsUtil.createJunction(new File(tmp.getRoot(), "test junction"), subdir1);
assertTrue(f1.createNewFile(), "Unable to create temporary file in notJunction directory");
File j1 = WindowsUtil.createJunction(new File(tmp, "test junction"), subdir1);
Util.deleteRecursive(j1);
assertFalse("Windows Junction should have been removed", j1.exists());
assertTrue("Contents of Windows Junction should not be removed", f1.exists());
assertFalse(j1.exists(), "Windows Junction should have been removed");
assertTrue(f1.exists(), "Contents of Windows Junction should not be removed");
}
private static File newFolder(File root, String... subDirs) throws IOException {
String subFolder = String.join("/", subDirs);
File result = new File(root, subFolder);
if (!result.mkdirs()) {
throw new IOException("Couldn't create folders " + root);
}
return result;
}
}

View File

@ -28,16 +28,16 @@ package hudson;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertArrayEquals;
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.Assume.assumeFalse;
import static org.junit.Assume.assumeNoException;
import static org.junit.Assume.assumeTrue;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import hudson.model.TaskListener;
import hudson.os.WindowsUtil;
@ -62,21 +62,20 @@ import java.util.Properties;
import org.apache.commons.io.FileUtils;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.jvnet.hudson.test.Issue;
/**
* @author Kohsuke Kawaguchi
*/
public class UtilTest {
class UtilTest {
@Rule public TemporaryFolder tmp = new TemporaryFolder();
@TempDir
private File tmp;
@Test
public void testReplaceMacro() {
void testReplaceMacro() {
Map<String, String> m = new HashMap<>();
m.put("A", "a");
m.put("A.B", "a-b");
@ -111,7 +110,7 @@ public class UtilTest {
}
@Test
public void testTimeSpanString() {
void testTimeSpanString() {
// Check that amounts less than 365 days are not rounded up to a whole year.
// In the previous implementation there were 360 days in a year.
// We're still working on the assumption that a month is 30 days, so there will
@ -144,8 +143,8 @@ public class UtilTest {
Locale.setDefault(Locale.GERMANY);
try {
// Just verifying no exception is thrown:
assertNotNull("German locale", Util.getTimeSpanString(1234));
assertNotNull("German locale <1 sec", Util.getTimeSpanString(123));
assertNotNull(Util.getTimeSpanString(1234), "German locale");
assertNotNull(Util.getTimeSpanString(123), "German locale <1 sec");
}
finally { Locale.setDefault(saveLocale); }
}
@ -155,7 +154,7 @@ public class UtilTest {
* Test that Strings that contain spaces are correctly URL encoded.
*/
@Test
public void testEncodeSpaces() {
void testEncodeSpaces() {
final String urlWithSpaces = "http://hudson/job/Hudson Job";
String encoded = Util.encode(urlWithSpaces);
assertEquals("http://hudson/job/Hudson%20Job", encoded);
@ -165,7 +164,7 @@ public class UtilTest {
* Test the rawEncode() method.
*/
@Test
public void testRawEncode() {
void testRawEncode() {
String[] data = { // Alternating raw,encoded
"abcdefghijklmnopqrstuvwxyz",
"abcdefghijklmnopqrstuvwxyz",
@ -185,7 +184,7 @@ public class UtilTest {
"%C3%A9%20",
};
for (int i = 0; i < data.length; i += 2) {
assertEquals("test " + i, data[i + 1], Util.rawEncode(data[i]));
assertEquals(data[i + 1], Util.rawEncode(data[i]), "test " + i);
}
}
@ -193,7 +192,7 @@ public class UtilTest {
* Test the fullEncode() method.
*/
@Test
public void testFullEncode() {
void testFullEncode() {
String[] data = {
"abcdefghijklmnopqrstuvwxyz",
"abcdefghijklmnopqrstuvwxyz",
@ -213,7 +212,7 @@ public class UtilTest {
"%C3%A9%20",
};
for (int i = 0; i < data.length; i += 2) {
assertEquals("test " + i, data[i + 1], Util.fullEncode(data[i]));
assertEquals(data[i + 1], Util.fullEncode(data[i]), "test " + i);
}
}
@ -221,20 +220,20 @@ public class UtilTest {
* Test the tryParseNumber() method.
*/
@Test
public void testTryParseNumber() {
assertEquals("Successful parse did not return the parsed value", 20, Util.tryParseNumber("20", 10).intValue());
assertEquals("Failed parse did not return the default value", 10, Util.tryParseNumber("ss", 10).intValue());
assertEquals("Parsing empty string did not return the default value", 10, Util.tryParseNumber("", 10).intValue());
assertEquals("Parsing null string did not return the default value", 10, Util.tryParseNumber(null, 10).intValue());
void testTryParseNumber() {
assertEquals(20, Util.tryParseNumber("20", 10).intValue(), "Successful parse did not return the parsed value");
assertEquals(10, Util.tryParseNumber("ss", 10).intValue(), "Failed parse did not return the default value");
assertEquals(10, Util.tryParseNumber("", 10).intValue(), "Parsing empty string did not return the default value");
assertEquals(10, Util.tryParseNumber(null, 10).intValue(), "Parsing null string did not return the default value");
}
@Test
public void testSymlink() throws Exception {
void testSymlink() throws Exception {
assumeFalse(Functions.isWindows());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
StreamTaskListener l = new StreamTaskListener(baos, Charset.defaultCharset());
File d = tmp.getRoot();
File d = tmp;
try {
new FilePath(new File(d, "a")).touch(0);
assertNull(Util.resolveSymlink(new File(d, "a")));
@ -256,7 +255,7 @@ public class UtilTest {
// test linking from another directory
File anotherDir = new File(d, "anotherDir");
assertTrue("Couldn't create " + anotherDir, anotherDir.mkdir());
assertTrue(anotherDir.mkdir(), "Couldn't create " + anotherDir);
Util.createSymlink(d, "a", "anotherDir/link", l);
assertEquals("a", Util.resolveSymlink(new File(d, "anotherDir/link")));
@ -277,12 +276,12 @@ public class UtilTest {
}
@Test
public void testIsSymlink() throws IOException, InterruptedException {
void testIsSymlink() throws IOException, InterruptedException {
assumeFalse(Functions.isWindows());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
StreamTaskListener l = new StreamTaskListener(baos, Charset.defaultCharset());
File d = tmp.getRoot();
File d = tmp;
try {
new FilePath(new File(d, "original")).touch(0);
assertFalse(Util.isSymlink(new File(d, "original")));
@ -292,11 +291,11 @@ public class UtilTest {
// test linking to another directory
File dir = new File(d, "dir");
assertTrue("Couldn't create " + dir, dir.mkdir());
assertTrue(dir.mkdir(), "Couldn't create " + dir);
assertFalse(Util.isSymlink(new File(d, "dir")));
File anotherDir = new File(d, "anotherDir");
assertTrue("Couldn't create " + anotherDir, anotherDir.mkdir());
assertTrue(anotherDir.mkdir(), "Couldn't create " + anotherDir);
Util.createSymlink(d, "dir", "anotherDir/symlinkDir", l);
// JENKINS-12331: either a bug in createSymlink or this isn't supposed to work:
@ -307,22 +306,22 @@ public class UtilTest {
}
@Test
public void testIsSymlink_onWindows_junction() throws Exception {
assumeTrue("Uses Windows-specific features", Functions.isWindows());
File targetDir = tmp.newFolder("targetDir");
File d = tmp.newFolder("dir");
void testIsSymlink_onWindows_junction() throws Exception {
assumeTrue(Functions.isWindows(), "Uses Windows-specific features");
File targetDir = newFolder(tmp, "targetDir");
File d = newFolder(tmp, "dir");
File junction = WindowsUtil.createJunction(new File(d, "junction"), targetDir);
assertTrue(Util.isSymlink(junction));
}
@Test
@Issue("JENKINS-55448")
public void testIsSymlink_ParentIsJunction() throws IOException, InterruptedException {
assumeTrue("Uses Windows-specific features", Functions.isWindows());
File targetDir = tmp.newFolder();
void testIsSymlink_ParentIsJunction() throws IOException, InterruptedException {
assumeTrue(Functions.isWindows(), "Uses Windows-specific features");
File targetDir = newFolder(tmp, "junit");
File file = new File(targetDir, "test-file");
new FilePath(file).touch(System.currentTimeMillis());
File dir = tmp.newFolder();
File dir = newFolder(tmp, "junit");
File junction = WindowsUtil.createJunction(new File(dir, "junction"), targetDir);
assertTrue(Util.isSymlink(junction));
@ -331,19 +330,19 @@ public class UtilTest {
@Test
@Issue("JENKINS-55448")
public void testIsSymlink_ParentIsSymlink() throws IOException, InterruptedException {
void testIsSymlink_ParentIsSymlink() throws IOException, InterruptedException {
assumeFalse(Functions.isWindows());
File folder = tmp.newFolder();
File folder = newFolder(tmp, "junit");
File file = new File(folder, "test-file");
new FilePath(file).touch(System.currentTimeMillis());
Path link = tmp.getRoot().toPath().resolve("sym-link");
Path link = tmp.toPath().resolve("sym-link");
Path pathWithSymlinkParent = Files.createSymbolicLink(link, folder.toPath()).resolve("test-file");
assertTrue(Util.isSymlink(link));
assertFalse(Util.isSymlink(pathWithSymlinkParent));
}
@Test
public void testHtmlEscape() {
void testHtmlEscape() {
assertEquals("<br>", Util.escape("\n"));
assertEquals("&lt;a&gt;", Util.escape("<a>"));
assertEquals("&#039;&quot;", Util.escape("'\""));
@ -356,7 +355,7 @@ public class UtilTest {
*/
@Issue("JENKINS-10346")
@Test
public void testDigestThreadSafety() throws InterruptedException {
void testDigestThreadSafety() throws InterruptedException {
String a = "abcdefgh";
String b = "123456789";
@ -405,7 +404,7 @@ public class UtilTest {
@Test
@SuppressWarnings("deprecation")
public void testIsAbsoluteUri() {
void testIsAbsoluteUri() {
assertTrue(Util.isAbsoluteUri("http://foobar/"));
assertTrue(Util.isAbsoluteUri("mailto:kk@kohsuke.org"));
assertTrue(Util.isAbsoluteUri("d123://test/"));
@ -417,7 +416,7 @@ public class UtilTest {
@Test
@Issue({"SECURITY-276", "SECURITY-3501"})
public void testIsSafeToRedirectTo() {
void testIsSafeToRedirectTo() {
assertFalse(Util.isSafeToRedirectTo("http://foobar/"));
assertFalse(Util.isSafeToRedirectTo("mailto:kk@kohsuke.org"));
assertFalse(Util.isSafeToRedirectTo("d123://test/"));
@ -440,7 +439,7 @@ public class UtilTest {
}
@Test
public void loadFile() throws IOException {
void loadFile() throws IOException {
// Standard character sets
assertEquals(
"Iñtërnâtiônàlizætiøn",
@ -473,17 +472,17 @@ public class UtilTest {
}
@Test
public void loadProperties() throws IOException {
void loadProperties() throws IOException {
assertEquals(0, Util.loadProperties("").size());
Properties p = Util.loadProperties("k.e.y=va.l.ue");
assertEquals(p.toString(), "va.l.ue", p.get("k.e.y"));
assertEquals(p.toString(), 1, p.size());
assertEquals("va.l.ue", p.get("k.e.y"), p.toString());
assertEquals(1, p.size(), p.toString());
}
@Test
public void isRelativePathUnix() {
void isRelativePathUnix() {
assertThat("/", not(aRelativePath()));
assertThat("/foo/bar", not(aRelativePath()));
assertThat("/foo/../bar", not(aRelativePath()));
@ -496,7 +495,7 @@ public class UtilTest {
}
@Test
public void isRelativePathWindows() {
void isRelativePathWindows() {
assertThat("\\", aRelativePath());
assertThat("\\foo\\bar", aRelativePath());
assertThat("\\foo\\..\\bar", aRelativePath());
@ -534,7 +533,7 @@ public class UtilTest {
}
@Test
public void testIsDescendant() throws IOException {
void testIsDescendant() throws IOException {
File root;
File other;
if (Functions.isWindows()) {
@ -572,7 +571,7 @@ public class UtilTest {
}
@Test
public void testModeToPermissions() throws Exception {
void testModeToPermissions() throws Exception {
assertEquals(PosixFilePermissions.fromString("rwxrwxrwx"), Util.modeToPermissions(0777));
assertEquals(PosixFilePermissions.fromString("rwxr-xrwx"), Util.modeToPermissions(0757));
assertEquals(PosixFilePermissions.fromString("rwxr-x---"), Util.modeToPermissions(0750));
@ -584,14 +583,14 @@ public class UtilTest {
assertEquals(PosixFilePermissions.fromString("-wxr--rw-"), Util.modeToPermissions(0346));
assertEquals(PosixFilePermissions.fromString("---------"), Util.modeToPermissions(0000));
assertEquals("Non-permission bits should be ignored", PosixFilePermissions.fromString("r-xr-----"), Util.modeToPermissions(0100540));
assertEquals(PosixFilePermissions.fromString("r-xr-----"), Util.modeToPermissions(0100540), "Non-permission bits should be ignored");
Exception e = Assert.assertThrows(Exception.class, () -> Util.modeToPermissions(01777));
Exception e = assertThrows(Exception.class, () -> Util.modeToPermissions(01777));
assertThat(e.getMessage(), startsWith("Invalid mode"));
}
@Test
public void testPermissionsToMode() {
void testPermissionsToMode() {
assertEquals(0777, Util.permissionsToMode(PosixFilePermissions.fromString("rwxrwxrwx")));
assertEquals(0757, Util.permissionsToMode(PosixFilePermissions.fromString("rwxr-xrwx")));
assertEquals(0750, Util.permissionsToMode(PosixFilePermissions.fromString("rwxr-x---")));
@ -605,7 +604,7 @@ public class UtilTest {
}
@Test
public void testDifferenceDays() throws Exception {
void testDifferenceDays() throws Exception {
Date may_6_10am = parseDate("2018-05-06 10:00:00");
Date may_6_11pm55 = parseDate("2018-05-06 23:55:00");
Date may_7_01am = parseDate("2018-05-07 01:00:00");
@ -636,7 +635,7 @@ public class UtilTest {
@Test
@Issue("SECURITY-904")
public void resolveSymlinkToFile() throws Exception {
void resolveSymlinkToFile() throws Exception {
assumeFalse(Functions.isWindows());
// root
// /a
@ -645,7 +644,7 @@ public class UtilTest {
// /_b => symlink to /root/b
// /b
// /_a => symlink to /root/a
File root = tmp.getRoot();
File root = tmp;
File a = new File(root, "a");
File aa = new File(a, "aa");
aa.mkdirs();
@ -675,14 +674,14 @@ public class UtilTest {
@Test
@Issue("JENKINS-67372")
public void createDirectories() throws Exception {
void createDirectories() throws Exception {
assumeFalse(Functions.isWindows());
// root
// /a
// /a1
// /a2 => symlink to a1
// /b => symlink to a
Path root = tmp.getRoot().toPath().toRealPath();
Path root = tmp.toPath().toRealPath();
Path a = root.resolve("a");
Path a1 = a.resolve("a1");
Files.createDirectories(a1);
@ -706,7 +705,7 @@ public class UtilTest {
@Test
@Issue("JENKINS-67372")
public void createDirectoriesInRoot() throws Exception {
void createDirectoriesInRoot() throws Exception {
assumeFalse(Functions.isWindows());
Path newDirInRoot = Paths.get("/new-dir-in-root");
Path newSymlinkInRoot = Paths.get("/new-symlink-in-root");
@ -716,30 +715,30 @@ public class UtilTest {
assertEquals(newDirInRoot.resolve("new2"), Util.createDirectories(newSymlinkInRoot.resolve("new2")).toRealPath());
} catch (FileSystemException e) {
// Not running as root
assumeNoException(e);
assumeTrue(false, e.toString());
}
}
@Test
public void ifOverriddenSuccess() {
void ifOverriddenSuccess() {
assertTrue(Util.ifOverridden(() -> true, BaseClass.class, DerivedClassSuccess.class, "method"));
}
@Test
public void ifOverriddenFailure() {
AbstractMethodError error = Assert.assertThrows(AbstractMethodError.class, () -> Util.ifOverridden(() -> true, BaseClass.class, DerivedClassFailure.class, "method"));
void ifOverriddenFailure() {
AbstractMethodError error = assertThrows(AbstractMethodError.class, () -> Util.ifOverridden(() -> true, BaseClass.class, DerivedClassFailure.class, "method"));
assertEquals("The class " + DerivedClassFailure.class.getName() + " must override at least one of the BaseClass.method methods", error.getMessage());
}
@Test
public void testGetHexOfSHA256DigestOf() throws IOException {
void testGetHexOfSHA256DigestOf() {
byte[] input = new byte[] {12, 34, 16};
String str = Util.getHexOfSHA256DigestOf(input);
assertEquals(str, "134fefbd329986726407a5208107ef07c9e33da779f5068bff191733268fe997");
assertEquals("134fefbd329986726407a5208107ef07c9e33da779f5068bff191733268fe997", str);
}
@Test
public void testGetSHA256DigestOf() {
void testGetSHA256DigestOf() {
byte[] input = new byte[] {12, 34, 16};
byte[] sha256DigestActual = Util.getSHA256DigestOf(input);
@ -753,6 +752,7 @@ public class UtilTest {
protected String method() {
return "base";
}
}
public static class DerivedClassFailure extends BaseClass {
@ -764,5 +764,15 @@ public class UtilTest {
protected String method() {
return DerivedClassSuccess.class.getName();
}
}
private static File newFolder(File root, String... subDirs) throws IOException {
String subFolder = String.join("/", subDirs);
File result = new File(root, subFolder);
if (!result.exists() && !result.mkdirs()) {
throw new IOException("Couldn't create folders " + root);
}
return result;
}
}

View File

@ -3,7 +3,7 @@ package hudson;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.io.StreamException;
@ -14,12 +14,12 @@ import java.io.File;
import java.io.IOException;
import java.net.URL;
import jenkins.model.Jenkins;
import org.junit.Test;
import org.junit.jupiter.api.Test;
public class XmlFileTest {
class XmlFileTest {
@Test
public void canReadXml1_0Test() throws IOException {
void canReadXml1_0Test() throws IOException {
URL configUrl = getClass().getResource("/hudson/config_1_0.xml");
XStream2 xs = new XStream2();
xs.alias("hudson", Jenkins.class);
@ -33,7 +33,7 @@ public class XmlFileTest {
}
@Test
public void xml1_0_withSpecialCharsShouldFail() {
void xml1_0_withSpecialCharsShouldFail() {
URL configUrl = getClass().getResource("/hudson/config_1_0_with_special_chars.xml");
XStream2 xs = new XStream2();
xs.alias("hudson", Jenkins.class);
@ -53,7 +53,7 @@ public class XmlFileTest {
}
@Test
public void canReadXml1_1Test() throws IOException {
void canReadXml1_1Test() throws IOException {
URL configUrl = getClass().getResource("/hudson/config_1_1.xml");
XStream2 xs = new XStream2();
xs.alias("hudson", Jenkins.class);
@ -67,7 +67,7 @@ public class XmlFileTest {
}
@Test
public void canReadXmlWithControlCharsTest() throws IOException {
void canReadXmlWithControlCharsTest() throws IOException {
URL configUrl = getClass().getResource("/hudson/config_1_1_with_special_chars.xml");
XStream2 xs = new XStream2();
xs.alias("hudson", Jenkins.class);

View File

@ -27,88 +27,88 @@ package hudson.util;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
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.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.jvnet.hudson.test.Issue;
public class ArgumentListBuilderTest {
class ArgumentListBuilderTest {
@Test
public void assertEmptyMask() {
void assertEmptyMask() {
ArgumentListBuilder builder = new ArgumentListBuilder();
builder.add("arg");
builder.add("other", "arguments");
assertFalse("There should not be any masked arguments", builder.hasMaskedArguments());
assertFalse(builder.hasMaskedArguments(), "There should not be any masked arguments");
boolean[] array = builder.toMaskArray();
assertNotNull("The mask array should not be null", array);
assertNotNull(array, "The mask array should not be null");
assertThat("The mask array was incorrect", array, is(new boolean[] { false, false, false }));
}
@Test
public void assertLastArgumentIsMasked() {
void assertLastArgumentIsMasked() {
ArgumentListBuilder builder = new ArgumentListBuilder();
builder.add("arg");
builder.addMasked("ismasked");
assertTrue("There should be masked arguments", builder.hasMaskedArguments());
assertTrue(builder.hasMaskedArguments(), "There should be masked arguments");
boolean[] array = builder.toMaskArray();
assertNotNull("The mask array should not be null", array);
assertNotNull(array, "The mask array should not be null");
assertThat("The mask array was incorrect", array, is(new boolean[] { false, true }));
}
@Test
public void assertSeveralMaskedArguments() {
void assertSeveralMaskedArguments() {
ArgumentListBuilder builder = new ArgumentListBuilder();
builder.add("arg");
builder.addMasked("ismasked");
builder.add("non masked arg");
builder.addMasked("ismasked2");
assertTrue("There should be masked arguments", builder.hasMaskedArguments());
assertTrue(builder.hasMaskedArguments(), "There should be masked arguments");
boolean[] array = builder.toMaskArray();
assertNotNull("The mask array should not be null", array);
assertNotNull(array, "The mask array should not be null");
assertThat("The mask array was incorrect", array, is(new boolean[] { false, true, false, true }));
}
@Test
public void assertPrependAfterAddingMasked() {
void assertPrependAfterAddingMasked() {
ArgumentListBuilder builder = new ArgumentListBuilder();
builder.addMasked("ismasked");
builder.add("arg");
builder.prepend("first", "second");
assertTrue("There should be masked arguments", builder.hasMaskedArguments());
assertTrue(builder.hasMaskedArguments(), "There should be masked arguments");
boolean[] array = builder.toMaskArray();
assertNotNull("The mask array should not be null", array);
assertNotNull(array, "The mask array should not be null");
assertThat("The mask array was incorrect", array, is(new boolean[] { false, false, true, false }));
}
@Test
public void assertPrependBeforeAddingMasked() {
void assertPrependBeforeAddingMasked() {
ArgumentListBuilder builder = new ArgumentListBuilder();
builder.prepend("first", "second");
builder.addMasked("ismasked");
builder.add("arg");
assertTrue("There should be masked arguments", builder.hasMaskedArguments());
assertTrue(builder.hasMaskedArguments(), "There should be masked arguments");
boolean[] array = builder.toMaskArray();
assertNotNull("The mask array should not be null", array);
assertNotNull(array, "The mask array should not be null");
assertThat("The mask array was incorrect", array, is(new boolean[] { false, false, true, false }));
}
@Test
public void testToWindowsCommand() {
void testToWindowsCommand() {
ArgumentListBuilder builder = new ArgumentListBuilder().
add("ant.bat").add("-Dfoo1=abc"). // nothing special, no quotes
add("-Dfoo2=foo bar").add("-Dfoo3=/u*r").add("-Dfoo4=/us?"). // add quotes
@ -148,9 +148,9 @@ public class ArgumentListBuilderTest {
}
@Test
@Ignore("It's only for reproduce JENKINS-28790 issue. It's added to testToWindowsCommand")
@Disabled("It's only for reproduce JENKINS-28790 issue. It's added to testToWindowsCommand")
@Issue("JENKINS-28790")
public void testToWindowsCommandMasked() {
void testToWindowsCommandMasked() {
ArgumentListBuilder builder = new ArgumentListBuilder().
add("ant.bat").add("-Dfoo1=abc"). // nothing special, no quotes
add("-Dfoo2=foo bar").add("-Dfoo3=/u*r").add("-Dfoo4=/us?"). // add quotes
@ -177,16 +177,16 @@ public class ArgumentListBuilderTest {
}
@Test
public void assertMaskOnClone() {
void assertMaskOnClone() {
ArgumentListBuilder builder = new ArgumentListBuilder();
builder.add("arg1");
builder.addMasked("masked1");
builder.add("arg2");
ArgumentListBuilder clone = builder.clone();
assertTrue("There should be masked arguments", clone.hasMaskedArguments());
assertTrue(clone.hasMaskedArguments(), "There should be masked arguments");
boolean[] array = clone.toMaskArray();
assertNotNull("The mask array should not be null", array);
assertNotNull(array, "The mask array should not be null");
assertThat("The mask array was incorrect", array, is(builder.toMaskArray()));
}
@ -201,30 +201,30 @@ public class ArgumentListBuilderTest {
private static final Set<String> MASKS = Set.of("key2");
@Test
public void assertKeyValuePairsWithMask() {
void assertKeyValuePairsWithMask() {
ArgumentListBuilder builder = new ArgumentListBuilder();
builder.addKeyValuePairs(null, KEY_VALUES, MASKS);
assertTrue("There should be masked arguments", builder.hasMaskedArguments());
assertTrue(builder.hasMaskedArguments(), "There should be masked arguments");
boolean[] array = builder.toMaskArray();
assertNotNull("The mask array should not be null", array);
assertNotNull(array, "The mask array should not be null");
assertThat("The mask array was incorrect", array, is(new boolean[] { false, true, false }));
}
@Test
public void assertKeyValuePairs() {
void assertKeyValuePairs() {
ArgumentListBuilder builder = new ArgumentListBuilder();
builder.addKeyValuePairs(null, KEY_VALUES);
assertFalse("There should not be any masked arguments", builder.hasMaskedArguments());
assertFalse(builder.hasMaskedArguments(), "There should not be any masked arguments");
boolean[] array = builder.toMaskArray();
assertNotNull("The mask array should not be null", array);
assertNotNull(array, "The mask array should not be null");
assertThat("The mask array was incorrect", array, is(new boolean[] { false, false, false }));
}
@Test
public void addKeyValuePairsFromPropertyString() throws IOException {
void addKeyValuePairsFromPropertyString() throws IOException {
final Map<String, String> map = new HashMap<>();
map.put("PATH", "C:\\Windows");
final VariableResolver<String> resolver = new VariableResolver.ByMap<>(map);
@ -241,15 +241,17 @@ public class ArgumentListBuilderTest {
}
@Test
public void numberOfBackslashesInPropertiesShouldBePreservedAfterMacroExpansion() throws IOException {
void numberOfBackslashesInPropertiesShouldBePreservedAfterMacroExpansion() throws IOException {
final Map<String, String> map = new HashMap<>();
map.put("ONE", "one\\backslash");
map.put("TWO", "two\\\\backslashes");
map.put("FOUR", "four\\\\\\\\backslashes");
final String properties = "one=$ONE\n" +
"two=$TWO\n" +
"four=$FOUR\n"
final String properties = """
one=$ONE
two=$TWO
four=$FOUR
"""
;
final String args = new ArgumentListBuilder()

View File

@ -4,12 +4,12 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import edu.umd.cs.findbugs.annotations.Nullable;
import hudson.Functions;
@ -22,15 +22,14 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermission;
import java.util.Set;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
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.io.TempDir;
import org.jvnet.hudson.test.Issue;
public class AtomicFileWriterTest {
class AtomicFileWriterTest {
private static final String PREVIOUS = "previous value \n blah";
/**
* Provides access to the default permissions given to a new file. (i.e. indirect way to get umask settings).
@ -38,15 +37,15 @@ public class AtomicFileWriterTest {
*/
@Nullable
private static Set<PosixFilePermission> DEFAULT_GIVEN_PERMISSIONS;
@ClassRule
public static TemporaryFolder tmp = new TemporaryFolder();
File af;
AtomicFileWriter afw;
String expectedContent = "hello world";
@TempDir
private static File tmp;
private File af;
private AtomicFileWriter afw;
private String expectedContent = "hello world";
@BeforeClass
public static void computePermissions() throws IOException {
final File tempDir = tmp.newFolder();
@BeforeAll
static void computePermissions() throws IOException {
final File tempDir = newFolder(tmp, "junit");
final File newFile = new File(tempDir, "blah");
assertThat(newFile.createNewFile(), is(true));
if (!isPosixSupported(newFile)) {
@ -66,23 +65,23 @@ public class AtomicFileWriterTest {
return posixSupported;
}
@Before
public void setUp() throws IOException {
af = tmp.newFile();
@BeforeEach
void setUp() throws IOException {
af = File.createTempFile("junit", null, tmp);
Files.writeString(af.toPath(), PREVIOUS, Charset.defaultCharset());
afw = new AtomicFileWriter(af.toPath(), Charset.defaultCharset());
}
@After
public void tearDown() throws IOException {
@AfterEach
void tearDown() throws IOException {
afw.abort();
}
@Test
public void symlinkToDirectory() throws Exception {
void symlinkToDirectory() throws Exception {
assumeFalse(Functions.isWindows());
final File folder = tmp.newFolder();
final File containingSymlink = tmp.newFolder();
final File folder = newFolder(tmp, "junit");
final File containingSymlink = newFolder(tmp, "junit");
final Path zeSymlink = Files.createSymbolicLink(Paths.get(containingSymlink.getAbsolutePath(), "ze_symlink"),
folder.toPath());
@ -93,13 +92,13 @@ public class AtomicFileWriterTest {
}
@Test
public void createFile() {
void createFile() {
// Verify the file we created exists
assertTrue(Files.exists(afw.getTemporaryPath()));
}
@Test
public void writeToAtomicFile() throws Exception {
void writeToAtomicFile() throws Exception {
// Given
afw.write(expectedContent, 0, expectedContent.length());
afw.write(expectedContent);
@ -109,12 +108,11 @@ public class AtomicFileWriterTest {
afw.flush();
// Then
assertEquals("File writer did not properly flush to temporary file",
expectedContent.length() * 2 + 1, Files.size(afw.getTemporaryPath()));
assertEquals(expectedContent.length() * 2 + 1, Files.size(afw.getTemporaryPath()), "File writer did not properly flush to temporary file");
}
@Test
public void commitToFile() throws Exception {
void commitToFile() throws Exception {
// Given
afw.write(expectedContent, 0, expectedContent.length());
afw.write(new char[]{'h', 'e', 'y'}, 0, 3);
@ -128,7 +126,7 @@ public class AtomicFileWriterTest {
}
@Test
public void abortDeletesTmpFile() throws Exception {
void abortDeletesTmpFile() throws Exception {
// Given
afw.write(expectedContent, 0, expectedContent.length());
@ -141,15 +139,15 @@ public class AtomicFileWriterTest {
}
@Test
public void indexOutOfBoundsLeavesOriginalUntouched() throws Exception {
void indexOutOfBoundsLeavesOriginalUntouched() throws Exception {
// Given
assertThrows(IndexOutOfBoundsException.class, () -> afw.write(expectedContent, 0, expectedContent.length() + 10));
assertEquals(PREVIOUS, Files.readString(af.toPath(), Charset.defaultCharset()));
}
@Test
public void badPath() throws Exception {
final File newFile = tmp.newFile();
void badPath() throws Exception {
final File newFile = File.createTempFile("junit", null, tmp);
File parentExistsAndIsAFile = new File(newFile, "badChild");
assertTrue(newFile.exists());
@ -163,12 +161,12 @@ public class AtomicFileWriterTest {
@Issue("JENKINS-48407")
@Test
public void checkPermissionsRespectUmask() throws IOException {
void checkPermissionsRespectUmask() throws IOException {
final File newFile = tmp.newFile();
final File newFile = File.createTempFile("junit", null, tmp);
boolean posixSupported = isPosixSupported(newFile);
assumeThat(posixSupported, is(true));
assumeTrue(posixSupported);
// given
Path filePath = newFile.toPath();
@ -184,4 +182,13 @@ public class AtomicFileWriterTest {
assertThat(Files.getPosixFilePermissions(filePath), equalTo(DEFAULT_GIVEN_PERMISSIONS));
}
private static File newFolder(File root, String... subDirs) throws IOException {
String subFolder = String.join("/", subDirs);
File result = new File(root, subFolder);
if (!result.exists() && !result.mkdirs()) {
throw new IOException("Couldn't create folders " + root);
}
return result;
}
}

View File

@ -1,17 +1,17 @@
package hudson.util;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.junit.Test;
import org.junit.jupiter.api.Test;
public class CompoundEnumerationTest {
class CompoundEnumerationTest {
@Test
public void smokes() {
void smokes() {
assertEquals(
rangeClosed(1, 12),
Collections.list(
@ -22,7 +22,7 @@ public class CompoundEnumerationTest {
}
@Test
public void empty() {
void empty() {
assertEquals(Collections.emptyList(), Collections.list(new CompoundEnumeration<>()));
assertEquals(
Collections.emptyList(),
@ -42,7 +42,7 @@ public class CompoundEnumerationTest {
}
@Test
public void gaps() {
void gaps() {
assertEquals(
rangeClosed(1, 8),
Collections.list(

View File

@ -24,12 +24,12 @@
package hudson.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.HashMap;
import java.util.HashSet;
@ -37,18 +37,18 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
/**
* @author Kohsuke Kawaguchi
*/
public class ConsistentHashTest {
class ConsistentHashTest {
/**
* Just some random tests to ensure that we have no silly NPE or that kind of error.
*/
@Test
public void basic() {
void basic() {
ConsistentHash<String> hash = new ConsistentHash<>();
hash.add("data1");
hash.add("data2");
@ -77,7 +77,7 @@ public class ConsistentHashTest {
* Uneven distribution should result in uneven mapping.
*/
@Test
public void unevenDistribution() {
void unevenDistribution() {
ConsistentHash<String> hash = new ConsistentHash<>();
hash.add("Even", 10);
hash.add("Odd", 100);
@ -102,7 +102,7 @@ public class ConsistentHashTest {
* Removal shouldn't affect existing nodes
*/
@Test
public void removal() {
void removal() {
ConsistentHash<Integer> hash = new ConsistentHash<>();
for (int i = 0; i < 10; i++) {
hash.add(i);
@ -127,7 +127,7 @@ public class ConsistentHashTest {
}
@Test
public void emptyBehavior() {
void emptyBehavior() {
ConsistentHash<String> hash = new ConsistentHash<>();
assertEquals(0, hash.countAllPoints());
assertFalse(hash.list(0).iterator().hasNext());
@ -136,7 +136,7 @@ public class ConsistentHashTest {
}
@Test
public void countAllPoints() {
void countAllPoints() {
ConsistentHash<String> hash = new ConsistentHash<>();
assertEquals(0, hash.countAllPoints());
hash.add("foo", 10);
@ -148,7 +148,7 @@ public class ConsistentHashTest {
}
@Test
public void defaultReplicationIsOneHundred() {
void defaultReplicationIsOneHundred() {
ConsistentHash<String> hash = new ConsistentHash<>();
assertEquals(0, hash.countAllPoints());
hash.add("foo");
@ -156,7 +156,7 @@ public class ConsistentHashTest {
}
@Test
public void setCustomDefaultReplication() {
void setCustomDefaultReplication() {
ConsistentHash<String> hash = new ConsistentHash<>((ConsistentHash.Hash<String>) ConsistentHash.DEFAULT_HASH, 7);
assertEquals(0, hash.countAllPoints());
hash.add("foo");
@ -164,7 +164,7 @@ public class ConsistentHashTest {
}
@Test
public void usesCustomHash() {
void usesCustomHash() {
final RuntimeException exception = new RuntimeException();
ConsistentHash.Hash<String> hashFunction = str -> {
throw exception;
@ -179,8 +179,8 @@ public class ConsistentHashTest {
* This test doesn't fail but it's written to measure the performance of the consistent hash function with large data set.
*/
@Test
@Ignore("Helper test for performance, no assertion")
public void speed() {
@Disabled("Helper test for performance, no assertion")
void speed() {
Map<String, Integer> data = new CopyOnWriteMap.Hash<>();
for (int i = 0; i < 1000; i++) {
data.put("node" + i, 100);

View File

@ -25,20 +25,20 @@
package hudson.util;
import static org.hamcrest.MatcherAssert.assertThat;
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 static org.xmlunit.matchers.CompareMatcher.isSimilarTo;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.xmlunit.diff.DefaultNodeMatcher;
import org.xmlunit.diff.ElementSelectors;
/**
* @author Kohsuke Kawaguchi, Alan Harder
*/
public class CopyOnWriteListTest {
class CopyOnWriteListTest {
public static final class TestData {
CopyOnWriteList list1 = new CopyOnWriteList();
@ -49,7 +49,7 @@ public class CopyOnWriteListTest {
* Verify that the serialization form of List and CopyOnWriteList are the same.
*/
@Test
public void serialization() {
void serialization() {
XStream2 xs = new XStream2();
TestData td = new TestData();

View File

@ -24,19 +24,19 @@
package hudson.util;
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.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import org.junit.Test;
import org.junit.jupiter.api.Test;
/**
* @author Mike Dillon, Alan Harder
*/
public class CopyOnWriteMapTest {
class CopyOnWriteMapTest {
public static final class HashData {
CopyOnWriteMap.Hash<String, String> map1 = new CopyOnWriteMap.Hash<>();
HashMap<String, String> map2 = new HashMap<>();
@ -45,14 +45,16 @@ public class CopyOnWriteMapTest {
/**
* Verify that serialization form of CopyOnWriteMap.Hash and HashMap are the same.
*/
@Test public void hashSerialization() {
@Test
void hashSerialization() {
HashData td = new HashData();
XStream2 xs = new XStream2();
String out = xs.toXML(td);
assertEquals("empty maps", "<hudson.util.CopyOnWriteMapTest_-HashData>"
assertEquals("<hudson.util.CopyOnWriteMapTest_-HashData>"
+ "<map1/><map2/></hudson.util.CopyOnWriteMapTest_-HashData>",
out.replaceAll("\\s+", ""));
out.replaceAll("\\s+", ""),
"empty maps");
HashData td2 = (HashData) xs.fromXML(out);
assertTrue(td2.map1.isEmpty());
assertTrue(td2.map2.isEmpty());
@ -60,11 +62,12 @@ public class CopyOnWriteMapTest {
td.map1.put("foo1", "bar1");
td.map2.put("foo2", "bar2");
out = xs.toXML(td);
assertEquals("maps", "<hudson.util.CopyOnWriteMapTest_-HashData><map1>"
assertEquals("<hudson.util.CopyOnWriteMapTest_-HashData><map1>"
+ "<entry><string>foo1</string><string>bar1</string></entry></map1>"
+ "<map2><entry><string>foo2</string><string>bar2</string></entry>"
+ "</map2></hudson.util.CopyOnWriteMapTest_-HashData>",
out.replaceAll("\\s+", ""));
out.replaceAll("\\s+", ""),
"maps");
td2 = (HashData) xs.fromXML(out);
assertEquals("bar1", td2.map1.get("foo1"));
assertEquals("bar2", td2.map2.get("foo2"));
@ -89,15 +92,17 @@ public class CopyOnWriteMapTest {
* Verify that an empty CopyOnWriteMap.Tree can be serialized,
* and that serialization form is the same as a standard TreeMap.
*/
@Test public void treeSerialization() {
@Test
void treeSerialization() {
TreeData td = new TreeData();
XStream2 xs = new XStream2();
String out = xs.toXML(td);
assertEquals("empty maps", "<hudson.util.CopyOnWriteMapTest_-TreeData>"
assertEquals("<hudson.util.CopyOnWriteMapTest_-TreeData>"
+ "<map1/><map2/>"
+ "</hudson.util.CopyOnWriteMapTest_-TreeData>",
out.replaceAll("\\s+", ""));
out.replaceAll("\\s+", ""),
"empty maps");
TreeData td2 = (TreeData) xs.fromXML(out);
assertTrue(td2.map1.isEmpty());
assertTrue(td2.map2.isEmpty());
@ -106,20 +111,22 @@ public class CopyOnWriteMapTest {
td.map1.put("foo1", "bar1");
td.map2.put("foo2", "bar2");
out = xs.toXML(td);
assertEquals("maps", "<hudson.util.CopyOnWriteMapTest_-TreeData><map1>"
assertEquals("<hudson.util.CopyOnWriteMapTest_-TreeData><map1>"
+ "<comparator class=\"java.lang.String$CaseInsensitiveComparator\"/>"
+ "<entry><string>foo1</string><string>bar1</string></entry></map1>"
+ "<map2><comparator class=\"java.lang.String$CaseInsensitiveComparator\""
+ " reference=\"../../map1/comparator\"/>"
+ "<entry><string>foo2</string><string>bar2</string></entry></map2>"
+ "</hudson.util.CopyOnWriteMapTest_-TreeData>",
out.replaceAll(">\\s+<", "><"));
out.replaceAll(">\\s+<", "><"),
"maps");
td2 = (TreeData) xs.fromXML(out);
assertEquals("bar1", td2.map1.get("foo1"));
assertEquals("bar2", td2.map2.get("foo2"));
}
@Test public void equalsHashCodeToString() {
@Test
void equalsHashCodeToString() {
Map<String, Integer> m1 = new TreeMap<>();
Map<String, Integer> m2 = new CopyOnWriteMap.Tree<>();
m1.put("foo", 5);

View File

@ -1,19 +1,19 @@
package hudson.util;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import hudson.util.CyclicGraphDetector.CycleDetectedException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import org.junit.Test;
import org.junit.jupiter.api.Test;
/**
* @author Kohsuke Kawaguchi
*/
public class CyclicGraphDetectorTest {
class CyclicGraphDetectorTest {
private static class Edge {
String src, dst;
@ -61,28 +61,27 @@ public class CyclicGraphDetectorTest {
}
void mustContainCycle(String... members) {
final CycleDetectedException e = assertThrows("Cycle expected",
CycleDetectedException.class, this::check);
final CycleDetectedException e = assertThrows(CycleDetectedException.class, this::check, "Cycle expected");
final String msg = "Expected cycle of " + Arrays.asList(members) + " but found " + e.cycle;
for (String s : members) {
assertTrue(msg, e.cycle.contains(s));
assertTrue(e.cycle.contains(s), msg);
}
}
}
@Test
public void cycle1() {
void cycle1() {
new Graph().e("A", "B").e("B", "C").e("C", "A").mustContainCycle("A", "B", "C");
}
@Test
public void cycle2() {
void cycle2() {
new Graph().e("A", "B").e("B", "C").e("C", "C").mustContainCycle("C");
}
@Test
public void cycle3() {
void cycle3() {
new Graph().e("A", "B").e("B", "C").e("C", "D").e("B", "E").e("E", "D").e("E", "A").mustContainCycle("A", "B", "E");
}
}

View File

@ -27,21 +27,21 @@ package hudson.util;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.arrayContaining;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter;
import hudson.model.Describable;
import hudson.model.Descriptor;
import hudson.model.Saveable;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.jvnet.hudson.test.Issue;
public class DescribableListTest {
class DescribableListTest {
@Issue("JENKINS-49054")
@Test
public void exceptionDuringUnmarshalling() {
void exceptionDuringUnmarshalling() {
Data data = new Data();
data.list.add(new Datum(1));
data.list.add(new Datum(2));
@ -54,7 +54,7 @@ public class DescribableListTest {
}
@Test
public void replace() throws Exception {
void replace() throws Exception {
AtomicInteger count = new AtomicInteger();
DescribableList<Datum, Descriptor<Datum>> list = new DescribableList<>((Saveable) count::incrementAndGet);
list.add(new Datum(1));

View File

@ -24,24 +24,25 @@
package hudson.util;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import hudson.FilePath;
import java.io.File;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
/**
* @author Christoph Thelen
*/
public class DirScannerTest {
class DirScannerTest {
@Rule public TemporaryFolder tmpRule = new TemporaryFolder();
@TempDir
private File tmpRule;
@Test public void globShouldUseDefaultExcludes() throws Exception {
FilePath tmp = new FilePath(tmpRule.getRoot());
@Test
void globShouldUseDefaultExcludes() throws Exception {
FilePath tmp = new FilePath(tmpRule);
try {
tmp.child(".gitignore").touch(0);
FilePath git = tmp.child(".git");
@ -63,8 +64,9 @@ public class DirScannerTest {
}
}
@Test public void globShouldIgnoreDefaultExcludesByRequest() throws Exception {
FilePath tmp = new FilePath(tmpRule.getRoot());
@Test
void globShouldIgnoreDefaultExcludesByRequest() throws Exception {
FilePath tmp = new FilePath(tmpRule);
try {
tmp.child(".gitignore").touch(0);
FilePath git = tmp.child(".git");

View File

@ -2,7 +2,7 @@ package hudson.util;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.io.File;
import java.io.IOException;
@ -10,26 +10,26 @@ import java.nio.channels.ClosedChannelException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
public class FileChannelWriterTest {
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
class FileChannelWriterTest {
File file;
FileChannelWriter writer;
@TempDir
private File temporaryFolder;
@Before
public void setUp() throws Exception {
file = temporaryFolder.newFile();
private File file;
private FileChannelWriter writer;
@BeforeEach
void setUp() throws Exception {
file = File.createTempFile("junit", null, temporaryFolder);
writer = new FileChannelWriter(file.toPath(), StandardCharsets.UTF_8, true, true, StandardOpenOption.WRITE);
}
@Test
public void write() throws Exception {
void write() throws Exception {
writer.write("helloooo");
writer.close();
@ -38,7 +38,7 @@ public class FileChannelWriterTest {
@Test
public void flush() throws Exception {
void flush() throws Exception {
writer.write("hello é è à".toCharArray());
writer.flush();
@ -46,7 +46,7 @@ public class FileChannelWriterTest {
}
@Test
public void close() throws Exception {
void close() throws Exception {
writer.write("helloooo");
writer.close();

View File

@ -28,35 +28,35 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import org.junit.Test;
import org.junit.jupiter.api.Test;
/**
* @author sogabe
*/
public class FormValidationTest {
class FormValidationTest {
@Test
public void testValidateRequired_OK() {
void testValidateRequired_OK() {
FormValidation actual = FormValidation.validateRequired("Name");
assertEquals(FormValidation.ok(), actual);
}
@Test
public void testValidateRequired_Null() {
void testValidateRequired_Null() {
FormValidation actual = FormValidation.validateRequired(null);
assertNotNull(actual);
assertEquals(FormValidation.Kind.ERROR, actual.kind);
}
@Test
public void testValidateRequired_Empty() {
void testValidateRequired_Empty() {
FormValidation actual = FormValidation.validateRequired(" ");
assertNotNull(actual);
assertEquals(FormValidation.Kind.ERROR, actual.kind);
@ -64,17 +64,17 @@ public class FormValidationTest {
// @Issue("JENKINS-7438")
@Test
public void testMessage() {
void testMessage() {
assertEquals("test msg", FormValidation.errorWithMarkup("test msg").getMessage());
}
@Test
public void aggregateZeroValidations() {
void aggregateZeroValidations() {
assertEquals(FormValidation.ok(), aggregate());
}
@Test
public void aggregateSingleValidations() {
void aggregateSingleValidations() {
FormValidation ok = FormValidation.ok();
FormValidation warning = FormValidation.warning("");
FormValidation error = FormValidation.error("");
@ -85,7 +85,7 @@ public class FormValidationTest {
}
@Test
public void aggregateSeveralValidations() {
void aggregateSeveralValidations() {
FormValidation ok = FormValidation.ok("ok_message");
FormValidation warning = FormValidation.warning("warning_message");
FormValidation error = FormValidation.error("error_message");
@ -115,13 +115,13 @@ public class FormValidationTest {
}
@Test
public void formValidationException() {
void formValidationException() {
FormValidation fv = FormValidation.error(new Exception("<html"), "Message<html");
assertThat(fv.renderHtml(), not(containsString("<html")));
}
@Test
public void testUrlCheck() throws IOException {
void testUrlCheck() throws IOException {
FormValidation.URLCheck urlCheck = new FormValidation.URLCheck() {
@Override
protected FormValidation check() throws IOException {

View File

@ -24,9 +24,10 @@
package hudson.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.awt.Dimension;
import org.junit.Assert;
import org.junit.Test;
import org.junit.jupiter.api.Test;
public class GraphTest {
@ -34,25 +35,25 @@ public class GraphTest {
public static final int DEFAULT_H = 300;
@Test
public void testDimensions() {
void testDimensions() {
final Dimension keep = Graph.safeDimension(Graph.MAX_AREA / 1_000, 1000, DEFAULT_W, DEFAULT_H);
Assert.assertEquals(Graph.MAX_AREA / 1_000, keep.width);
Assert.assertEquals(1_000, keep.height);
assertEquals(Graph.MAX_AREA / 1_000, keep.width);
assertEquals(1_000, keep.height);
final Dimension keep2 = Graph.safeDimension(Graph.MAX_AREA / 2, 2, DEFAULT_W, DEFAULT_H);
Assert.assertEquals(Graph.MAX_AREA / 2, keep2.width);
Assert.assertEquals(2, keep2.height);
assertEquals(Graph.MAX_AREA / 2, keep2.width);
assertEquals(2, keep2.height);
final Dimension resetArea = Graph.safeDimension(Graph.MAX_AREA, Graph.MAX_AREA, DEFAULT_W, DEFAULT_H);
Assert.assertEquals(DEFAULT_W, resetArea.width);
Assert.assertEquals(DEFAULT_H, resetArea.height);
assertEquals(DEFAULT_W, resetArea.width);
assertEquals(DEFAULT_H, resetArea.height);
final Dimension resetNegativeWidth = Graph.safeDimension(-50, 1000, DEFAULT_W, DEFAULT_H);
Assert.assertEquals(DEFAULT_W, resetNegativeWidth.width);
Assert.assertEquals(DEFAULT_H, resetNegativeWidth.height);
assertEquals(DEFAULT_W, resetNegativeWidth.width);
assertEquals(DEFAULT_H, resetNegativeWidth.height);
final Dimension resetNegativeHeight = Graph.safeDimension(1000, -50, DEFAULT_W, DEFAULT_H);
Assert.assertEquals(DEFAULT_W, resetNegativeHeight.width);
Assert.assertEquals(DEFAULT_H, resetNegativeHeight.height);
assertEquals(DEFAULT_W, resetNegativeHeight.width);
assertEquals(DEFAULT_H, resetNegativeHeight.height);
}
}

View File

@ -26,30 +26,26 @@ package hudson.util;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import hudson.Util;
import java.io.PrintWriter;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ErrorCollector;
import org.junit.jupiter.api.Test;
import org.jvnet.hudson.test.Issue;
/**
* Test for {@link Util#isOverridden} method.
*/
public class IsOverriddenTest {
@Rule
public ErrorCollector errors = new ErrorCollector();
class IsOverriddenTest {
/**
* Test that a method is found by isOverridden even when it is inherited from an intermediate class.
*/
@Test
public void isOverriddenTest() {
void isOverriddenTest() {
assertTrue(Util.isOverridden(Base.class, Derived.class, "method"));
assertTrue(Util.isOverridden(Base.class, Intermediate.class, "method"));
assertFalse(Util.isOverridden(Base.class, Base.class, "method"));
@ -64,13 +60,13 @@ public class IsOverriddenTest {
* Trying to check for a method which does not exist in the hierarchy.
*/
@Test
public void isOverriddenNegativeTest() {
void isOverriddenNegativeTest() {
assertThrows(IllegalArgumentException.class, () -> Util.isOverridden(Base.class, Derived.class, "method2"));
}
/** Specifying a base class that is not a base class should result in an error. */
@Test
public void badHierarchyIsReported() {
void badHierarchyIsReported() {
assertThrows(IllegalArgumentException.class, () -> Util.isOverridden(Derived.class, Base.class, "method"));
}
@ -78,7 +74,7 @@ public class IsOverriddenTest {
* Do not inspect private methods.
*/
@Test
public void avoidPrivateMethodsInspection() {
void avoidPrivateMethodsInspection() {
assertThrows(IllegalArgumentException.class, () -> Util.isOverridden(Base.class, Intermediate.class, "aPrivateMethod"));
}
@ -106,39 +102,17 @@ public class IsOverriddenTest {
@Issue("JENKINS-62723")
@Test
public void finalOverrides() {
errors.checkSucceeds(() -> {
assertThat("X1 overrides X.m1", Util.isOverridden(X.class, X1.class, "m1"), is(true));
return null;
});
errors.checkSucceeds(() -> {
assertThat("x1 does not override x.m2", Util.isOverridden(X.class, X1.class, "m2"), is(false));
return null;
});
errors.checkSucceeds(() -> {
assertThat("X2 overrides X.m1", Util.isOverridden(X.class, X2.class, "m1"), is(true));
return null;
});
errors.checkSucceeds(() -> {
assertThat("X2 does not override X.m2", Util.isOverridden(X.class, X2.class, "m2"), is(false));
return null;
});
errors.checkSucceeds(() -> {
assertThat("X3 overrides X.m1", Util.isOverridden(X.class, X3.class, "m1"), is(true));
return null;
});
errors.checkSucceeds(() -> {
assertThat("X3 overrides X.m2", Util.isOverridden(X.class, X3.class, "m2"), is(true));
return null;
});
errors.checkSucceeds(() -> {
assertThat("X4 overrides X.m1", Util.isOverridden(X.class, X4.class, "m1"), is(true));
return null;
});
errors.checkSucceeds(() -> {
assertThat("X4 overrides X.m2", Util.isOverridden(X.class, X4.class, "m2"), is(true));
return null;
});
void finalOverrides() {
assertAll(
() -> assertThat("X1 overrides X.m1", Util.isOverridden(X.class, X1.class, "m1"), is(true)),
() -> assertThat("x1 does not override x.m2", Util.isOverridden(X.class, X1.class, "m2"), is(false)),
() -> assertThat("X2 overrides X.m1", Util.isOverridden(X.class, X2.class, "m1"), is(true)),
() -> assertThat("X2 does not override X.m2", Util.isOverridden(X.class, X2.class, "m2"), is(false)),
() -> assertThat("X3 overrides X.m1", Util.isOverridden(X.class, X3.class, "m1"), is(true)),
() -> assertThat("X3 overrides X.m2", Util.isOverridden(X.class, X3.class, "m2"), is(true)),
() -> assertThat("X4 overrides X.m1", Util.isOverridden(X.class, X4.class, "m1"), is(true)),
() -> assertThat("X4 overrides X.m2", Util.isOverridden(X.class, X4.class, "m2"), is(true))
);
}
public interface X {
@ -171,57 +145,23 @@ public class IsOverriddenTest {
@Issue("JENKINS-62723")
@Test
public void baseInterface() {
void baseInterface() {
// Normal case: classes implementing interface methods
errors.checkSucceeds(() -> {
assertThat("I1 does not override I1.foo", Util.isOverridden(I1.class, I1.class, "foo"), is(false));
return null;
});
errors.checkSucceeds(() -> {
assertThat("I2 does not override I1.foo", Util.isOverridden(I1.class, I2.class, "foo"), is(false));
return null;
});
errors.checkSucceeds(() -> {
assertThat("C1 does not override I1.foo", Util.isOverridden(I1.class, C1.class, "foo"), is(false));
return null;
});
errors.checkSucceeds(() -> {
assertThat("C2 does not override I1.foo", Util.isOverridden(I1.class, C2.class, "foo"), is(false));
return null;
});
errors.checkSucceeds(() -> {
assertThat("C3 overrides I1.foo", Util.isOverridden(I1.class, C3.class, "foo"), is(true));
return null;
});
errors.checkSucceeds(() -> {
assertThat("C4 overrides I1.foo", Util.isOverridden(I1.class, C4.class, "foo"), is(true));
return null;
});
// Special case: interfaces providing default implementation of base interface
errors.checkSucceeds(() -> {
assertThat("I1 does not override I1.bar", Util.isOverridden(I1.class, I1.class, "bar"), is(false));
return null;
});
errors.checkSucceeds(() -> {
assertThat("I2 overrides I1.bar", Util.isOverridden(I1.class, I2.class, "bar"), is(true));
return null;
});
errors.checkSucceeds(() -> {
assertThat("C1 does not override I1.bar", Util.isOverridden(I1.class, C1.class, "bar"), is(false));
return null;
});
errors.checkSucceeds(() -> {
assertThat("C2 overrides I1.bar (via I2)", Util.isOverridden(I1.class, C2.class, "bar"), is(true));
return null;
});
errors.checkSucceeds(() -> {
assertThat("C3 overrides I1.bar (via I2)", Util.isOverridden(I1.class, C3.class, "bar"), is(true));
return null;
});
errors.checkSucceeds(() -> {
assertThat("C4 overrides I1.bar", Util.isOverridden(I1.class, C4.class, "bar"), is(true));
return null;
});
assertAll(
() -> assertThat("I1 does not override I1.foo", Util.isOverridden(I1.class, I1.class, "foo"), is(false)),
() -> assertThat("I2 does not override I1.foo", Util.isOverridden(I1.class, I2.class, "foo"), is(false)),
() -> assertThat("C1 does not override I1.foo", Util.isOverridden(I1.class, C1.class, "foo"), is(false)),
() -> assertThat("C2 does not override I1.foo", Util.isOverridden(I1.class, C2.class, "foo"), is(false)),
() -> assertThat("C3 overrides I1.foo", Util.isOverridden(I1.class, C3.class, "foo"), is(true)),
() -> assertThat("C4 overrides I1.foo", Util.isOverridden(I1.class, C4.class, "foo"), is(true)),
// Special case: interfaces providing default implementation of base interface
() -> assertThat("I1 does not override I1.bar", Util.isOverridden(I1.class, I1.class, "bar"), is(false)),
() -> assertThat("I2 overrides I1.bar", Util.isOverridden(I1.class, I2.class, "bar"), is(true)),
() -> assertThat("C1 does not override I1.bar", Util.isOverridden(I1.class, C1.class, "bar"), is(false)),
() -> assertThat("C2 overrides I1.bar (via I2)", Util.isOverridden(I1.class, C2.class, "bar"), is(true)),
() -> assertThat("C3 overrides I1.bar (via I2)", Util.isOverridden(I1.class, C3.class, "bar"), is(true)),
() -> assertThat("C4 overrides I1.bar", Util.isOverridden(I1.class, C4.class, "bar"), is(true))
);
}
private interface I1 {

View File

@ -28,23 +28,23 @@ import static java.util.Arrays.asList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.not;
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.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import hudson.util.Iterators.CountingPredicate;
import java.util.Iterator;
import java.util.List;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.jvnet.hudson.test.Issue;
/**
* @author Kohsuke Kawaguchi
*/
public class IteratorsTest {
class IteratorsTest {
@Test
public void reverseSequence() {
void reverseSequence() {
List<Integer> lst = Iterators.reverseSequence(1, 4);
assertEquals(3, (int) lst.get(0));
assertEquals(2, (int) lst.get(1));
@ -53,7 +53,7 @@ public class IteratorsTest {
}
@Test
public void sequence() {
void sequence() {
List<Integer> lst = Iterators.sequence(1, 4);
assertEquals(1, (int) lst.get(0));
assertEquals(2, (int) lst.get(1));
@ -62,7 +62,7 @@ public class IteratorsTest {
}
@Test
public void wrap() {
void wrap() {
List<Integer> lst = Iterators.sequence(1, 4);
Iterable<Integer> wrapped = Iterators.wrap(lst);
assertThat(wrapped, not(instanceOf(List.class)));
@ -77,7 +77,7 @@ public class IteratorsTest {
}
@Test
public void limit() {
void limit() {
assertEquals("[0]", com.google.common.collect.Iterators.toString(Iterators.limit(asList(0, 1, 2, 3, 4).iterator(), EVEN)));
assertEquals("[]", com.google.common.collect.Iterators.toString(Iterators.limit(asList(1, 2, 4, 6).iterator(), EVEN)));
}
@ -86,7 +86,7 @@ public class IteratorsTest {
@Issue("JENKINS-51779")
@Test
public void skip() {
void skip() {
List<Integer> lst = Iterators.sequence(1, 4);
Iterator<Integer> it = lst.iterator();
Iterators.skip(it, 0);

View File

@ -24,19 +24,20 @@
package hudson.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.HashMap;
import java.util.Map;
import net.sf.json.JSONObject;
import org.junit.Assert;
import org.junit.Test;
import org.junit.jupiter.api.Test;
/**
* @author <a href="mailto:tom.fennelly@gmail.com">tom.fennelly@gmail.com</a>
*/
public class JSONObjectResponseTest {
class JSONObjectResponseTest {
@Test
public void test() {
void test() {
Map<String, String> data = new HashMap<>();
data.put("val_1", "1");
@ -44,13 +45,13 @@ public class JSONObjectResponseTest {
HttpResponses.JSONObjectResponse response = new HttpResponses.JSONObjectResponse(data);
JSONObject payload = response.getJsonObject();
Assert.assertEquals("ok", payload.getString("status"));
assertEquals("ok", payload.getString("status"));
JSONObject payloadData = payload.getJSONObject("data");
Assert.assertEquals("1", payloadData.getString("val_1"));
assertEquals("1", payloadData.getString("val_1"));
// change it to an error
response.error("a message");
Assert.assertEquals("error", payload.getString("status"));
Assert.assertEquals("a message", payload.getString("message"));
assertEquals("error", payload.getString("status"));
assertEquals("a message", payload.getString("message"));
}
}

View File

@ -24,21 +24,23 @@
package hudson.util;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
/**
* @author <a href="mailto:tom.fennelly@gmail.com">tom.fennelly@gmail.com</a>
*/
public class MultipartFormDataParserTest {
class MultipartFormDataParserTest {
@Test
public void testIsMultipart() {
Assert.assertFalse("Wrongly identified \"multipart/form-data\"", MultipartFormDataParser.isMultiPartForm(null));
Assert.assertFalse("Wrongly identified \"multipart/form-data\"", MultipartFormDataParser.isMultiPartForm("blah"));
void testIsMultipart() {
assertFalse(MultipartFormDataParser.isMultiPartForm(null), "Wrongly identified \"multipart/form-data\"");
assertFalse(MultipartFormDataParser.isMultiPartForm("blah"), "Wrongly identified \"multipart/form-data\"");
Assert.assertTrue("Failed to identify \"multipart/form-data\"", MultipartFormDataParser.isMultiPartForm("multipart/form-data"));
Assert.assertTrue("Failed to identify \"multipart/form-data\"", MultipartFormDataParser.isMultiPartForm("multipart/form-data;"));
Assert.assertTrue("Failed to identify \"multipart/form-data\"", MultipartFormDataParser.isMultiPartForm("multipart/form-data; boundary=----WebKitFormBoundary8OOwv1Xp4c5XkBmD"));
assertTrue(MultipartFormDataParser.isMultiPartForm("multipart/form-data"), "Failed to identify \"multipart/form-data\"");
assertTrue(MultipartFormDataParser.isMultiPartForm("multipart/form-data;"), "Failed to identify \"multipart/form-data\"");
assertTrue(MultipartFormDataParser.isMultiPartForm("multipart/form-data; boundary=----WebKitFormBoundary8OOwv1Xp4c5XkBmD"), "Failed to identify \"multipart/form-data\"");
}
}

View File

@ -1,15 +1,15 @@
package hudson.util;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.Map;
import java.util.TreeMap;
import org.junit.Test;
import org.junit.jupiter.api.Test;
/**
* @author Kohsuke Kawaguchi
*/
public class PackedMapTest {
class PackedMapTest {
static class Holder {
PackedMap pm;
@ -18,7 +18,7 @@ public class PackedMapTest {
private XStream2 xs = new XStream2();
@Test
public void basic() {
void basic() {
Map<String, String> o = new TreeMap<>();
o.put("a", "b");
o.put("c", "d");
@ -35,18 +35,19 @@ public class PackedMapTest {
h.pm = p;
String xml = xs.toXML(h);
assertEquals(
"<hudson.util.PackedMapTest_-Holder>\n" +
" <pm>\n" +
" <entry>\n" +
" <string>a</string>\n" +
" <string>b</string>\n" +
" </entry>\n" +
" <entry>\n" +
" <string>c</string>\n" +
" <string>d</string>\n" +
" </entry>\n" +
" </pm>\n" +
"</hudson.util.PackedMapTest_-Holder>",
"""
<hudson.util.PackedMapTest_-Holder>
<pm>
<entry>
<string>a</string>
<string>b</string>
</entry>
<entry>
<string>c</string>
<string>d</string>
</entry>
</pm>
</hudson.util.PackedMapTest_-Holder>""",
xml);
xs.fromXML(xml);

View File

@ -1,38 +1,82 @@
package hudson.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import hudson.ChannelRule;
import hudson.remoting.Channel;
import hudson.remoting.ChannelBuilder;
import hudson.remoting.FastPipedInputStream;
import hudson.remoting.FastPipedOutputStream;
import hudson.remoting.VirtualChannel;
import hudson.util.ProcessTree.OSProcess;
import hudson.util.ProcessTree.ProcessCallable;
import java.io.IOException;
import java.io.Serial;
import java.io.Serializable;
import java.io.UncheckedIOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import jenkins.security.MasterToSlaveCallable;
import org.junit.Assume;
import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* @author Kohsuke Kawaguchi
*/
public class ProcessTreeTest {
class ProcessTreeTest {
@Rule public ChannelRule channels = new ChannelRule();
/**
* Two channels that are connected to each other, but shares the same classloader.
*/
private Channel french;
private Channel british;
private ExecutorService executors;
@BeforeEach
void setUp() throws Exception {
executors = Executors.newCachedThreadPool();
final FastPipedInputStream p1i = new FastPipedInputStream();
final FastPipedInputStream p2i = new FastPipedInputStream();
final FastPipedOutputStream p1o = new FastPipedOutputStream(p1i);
final FastPipedOutputStream p2o = new FastPipedOutputStream(p2i);
Future<Channel> f1 = executors.submit(() -> new ChannelBuilder("This side of the channel", executors).withMode(Channel.Mode.BINARY).build(p1i, p2o));
Future<Channel> f2 = executors.submit(() -> new ChannelBuilder("The other side of the channel", executors).withMode(Channel.Mode.BINARY).build(p2i, p1o));
french = f1.get();
british = f2.get();
}
@AfterEach
void tearDown() {
try {
french.close(); // this will automatically initiate the close on the other channel, too.
french.join();
british.join();
} catch (IOException e) {
throw new UncheckedIOException(e);
} catch (InterruptedException x) {
throw new AssertionError(x);
}
executors.shutdownNow();
}
static class Tag implements Serializable {
ProcessTree tree;
OSProcess p;
int id;
@Serial
private static final long serialVersionUID = 1L;
}
@Test public void remoting() throws Exception {
Assume.assumeFalse("on some platforms where we fail to list any processes", ProcessTree.get() == ProcessTree.DEFAULT);
@Test
void remoting() throws Exception {
Assumptions.assumeFalse(ProcessTree.get() == ProcessTree.DEFAULT, "on some platforms where we fail to list any processes");
Tag t = channels.french.call(new MyCallable());
Tag t = french.call(new MyCallable());
// make sure the serialization preserved the reference graph
assertSame(t.p.getTree(), t.tree);
@ -56,6 +100,7 @@ public class ProcessTreeTest {
return t;
}
@Serial
private static final long serialVersionUID = 1L;
}

View File

@ -1,7 +1,9 @@
package hudson.util;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.time.Duration;
@ -9,14 +11,13 @@ import java.time.Instant;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.Assert;
import org.junit.Test;
import org.junit.jupiter.api.Test;
public class RetrierTest {
class RetrierTest {
private static final Logger LOG = Logger.getLogger(RetrierTest.class.getName());
@Test
public void performedAtThirdAttemptTest() throws Exception {
void performedAtThirdAttemptTest() throws Exception {
final int SUCCESSFUL_ATTEMPT = 3;
final String ACTION = "print";
@ -45,14 +46,14 @@ public class RetrierTest {
// Begin the process
Boolean finalResult = r.start();
Assert.assertTrue(finalResult != null && finalResult);
assertTrue(finalResult != null && finalResult);
String text = Messages.Retrier_Success(ACTION, SUCCESSFUL_ATTEMPT);
assertTrue(String.format("The log should contain '%s'", text), handler.getView().stream().anyMatch(m -> m.getMessage().contains(text)));
assertTrue(handler.getView().stream().anyMatch(m -> m.getMessage().contains(text)), String.format("The log should contain '%s'", text));
}
@Test
public void sleepWorksTest() throws Exception {
void sleepWorksTest() throws Exception {
final int SUCCESSFUL_ATTEMPT = 2;
final String ACTION = "print";
final int SLEEP = 500;
@ -94,21 +95,21 @@ public class RetrierTest {
long timeElapsed = Duration.between(start, finish).toMillis();
// Check delay works
Assert.assertTrue(timeElapsed >= SLEEP);
assertTrue(timeElapsed >= SLEEP);
// Check result is true
Assert.assertTrue(finalResult != null && finalResult);
assertTrue(finalResult != null && finalResult);
// Check the log tell us the sleep time
String text = Messages.Retrier_Sleeping(SLEEP, ACTION);
assertTrue(String.format("The log should contain '%s'", text), handler.getView().stream().anyMatch(m -> m.getMessage().contains(text)));
assertTrue(handler.getView().stream().anyMatch(m -> m.getMessage().contains(text)), String.format("The log should contain '%s'", text));
// recover log level
retrierLogger.setLevel(currentLogLevel);
}
@Test
public void failedActionAfterThreeAttemptsTest() throws Exception {
void failedActionAfterThreeAttemptsTest() throws Exception {
final int ATTEMPTS = 3;
final String ACTION = "print";
@ -138,15 +139,15 @@ public class RetrierTest {
// Begin the process
Boolean finalResult = r.start();
Assert.assertFalse(finalResult != null && finalResult);
assertFalse(finalResult != null && finalResult);
String text = Messages.Retrier_NoSuccess(ACTION, ATTEMPTS);
assertTrue(String.format("The log should contain '%s'", text), handler.getView().stream().anyMatch(m -> m.getMessage().contains(text)));
assertTrue(handler.getView().stream().anyMatch(m -> m.getMessage().contains(text)), String.format("The log should contain '%s'", text));
}
@Test
public void failedActionWithExceptionAfterThreeAttemptsWithoutListenerTest() throws Exception {
void failedActionWithExceptionAfterThreeAttemptsWithoutListenerTest() throws Exception {
final int ATTEMPTS = 3;
final String ACTION = "print";
@ -174,18 +175,18 @@ public class RetrierTest {
// Begin the process without catching the allowed exceptions
Boolean finalResult = r.start();
Assert.assertNull(finalResult);
assertNull(finalResult);
String textNoSuccess = Messages.Retrier_NoSuccess(ACTION, ATTEMPTS);
assertTrue(String.format("The log should contain '%s'", textNoSuccess), handler.getView().stream().anyMatch(m -> m.getMessage().contains(textNoSuccess)));
assertTrue(handler.getView().stream().anyMatch(m -> m.getMessage().contains(textNoSuccess)), String.format("The log should contain '%s'", textNoSuccess));
String testException = Messages.Retrier_ExceptionFailed(ATTEMPTS, ACTION);
assertTrue(String.format("The log should contain '%s'", testException), handler.getView().stream().anyMatch(m -> m.getMessage().startsWith(testException)));
assertTrue(handler.getView().stream().anyMatch(m -> m.getMessage().startsWith(testException)), String.format("The log should contain '%s'", testException));
}
@Test
public void failedActionWithAllowedExceptionWithListenerChangingResultTest() throws Exception {
void failedActionWithAllowedExceptionWithListenerChangingResultTest() throws Exception {
final int ATTEMPTS = 1;
final String ACTION = "print";
@ -215,19 +216,19 @@ public class RetrierTest {
// Begin the process catching the allowed exception
Boolean finalResult = r.start();
Assert.assertTrue(finalResult != null && finalResult);
assertTrue(finalResult != null && finalResult);
// The action was a success
String textSuccess = Messages.Retrier_Success(ACTION, ATTEMPTS);
assertTrue(String.format("The log should contain '%s'", textSuccess), handler.getView().stream().anyMatch(m -> m.getMessage().contains(textSuccess)));
assertTrue(handler.getView().stream().anyMatch(m -> m.getMessage().contains(textSuccess)), String.format("The log should contain '%s'", textSuccess));
// And the message talking about the allowed raised is also there
String testException = Messages.Retrier_ExceptionFailed(ATTEMPTS, ACTION);
assertTrue(String.format("The log should contain '%s'", testException), handler.getView().stream().anyMatch(m -> m.getMessage().startsWith(testException)));
assertTrue(handler.getView().stream().anyMatch(m -> m.getMessage().startsWith(testException)), String.format("The log should contain '%s'", testException));
}
@Test
public void failedActionWithAllowedExceptionByInheritanceTest() throws Exception {
void failedActionWithAllowedExceptionByInheritanceTest() throws Exception {
final int ATTEMPTS = 1;
final String ACTION = "print";
@ -258,19 +259,19 @@ public class RetrierTest {
// Begin the process catching the allowed exception
Boolean finalResult = r.start();
Assert.assertTrue(finalResult != null && finalResult);
assertTrue(finalResult != null && finalResult);
// The action was a success
String textSuccess = Messages.Retrier_Success(ACTION, ATTEMPTS);
assertTrue(String.format("The log should contain '%s'", textSuccess), handler.getView().stream().anyMatch(m -> m.getMessage().contains(textSuccess)));
assertTrue(handler.getView().stream().anyMatch(m -> m.getMessage().contains(textSuccess)), String.format("The log should contain '%s'", textSuccess));
// And the message talking about the allowed raised is also there
String testException = Messages.Retrier_ExceptionFailed(ATTEMPTS, ACTION);
assertTrue(String.format("The log should contain '%s'", testException), handler.getView().stream().anyMatch(m -> m.getMessage().startsWith(testException)));
assertTrue(handler.getView().stream().anyMatch(m -> m.getMessage().startsWith(testException)), String.format("The log should contain '%s'", testException));
}
@Test
public void failedActionWithUnAllowedExceptionTest() {
void failedActionWithUnAllowedExceptionTest() {
final int ATTEMPTS = 1;
final String ACTION = "print";
@ -298,8 +299,8 @@ public class RetrierTest {
.build();
// Begin the process that raises an unexpected exception
assertThrows("The process should be exited with an unexpected exception", IOException.class, r::start);
assertThrows(IOException.class, r::start, "The process should be exited with an unexpected exception");
String testFailure = Messages.Retrier_ExceptionThrown(ATTEMPTS, ACTION);
assertTrue(String.format("The log should contain '%s'", testFailure), handler.getView().stream().anyMatch(m -> m.getMessage().contains(testFailure)));
assertTrue(handler.getView().stream().anyMatch(m -> m.getMessage().contains(testFailure)), String.format("The log should contain '%s'", testFailure));
}
}

View File

@ -26,10 +26,10 @@ package hudson.util;
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.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.thoughtworks.xstream.security.InputManipulationException;
import hudson.model.Saveable;
@ -43,27 +43,29 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import jenkins.util.xstream.CriticalXStreamException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
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.Issue;
public class RobustCollectionConverterTest {
class RobustCollectionConverterTest {
private final boolean originalRecordFailures = RobustReflectionConverter.RECORD_FAILURES_FOR_ALL_AUTHENTICATIONS;
@Before
public void before() {
@BeforeEach
void before() {
RobustReflectionConverter.RECORD_FAILURES_FOR_ALL_AUTHENTICATIONS = true;
}
@After
public void after() {
@AfterEach
void after() {
RobustReflectionConverter.RECORD_FAILURES_FOR_ALL_AUTHENTICATIONS = originalRecordFailures;
}
@Test
public void workingByDefaultWithSimplePayload() {
void workingByDefaultWithSimplePayload() {
XStream2 xstream2 = new XStream2();
Map<String, String> map = new HashMap<>();
@ -91,9 +93,10 @@ public class RobustCollectionConverterTest {
* We had to patch it in order to not be impacted by CVE-2021-43859
*/
// force timeout to prevent DoS due to test in the case the DoS prevention is broken
@Test(timeout = 30 * 1000)
@Test
@Timeout(value = 30 * 1000, unit = TimeUnit.MILLISECONDS)
@Issue("SECURITY-2602")
public void dosIsPrevented_customProgrammaticallyTimeout() {
void dosIsPrevented_customProgrammaticallyTimeout() {
XStream2 xstream2 = new XStream2();
Set<Object> set = preparePayload();
@ -105,12 +108,13 @@ public class RobustCollectionConverterTest {
assertNotNull(cause);
assertThat(cause, instanceOf(InputManipulationException.class));
InputManipulationException ime = (InputManipulationException) cause;
assertTrue("Limit expected in message", ime.getMessage().contains("exceeds 3 seconds"));
assertTrue(ime.getMessage().contains("exceeds 3 seconds"), "Limit expected in message");
}
@Test(timeout = 30 * 1000)
@Test
@Timeout(value = 30 * 1000, unit = TimeUnit.MILLISECONDS)
@Issue("SECURITY-2602")
public void dosIsPrevented_customPropertyTimeout() {
void dosIsPrevented_customPropertyTimeout() {
String currentValue = System.getProperty(XStream2.COLLECTION_UPDATE_LIMIT_PROPERTY_NAME);
try {
System.setProperty(XStream2.COLLECTION_UPDATE_LIMIT_PROPERTY_NAME, "4");
@ -125,7 +129,7 @@ public class RobustCollectionConverterTest {
assertNotNull(cause);
assertThat(cause, instanceOf(InputManipulationException.class));
InputManipulationException ime = (InputManipulationException) cause;
assertTrue("Limit expected in message", ime.getMessage().contains("exceeds 4 seconds"));
assertTrue(ime.getMessage().contains("exceeds 4 seconds"), "Limit expected in message");
} finally {
if (currentValue == null) {
System.clearProperty(XStream2.COLLECTION_UPDATE_LIMIT_PROPERTY_NAME);
@ -136,9 +140,10 @@ public class RobustCollectionConverterTest {
}
// force timeout to prevent DoS due to test in the case the DoS prevention is broken
@Test(timeout = 30 * 1000)
@Test
@Timeout(value = 30 * 1000, unit = TimeUnit.MILLISECONDS)
@Issue("SECURITY-2602")
public void dosIsPrevented_defaultTimeout() {
void dosIsPrevented_defaultTimeout() {
XStream2 xstream2 = new XStream2();
Set<Object> set = preparePayload();
@ -149,7 +154,7 @@ public class RobustCollectionConverterTest {
assertNotNull(cause);
assertThat(cause, instanceOf(InputManipulationException.class));
InputManipulationException ime = (InputManipulationException) cause;
assertTrue("Limit expected in message", ime.getMessage().contains("exceeds 5 seconds"));
assertTrue(ime.getMessage().contains("exceeds 5 seconds"), "Limit expected in message");
}
// Inspired by https://github.com/x-stream/xstream/commit/e8e88621ba1c85ac3b8620337dd672e0c0c3a846#diff-9fde4ecf1bb4dc9850c031cb161960d2e61e069b386fa0b3db0d57e0e9f5baa
@ -192,7 +197,7 @@ public class RobustCollectionConverterTest {
@Issue("JENKINS-63343")
@Test
public void checkElementTypes() {
void checkElementTypes() {
var xmlContent =
"""
<hudson.util.RobustCollectionConverterTest_-Data>
@ -210,7 +215,7 @@ public class RobustCollectionConverterTest {
}
@Test
public void rawtypes() {
void rawtypes() {
var xmlContent =
"""
<hudson.util.RobustCollectionConverterTest_-DataRaw>

View File

@ -27,31 +27,33 @@ package hudson.util;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.thoughtworks.xstream.security.InputManipulationException;
import hudson.model.Saveable;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import jenkins.util.xstream.CriticalXStreamException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
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.Issue;
public class RobustMapConverterTest {
class RobustMapConverterTest {
private final boolean originalRecordFailures = RobustReflectionConverter.RECORD_FAILURES_FOR_ALL_AUTHENTICATIONS;
@Before
public void before() {
@BeforeEach
void before() {
RobustReflectionConverter.RECORD_FAILURES_FOR_ALL_AUTHENTICATIONS = true;
}
@After
public void after() {
@AfterEach
void after() {
RobustReflectionConverter.RECORD_FAILURES_FOR_ALL_AUTHENTICATIONS = originalRecordFailures;
}
@ -60,9 +62,10 @@ public class RobustMapConverterTest {
* We had to patch it in order to not be impacted by CVE-2021-43859
*/
// force timeout to prevent DoS due to test in the case the DoS prevention is broken
@Test(timeout = 30 * 1000)
@Test
@Timeout(value = 30 * 1000, unit = TimeUnit.MILLISECONDS)
@Issue("SECURITY-2602")
public void dosIsPrevented_customProgrammaticallyTimeout() {
void dosIsPrevented_customProgrammaticallyTimeout() {
XStream2 xstream2 = new XStream2();
Map<Object, Object> map = preparePayload();
@ -75,12 +78,13 @@ public class RobustMapConverterTest {
assertNotNull(cause);
assertThat(cause, instanceOf(InputManipulationException.class));
InputManipulationException ime = (InputManipulationException) cause;
assertTrue("Limit expected in message", ime.getMessage().contains("exceeds 3 seconds"));
assertTrue(ime.getMessage().contains("exceeds 3 seconds"), "Limit expected in message");
}
@Test(timeout = 30 * 1000)
@Test
@Timeout(value = 30 * 1000, unit = TimeUnit.MILLISECONDS)
@Issue("SECURITY-2602")
public void dosIsPrevented_customPropertyTimeout() {
void dosIsPrevented_customPropertyTimeout() {
String currentValue = System.getProperty(XStream2.COLLECTION_UPDATE_LIMIT_PROPERTY_NAME);
try {
System.setProperty(XStream2.COLLECTION_UPDATE_LIMIT_PROPERTY_NAME, "4");
@ -95,7 +99,7 @@ public class RobustMapConverterTest {
assertNotNull(cause);
assertThat(cause, instanceOf(InputManipulationException.class));
InputManipulationException ime = (InputManipulationException) cause;
assertTrue("Limit expected in message", ime.getMessage().contains("exceeds 4 seconds"));
assertTrue(ime.getMessage().contains("exceeds 4 seconds"), "Limit expected in message");
} finally {
if (currentValue == null) {
System.clearProperty(XStream2.COLLECTION_UPDATE_LIMIT_PROPERTY_NAME);
@ -106,9 +110,10 @@ public class RobustMapConverterTest {
}
// force timeout to prevent DoS due to test in the case the DoS prevention is broken
@Test(timeout = 30 * 1000)
@Test
@Timeout(value = 30 * 1000, unit = TimeUnit.MILLISECONDS)
@Issue("SECURITY-2602")
public void dosIsPrevented_defaultTimeout() {
void dosIsPrevented_defaultTimeout() {
XStream2 xstream2 = new XStream2();
Map<Object, Object> map = preparePayload();
@ -119,7 +124,7 @@ public class RobustMapConverterTest {
assertNotNull(cause);
assertThat(cause, instanceOf(InputManipulationException.class));
InputManipulationException ime = (InputManipulationException) cause;
assertTrue("Limit expected in message", ime.getMessage().contains("exceeds 5 seconds"));
assertTrue(ime.getMessage().contains("exceeds 5 seconds"), "Limit expected in message");
}
// Inspired by https://github.com/x-stream/xstream/commit/e8e88621ba1c85ac3b8620337dd672e0c0c3a846#diff-9fde4ecf1bb4dc9850c031cb161960d2e61e069b386fa0b3db0d57e0e9f5baa
@ -161,7 +166,7 @@ public class RobustMapConverterTest {
}
@Test
public void robustAgainstInvalidEntry() {
void robustAgainstInvalidEntry() {
RobustReflectionConverter.RECORD_FAILURES_FOR_ALL_AUTHENTICATIONS = true;
XStream2 xstream2 = new XStream2();
String xml =
@ -181,7 +186,7 @@ public class RobustMapConverterTest {
}
@Test
public void robustAgainstInvalidEntryWithNoValue() {
void robustAgainstInvalidEntryWithNoValue() {
XStream2 xstream2 = new XStream2();
String xml =
"""
@ -203,7 +208,7 @@ public class RobustMapConverterTest {
@Issue("JENKINS-63343")
@Test
public void robustAgainstInvalidKeyType() {
void robustAgainstInvalidKeyType() {
XStream2 xstream2 = new XStream2();
String xml =
"""
@ -233,7 +238,7 @@ public class RobustMapConverterTest {
@Issue("JENKINS-63343")
@Test
public void robustAgainstInvalidValueType() {
void robustAgainstInvalidValueType() {
XStream2 xstream2 = new XStream2();
String xml =
"""
@ -262,7 +267,7 @@ public class RobustMapConverterTest {
}
@Test
public void rawtypes() {
void rawtypes() {
XStream2 xstream2 = new XStream2();
String xml =
"""

View File

@ -28,10 +28,10 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.ConversionException;
@ -51,38 +51,40 @@ import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import jenkins.util.xstream.CriticalXStreamException;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
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.junit.jupiter.api.Timeout;
import org.jvnet.hudson.test.Issue;
/**
* @author Kohsuke Kawaguchi
*/
public class RobustReflectionConverterTest {
class RobustReflectionConverterTest {
private final boolean originalRecordFailures = RobustReflectionConverter.RECORD_FAILURES_FOR_ALL_AUTHENTICATIONS;
static {
Logger.getLogger(RobustReflectionConverter.class.getName()).setLevel(Level.OFF);
}
@Before
public void before() {
@BeforeEach
void before() {
RobustReflectionConverter.RECORD_FAILURES_FOR_ALL_AUTHENTICATIONS = true;
}
@After
public void after() {
@AfterEach
void after() {
RobustReflectionConverter.RECORD_FAILURES_FOR_ALL_AUTHENTICATIONS = originalRecordFailures;
}
@Test
public void robustUnmarshalling() {
void robustUnmarshalling() {
Point p = read(new XStream2());
assertEquals(1, p.x);
assertEquals(2, p.y);
@ -94,7 +96,7 @@ public class RobustReflectionConverterTest {
}
@Test
public void ifWorkaroundNeeded() {
void ifWorkaroundNeeded() {
XStream xs = new XStream(XStream2.getDefaultDriver());
xs.allowTypes(new Class[] {Point.class});
final ConversionException e = assertThrows(ConversionException.class, () -> read(xs));
@ -102,7 +104,7 @@ public class RobustReflectionConverterTest {
}
@Test
public void classOwnership() {
void classOwnership() {
Enchufla s1 = new Enchufla();
s1.number = 1;
s1.direction = "North";
@ -137,35 +139,37 @@ public class RobustReflectionConverterTest {
}
@Test
public void implicitCollection() {
void implicitCollection() {
XStream2 xs = new XStream2();
xs.alias("hold", Hold.class);
xs.addImplicitCollection(Hold.class, "items", "item", String.class);
Hold h = (Hold) xs.fromXML("<hold><item>a</item><item>b</item></hold>");
assertThat(h.items, Matchers.containsInAnyOrder("a", "b"));
assertEquals("<hold>\n" +
" <item>a</item>\n" +
" <item>b</item>\n" +
"</hold>", xs.toXML(h));
assertEquals("""
<hold>
<item>a</item>
<item>b</item>
</hold>""", xs.toXML(h));
}
@Ignore("Throws an NPE in writeValueToImplicitCollection. Issue has existed since RobustReflectionConverter was created.")
@Disabled("Throws an NPE in writeValueToImplicitCollection. Issue has existed since RobustReflectionConverter was created.")
@Test
public void implicitCollectionsAllowNullElements() {
void implicitCollectionsAllowNullElements() {
XStream2 xs = new XStream2();
xs.alias("hold", Hold.class);
xs.addImplicitCollection(Hold.class, "items", "item", String.class);
Hold h = (Hold) xs.fromXML("<hold><null/><item>b</item></hold>");
assertThat(h.items, Matchers.containsInAnyOrder(null, "b"));
assertEquals("<hold>\n" +
" <null/>\n" +
" <item>b</item>\n" +
"</hold>", xs.toXML(h));
assertEquals("""
<hold>
<null/>
<item>b</item>
</hold>""", xs.toXML(h));
}
@Issue("JENKINS-63343")
@Test
public void robustAgainstImplicitCollectionElementsWithBadTypes() {
void robustAgainstImplicitCollectionElementsWithBadTypes() {
XStream2 xs = new XStream2();
xs.alias("hold", Hold.class);
// Note that the fix only matters for `addImplicitCollection` overloads like the following where the element type is not provided.
@ -186,13 +190,13 @@ public class RobustReflectionConverterTest {
List<String> items;
@Override
public void save() throws IOException {
public void save() {
// We only implement Saveable so that RobustReflectionConverter logs deserialization problems.
}
}
@Test
public void implicitCollectionRawtypes() {
void implicitCollectionRawtypes() {
XStream2 xs = new XStream2();
xs.alias("hold", HoldRaw.class);
xs.addImplicitCollection(HoldRaw.class, "items");
@ -259,9 +263,10 @@ public class RobustReflectionConverterTest {
@Owner("p4")
public static class Jean extends Lover {}
@Test(timeout = 30 * 1000)
@Test
@Timeout(value = 30 * 1000, unit = TimeUnit.MILLISECONDS)
@Issue("SECURITY-2602")
public void robustDoesNotSwallowDosException() {
void robustDoesNotSwallowDosException() {
XStream2 xstream2 = new XStream2();
Set<Object> set = preparePayload();
@ -280,11 +285,12 @@ public class RobustReflectionConverterTest {
assertNotNull(cause);
assertThat(cause, instanceOf(InputManipulationException.class));
InputManipulationException ime = (InputManipulationException) cause;
assertTrue("Limit expected in message", ime.getMessage().contains("exceeds 5 seconds"));
assertTrue(ime.getMessage().contains("exceeds 5 seconds"), "Limit expected in message");
}
@Test(timeout = 30 * 1000)
public void customConverter_useDefaultXStreamException() {
@Test
@Timeout(value = 30 * 1000, unit = TimeUnit.MILLISECONDS)
void customConverter_useDefaultXStreamException() {
XStream2 xstream2 = new XStream2();
xstream2.registerConverter(new CustomSet.ConverterImpl(xstream2.getMapper()));
@ -294,12 +300,13 @@ public class RobustReflectionConverterTest {
final String xml = xstream2.toXML(customSet);
InputManipulationException e = assertThrows(InputManipulationException.class, () -> xstream2.fromXML(xml));
assertTrue("Limit expected in message", e.getMessage().contains("exceeds 5 seconds"));
assertTrue(e.getMessage().contains("exceeds 5 seconds"), "Limit expected in message");
}
@Test(timeout = 30 * 1000)
@Test
@Timeout(value = 30 * 1000, unit = TimeUnit.MILLISECONDS)
@Issue("SECURITY-2602")
public void customConverter_wrapped_useCriticalXStreamException() {
void customConverter_wrapped_useCriticalXStreamException() {
XStream2 xstream2 = new XStream2();
xstream2.registerConverter(new CustomSet.ConverterImpl(xstream2.getMapper())); // TODO Fix test so it does not pass without this
@ -319,7 +326,7 @@ public class RobustReflectionConverterTest {
assertNotNull(cause);
assertThat(cause, instanceOf(InputManipulationException.class));
InputManipulationException ime = (InputManipulationException) cause;
assertTrue("Limit expected in message", ime.getMessage().contains("exceeds 5 seconds"));
assertTrue(ime.getMessage().contains("exceeds 5 seconds"), "Limit expected in message");
}
private Set<Object> preparePayload() {

View File

@ -24,19 +24,19 @@
package hudson.util;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import hudson.model.Run;
import java.util.ArrayList;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.jvnet.hudson.test.Issue;
/**
* @author Ignacio Albors
*/
public class RunListTest {
class RunListTest {
// RunList for byTimestamp tests
private RunList rlist;
@ -60,7 +60,7 @@ public class RunListTest {
}
@Test
public void byTimestampAllRuns() {
void byTimestampAllRuns() {
setUpByTimestampRuns();
RunList<Run> tested = rlist.byTimestamp(0, 400);
@ -70,7 +70,7 @@ public class RunListTest {
@Issue("JENKINS-21159")
@Test
@SuppressWarnings("deprecation")
public void byTimestampFirstRun() {
void byTimestampFirstRun() {
setUpByTimestampRuns();
// Only r1
RunList<Run> tested = rlist.byTimestamp(150, 250);
@ -80,7 +80,7 @@ public class RunListTest {
@Test
@SuppressWarnings("deprecation")
public void byTimestampLastRun() {
void byTimestampLastRun() {
setUpByTimestampRuns();
// Only r2
RunList<Run> tested = rlist.byTimestamp(250, 350);

View File

@ -27,10 +27,10 @@ package hudson.util;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
@ -39,19 +39,21 @@ import java.util.regex.Pattern;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import jenkins.model.Jenkins;
import jenkins.security.ConfidentialStoreRule;
import org.junit.Rule;
import org.junit.Test;
import jenkins.security.ConfidentialStore;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class SecretTest {
@Rule
public ConfidentialStoreRule confidentialStore = new ConfidentialStoreRule();
class SecretTest {
private static final Pattern ENCRYPTED_VALUE_PATTERN = Pattern.compile("\\{?[A-Za-z0-9+/]+={0,2}}?");
@BeforeEach
void setUp() {
ConfidentialStore.Mock.INSTANCE.clear();
}
@Test
public void encrypt() {
void encrypt() {
Secret secret = Secret.fromString("abc");
assertEquals("abc", secret.getPlainText());
@ -68,7 +70,7 @@ public class SecretTest {
}
@Test
public void encryptedValuePattern() {
void encryptedValuePattern() {
final Random random = new Random();
for (int i = 1; i < 100; i++) {
String plaintext = random(i, random);
@ -95,20 +97,20 @@ public class SecretTest {
}
@Test
public void decrypt() {
void decrypt() {
assertEquals("abc", Secret.toString(Secret.fromString("abc")));
}
@Test
public void serialization() {
void serialization() {
Secret s = Secret.fromString("Mr.Jenkins");
String xml = Jenkins.XSTREAM.toXML(s);
assertThat(xml, not(containsString(s.getPlainText())));
// TODO MatchesPattern not available until Hamcrest 2.0
assertTrue(xml, xml.matches("<hudson[.]util[.]Secret>[{][A-Za-z0-9+/]+={0,2}[}]</hudson[.]util[.]Secret>"));
assertTrue(xml.matches("<hudson[.]util[.]Secret>[{][A-Za-z0-9+/]+={0,2}[}]</hudson[.]util[.]Secret>"), xml);
Object o = Jenkins.XSTREAM.fromXML(xml);
assertEquals(xml, s, o);
assertEquals(s, o, xml);
}
public static class Foo {
@ -119,7 +121,7 @@ public class SecretTest {
* Makes sure the serialization form is backward compatible with String.
*/
@Test
public void testCompatibilityFromString() {
void testCompatibilityFromString() {
String tagName = Foo.class.getName().replace("$", "_-");
String xml = "<" + tagName + "><password>secret</password></" + tagName + ">";
Foo foo = new Foo();
@ -132,15 +134,15 @@ public class SecretTest {
*/
@Test
@SuppressWarnings("deprecation")
public void migrationFromLegacyKeyToConfidentialStore() throws Exception {
void migrationFromLegacyKeyToConfidentialStore() throws Exception {
SecretKey legacy = HistoricalSecrets.getLegacyKey();
for (String str : new String[] {"Hello world", "", "\u0000unprintable"}) {
Cipher cipher = Secret.getCipher("AES");
cipher.init(Cipher.ENCRYPT_MODE, legacy);
String old = Base64.getEncoder().encodeToString(cipher.doFinal((str + HistoricalSecrets.MAGIC).getBytes(StandardCharsets.UTF_8)));
Secret s = Secret.fromString(old);
assertEquals("secret by the old key should decrypt", str, s.getPlainText());
assertNotEquals("but when encrypting, ConfidentialKey should be in use", old, s.getEncryptedValue());
assertEquals(str, s.getPlainText(), "secret by the old key should decrypt");
assertNotEquals(old, s.getEncryptedValue(), "but when encrypting, ConfidentialKey should be in use");
}
}

View File

@ -1,41 +1,42 @@
package hudson.util;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertNull;
import org.junit.jupiter.api.Test;
import org.jvnet.hudson.test.Issue;
public class SecretUtilTest {
class SecretUtilTest {
@Issue("JENKINS-47500")
@Test
public void decrypt() {
void decrypt() {
String data = "{}";
Secret secret = Secret.decrypt(data);
Assert.assertNull(secret); // expected to not throw ArrayIndexOutOfBoundsException
assertNull(secret); // expected to not throw ArrayIndexOutOfBoundsException
}
@Issue("JENKINS-47500")
@Test
public void decryptJustSpace() {
void decryptJustSpace() {
String data = " ";
Secret secret = Secret.decrypt(data);
Assert.assertNull(secret); // expected to not throw ArrayIndexOutOfBoundsException
assertNull(secret); // expected to not throw ArrayIndexOutOfBoundsException
}
@Issue("JENKINS-47500")
@Test
public void decryptWithSpace() {
void decryptWithSpace() {
String data = "{ }";
Secret secret = Secret.decrypt(data);
Assert.assertNull(secret); // expected to not throw ArrayIndexOutOfBoundsException
assertNull(secret); // expected to not throw ArrayIndexOutOfBoundsException
}
@Issue("JENKINS-47500")
@Test
public void decryptWithSpaces() {
void decryptWithSpaces() {
String data = "{ }";
Secret secret = Secret.decrypt(data);
Assert.assertNull(secret); // expected to not throw ArrayIndexOutOfBoundsException
assertNull(secret); // expected to not throw ArrayIndexOutOfBoundsException
}
}

View File

@ -1,6 +1,6 @@
package hudson.util;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.File;
import java.io.FileOutputStream;
@ -8,18 +8,17 @@ import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.file.Files;
import org.apache.commons.io.FileUtils;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
public class TextFileTest {
class TextFileTest {
@Rule
public TemporaryFolder tmp = new TemporaryFolder();
@TempDir
private File tmp;
@Test
public void head() throws Exception {
File f = tmp.newFile();
void head() throws Exception {
File f = File.createTempFile("junit", null, tmp);
FileUtils.copyURLToFile(getClass().getResource("ascii.txt"), f);
TextFile t = new TextFile(f);
@ -29,8 +28,8 @@ public class TextFileTest {
}
@Test
public void shortHead() throws Exception {
File f = tmp.newFile();
void shortHead() throws Exception {
File f = File.createTempFile("junit", null, tmp);
Files.writeString(f.toPath(), "hello", Charset.defaultCharset());
TextFile t = new TextFile(f);
@ -38,8 +37,8 @@ public class TextFileTest {
}
@Test
public void tail() throws Exception {
File f = tmp.newFile();
void tail() throws Exception {
File f = File.createTempFile("junit", null, tmp);
FileUtils.copyURLToFile(getClass().getResource("ascii.txt"), f);
String whole = Files.readString(f.toPath(), Charset.defaultCharset());
TextFile t = new TextFile(f);
@ -48,8 +47,8 @@ public class TextFileTest {
}
@Test
public void shortTail() throws Exception {
File f = tmp.newFile();
void shortTail() throws Exception {
File f = File.createTempFile("junit", null, tmp);
Files.writeString(f.toPath(), "hello", Charset.defaultCharset());
TextFile t = new TextFile(f);
@ -63,8 +62,8 @@ public class TextFileTest {
* careful, we'll parse the text incorrectly.
*/
@Test
public void tailShiftJIS() throws Exception {
File f = tmp.newFile();
void tailShiftJIS() throws Exception {
File f = File.createTempFile("junit", null, tmp);
TextFile t = new TextFile(f);

View File

@ -27,25 +27,24 @@ package hudson.util;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assume.assumeNoException;
import static org.junit.Assume.assumeThat;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import org.junit.Test;
import org.junit.jupiter.api.Test;
/**
* In its own suite to minimize the chance of mucking about with other tests.
*/
public class XStream2EncodingTest {
class XStream2EncodingTest {
private static void useNonUTF8() {
clearDefaultEncoding();
System.setProperty("file.encoding", "ISO-8859-1");
assumeThat(Charset.defaultCharset().name(), is("ISO-8859-1"));
assumeTrue(Charset.defaultCharset().name().equals("ISO-8859-1"));
}
private static void clearDefaultEncodingAfter() {
@ -59,12 +58,13 @@ public class XStream2EncodingTest {
defaultCharset.set(null, null);
} catch (Exception x) {
// Per JDK-4163515, this is not supported. It happened to work prior to Java 17, though.
assumeNoException(x);
assumeTrue(false, x.toString());
}
}
@SuppressWarnings("deprecation")
@Test public void toXMLUnspecifiedEncoding() throws Exception {
@Test
void toXMLUnspecifiedEncoding() throws Exception {
useNonUTF8();
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@ -84,7 +84,8 @@ public class XStream2EncodingTest {
}
}
@Test public void toXMLUTF8() throws Exception {
@Test
void toXMLUTF8() throws Exception {
useNonUTF8();
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();

View File

@ -28,12 +28,12 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
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.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@ -55,26 +55,26 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import jenkins.model.Jenkins;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.jvnet.hudson.test.Issue;
/**
* Tests for XML serialization of java objects.
* @author Kohsuke Kawaguchi, Mike Dillon, Alan Harder, Richard Mortimer
*/
public class XStream2Test {
class XStream2Test {
public static final class Foo {
Result r1, r2;
}
@Test
public void marshalValue() {
void marshalValue() {
Foo f = new Foo();
f.r1 = f.r2 = Result.FAILURE;
String xml = Run.XSTREAM.toXML(f);
// we should find two "FAILURE"s as they should be written out twice
assertEquals(xml, 3, xml.split("FAILURE").length);
assertEquals(3, xml.split("FAILURE").length, xml);
}
private static class Bar {
@ -85,7 +85,7 @@ public class XStream2Test {
* Test ability to read old XML from Hudson 1.105 or older.
*/
@Test
public void xStream11Compatibility() {
void xStream11Compatibility() {
Bar b = (Bar) new XStream2().fromXML(
"<hudson.util.XStream2Test-Bar><s>foo</s></hudson.util.XStream2Test-Bar>");
assertEquals("foo", b.s);
@ -102,19 +102,19 @@ public class XStream2Test {
*/
@Issue("JENKINS-5768")
@Test
public void xmlRoundTrip() {
void xmlRoundTrip() {
XStream2 xs = new XStream2();
__Foo_Bar$Class b = new __Foo_Bar$Class();
String xml = xs.toXML(b);
__Foo_Bar$Class b2 = (__Foo_Bar$Class) xs.fromXML(xml);
assertEquals(xml, b.under_1, b2.under_1);
assertEquals(xml, b.under__2, b2.under__2);
assertEquals(xml, b._leadUnder1, b2._leadUnder1);
assertEquals(xml, b.__leadUnder2, b2.__leadUnder2);
assertEquals(xml, b.$dollar, b2.$dollar);
assertEquals(xml, b.dollar$2, b2.dollar$2);
assertEquals(b.under_1, b2.under_1, xml);
assertEquals(b.under__2, b2.under__2, xml);
assertEquals(b._leadUnder1, b2._leadUnder1, xml);
assertEquals(b.__leadUnder2, b2.__leadUnder2, xml);
assertEquals(b.$dollar, b2.$dollar, xml);
assertEquals(b.dollar$2, b2.dollar$2, xml);
}
private static class Baz {
@ -128,7 +128,7 @@ public class XStream2Test {
*/
@Issue("JENKINS-5769")
@Test
public void unmarshalThrowableMissingField() {
void unmarshalThrowableMissingField() {
Level oldLevel = disableLogging();
Baz baz = new Baz();
@ -171,7 +171,7 @@ public class XStream2Test {
}
@Test
public void immutableMap() {
void immutableMap() {
XStream2 xs = new XStream2();
roundtripImmutableMap(xs, ImmutableMap.of());
@ -191,8 +191,8 @@ public class XStream2Test {
a.m = m;
String xml = xs.toXML(a);
//System.out.println(xml);
assertFalse("shouldn't contain the class name", xml.contains("google"));
assertFalse("shouldn't contain the class name", xml.contains("class"));
assertFalse(xml.contains("google"), "shouldn't contain the class name");
assertFalse(xml.contains("class"), "shouldn't contain the class name");
a = (ImmutableMapHolder) xs.fromXML(xml);
assertSame(m.getClass(), a.m.getClass()); // should get back the exact same type, not just a random map
@ -204,7 +204,7 @@ public class XStream2Test {
a.m = m;
String xml = xs.toXML(a);
//System.out.println(xml);
assertTrue("XML should mention the class name", xml.contains('\"' + ImmutableMap.class.getName() + '\"'));
assertTrue(xml.contains('\"' + ImmutableMap.class.getName() + '\"'), "XML should mention the class name");
a = (MapHolder) xs.fromXML(xml);
assertSame(m.getClass(), a.m.getClass()); // should get back the exact same type, not just a random map
@ -220,7 +220,7 @@ public class XStream2Test {
}
@Test
public void immutableList() {
void immutableList() {
XStream2 xs = new XStream2();
roundtripImmutableList(xs, ImmutableList.of());
@ -240,8 +240,8 @@ public class XStream2Test {
a.l = l;
String xml = xs.toXML(a);
//System.out.println(xml);
assertFalse("shouldn't contain the class name", xml.contains("google"));
assertFalse("shouldn't contain the class name", xml.contains("class"));
assertFalse(xml.contains("google"), "shouldn't contain the class name");
assertFalse(xml.contains("class"), "shouldn't contain the class name");
a = (ImmutableListHolder) xs.fromXML(xml);
assertSame(l.getClass(), a.l.getClass()); // should get back the exact same type, not just a random list
@ -253,7 +253,7 @@ public class XStream2Test {
a.l = l;
String xml = xs.toXML(a);
//System.out.println(xml);
assertTrue("XML should mention the class name", xml.contains('\"' + ImmutableList.class.getName() + '\"'));
assertTrue(xml.contains('\"' + ImmutableList.class.getName() + '\"'), "XML should mention the class name");
a = (ListHolder) xs.fromXML(xml);
assertSame(l.getClass(), a.l.getClass()); // should get back the exact same type, not just a random list
@ -262,14 +262,14 @@ public class XStream2Test {
@Issue("JENKINS-8006") // Previously a null entry in an array caused NPE
@Test
public void emptyStack() {
void emptyStack() {
assertEquals("<object-array><null/><null/></object-array>",
Run.XSTREAM.toXML(new Object[2]).replaceAll("[ \n\r\t]+", ""));
}
@Issue("JENKINS-9843")
@Test
public void compatibilityAlias() {
void compatibilityAlias() {
XStream2 xs = new XStream2();
xs.addCompatibilityAlias("legacy.Point", Point.class);
Point pt = (Point) xs.fromXML("<legacy.Point><x>1</x><y>2</y></legacy.Point>");
@ -277,7 +277,7 @@ public class XStream2Test {
assertEquals(2, pt.y);
String xml = xs.toXML(pt);
//System.out.println(xml);
assertFalse("Shouldn't use the alias when writing back", xml.contains("legacy"));
assertFalse(xml.contains("legacy"), "Shouldn't use the alias when writing back");
}
public static class Point {
@ -290,7 +290,7 @@ public class XStream2Test {
@Issue("SECURITY-105")
@Test
public void dynamicProxyBlocked() {
void dynamicProxyBlocked() {
assertThrows(
XStreamException.class,
() -> ((Runnable) new XStream2().fromXML(
@ -298,7 +298,7 @@ public class XStream2Test {
+ Hacked.class.getName()
+ "'/><action>oops</action></handler></dynamic-proxy>"))
.run());
assertFalse("should never have run that", Hacked.tripped);
assertFalse(Hacked.tripped, "should never have run that");
}
public static final class Hacked {
@ -310,7 +310,7 @@ public class XStream2Test {
}
@Test
public void trimVersion() {
void trimVersion() {
assertEquals("3.2", XStream2.trimVersion("3.2"));
assertEquals("3.2.1", XStream2.trimVersion("3.2.1"));
assertEquals("3.2-SNAPSHOT", XStream2.trimVersion("3.2-SNAPSHOT (private-09/23/2012 12:26-jhacker)"));
@ -318,41 +318,42 @@ public class XStream2Test {
@Issue("JENKINS-21017")
@Test
public void unmarshalToDefault_populated() {
String populatedXml = "<hudson.util.XStream2Test_-WithDefaults>\n"
+ " <stringDefaultValue>my string</stringDefaultValue>\n"
+ " <stringDefaultNull>not null</stringDefaultNull>\n"
+ " <arrayDefaultValue>\n"
+ " <string>1</string>\n"
+ " <string>2</string>\n"
+ " <string>3</string>\n"
+ " </arrayDefaultValue>\n"
+ " <arrayDefaultEmpty>\n"
+ " <string>1</string>\n"
+ " <string>2</string>\n"
+ " <string>3</string>\n"
+ " </arrayDefaultEmpty>\n"
+ " <arrayDefaultNull>\n"
+ " <string>1</string>\n"
+ " <string>2</string>\n"
+ " <string>3</string>\n"
+ " </arrayDefaultNull>\n"
+ " <listDefaultValue>\n"
+ " <string>1</string>\n"
+ " <string>2</string>\n"
+ " <string>3</string>\n"
+ " </listDefaultValue>\n"
+ " <listDefaultEmpty>\n"
+ " <string>1</string>\n"
+ " <string>2</string>\n"
+ " <string>3</string>\n"
+ " </listDefaultEmpty>\n"
+ " <listDefaultNull>\n"
+ " <string>1</string>\n"
+ " <string>2</string>\n"
+ " <string>3</string>\n"
+ " </listDefaultNull>\n"
+ "</hudson.util.XStream2Test_-WithDefaults>";
void unmarshalToDefault_populated() {
String populatedXml = """
<hudson.util.XStream2Test_-WithDefaults>
<stringDefaultValue>my string</stringDefaultValue>
<stringDefaultNull>not null</stringDefaultNull>
<arrayDefaultValue>
<string>1</string>
<string>2</string>
<string>3</string>
</arrayDefaultValue>
<arrayDefaultEmpty>
<string>1</string>
<string>2</string>
<string>3</string>
</arrayDefaultEmpty>
<arrayDefaultNull>
<string>1</string>
<string>2</string>
<string>3</string>
</arrayDefaultNull>
<listDefaultValue>
<string>1</string>
<string>2</string>
<string>3</string>
</listDefaultValue>
<listDefaultEmpty>
<string>1</string>
<string>2</string>
<string>3</string>
</listDefaultEmpty>
<listDefaultNull>
<string>1</string>
<string>2</string>
<string>3</string>
</listDefaultNull>
</hudson.util.XStream2Test_-WithDefaults>""";
WithDefaults existingInstance = new WithDefaults("foobar",
"foobar",
@ -377,20 +378,21 @@ public class XStream2Test {
@Issue("JENKINS-21017")
@Test
public void unmarshalToDefault_default() {
String defaultXml = "<hudson.util.XStream2Test_-WithDefaults>\n"
+ " <stringDefaultValue>defaultValue</stringDefaultValue>\n"
+ " <arrayDefaultValue>\n"
+ " <string>first</string>\n"
+ " <string>second</string>\n"
+ " </arrayDefaultValue>\n"
+ " <arrayDefaultEmpty/>\n"
+ " <listDefaultValue>\n"
+ " <string>first</string>\n"
+ " <string>second</string>\n"
+ " </listDefaultValue>\n"
+ " <listDefaultEmpty/>\n"
+ "</hudson.util.XStream2Test_-WithDefaults>";
void unmarshalToDefault_default() {
String defaultXml = """
<hudson.util.XStream2Test_-WithDefaults>
<stringDefaultValue>defaultValue</stringDefaultValue>
<arrayDefaultValue>
<string>first</string>
<string>second</string>
</arrayDefaultValue>
<arrayDefaultEmpty/>
<listDefaultValue>
<string>first</string>
<string>second</string>
</listDefaultValue>
<listDefaultEmpty/>
</hudson.util.XStream2Test_-WithDefaults>""";
WithDefaults existingInstance = new WithDefaults("foobar",
"foobar",
@ -415,7 +417,7 @@ public class XStream2Test {
@Issue("JENKINS-21017")
@Test
public void unmarshalToDefault_empty() {
void unmarshalToDefault_empty() {
String emptyXml = "<hudson.util.XStream2Test_-WithDefaults/>";
WithDefaults existingInstance = new WithDefaults("foobar",
@ -455,9 +457,11 @@ public class XStream2Test {
private List<String> listDefaultEmpty = new ArrayList<>();
private List<String> listDefaultNull;
@SuppressWarnings("checkstyle:redundantmodifier")
public WithDefaults() {
}
@SuppressWarnings("checkstyle:redundantmodifier")
public WithDefaults(String stringDefaultValue, String stringDefaultNull, String[] arrayDefaultValue,
String[] arrayDefaultEmpty, String[] arrayDefaultNull,
List<String> listDefaultValue, List<String> listDefaultEmpty,
@ -539,15 +543,15 @@ public class XStream2Test {
@Issue("SECURITY-503")
@Test
public void crashXstream() {
void crashXstream() {
assertThrows(XStreamException.class, () -> new XStream2().fromXML("<void/>"));
}
@Test
public void annotations() {
assertEquals("not registered, so sorry", "<hudson.util.XStream2Test_-C1/>", Jenkins.XSTREAM2.toXML(new C1()));
assertEquals("manually registered", "<C-2/>", Jenkins.XSTREAM2.toXML(new C2()));
assertEquals("manually processed", "<C-3/>", Jenkins.XSTREAM2.toXML(new C3()));
void annotations() {
assertEquals("<hudson.util.XStream2Test_-C1/>", Jenkins.XSTREAM2.toXML(new C1()), "not registered, so sorry");
assertEquals("<C-2/>", Jenkins.XSTREAM2.toXML(new C2()), "manually registered");
assertEquals("<C-3/>", Jenkins.XSTREAM2.toXML(new C3()), "manually processed");
assertThrows(CannotResolveClassException.class, () -> Jenkins.XSTREAM2.fromXML("<C-4/>"));
Jenkins.XSTREAM2.processAnnotations(C5.class);
@ -578,7 +582,7 @@ public class XStream2Test {
@Issue("JENKINS-69129")
@Test
public void testEmoji() throws Exception {
void testEmoji() throws Exception {
Bar bar;
try (InputStream is = getClass().getResource("XStream2Emoji.xml").openStream()) {
bar = (Bar) new XStream2().fromXML(is);
@ -588,7 +592,7 @@ public class XStream2Test {
@Issue("JENKINS-69129")
@Test
public void testEmojiEscaped() throws Exception {
void testEmojiEscaped() throws Exception {
Bar bar;
try (InputStream is = getClass().getResource("XStream2EmojiEscaped.xml").openStream()) {
bar = (Bar) new XStream2().fromXML(is);
@ -598,7 +602,7 @@ public class XStream2Test {
@Issue("JENKINS-71182")
@Test
public void writeEmoji() throws Exception {
void writeEmoji() {
Bar b = new Bar();
String text = "Fox 🦊";
b.s = text;
@ -613,7 +617,7 @@ public class XStream2Test {
@Issue("JENKINS-71139")
@Test
public void nullsWithoutEncodingDeclaration() throws Exception {
void nullsWithoutEncodingDeclaration() {
Bar b = new Bar();
b.s = "x\u0000y";
try {
@ -626,7 +630,7 @@ public class XStream2Test {
@Issue("JENKINS-71139")
@Test
public void nullsWithEncodingDeclaration() throws Exception {
void nullsWithEncodingDeclaration() throws Exception {
Bar b = new Bar();
b.s = "x\u0000y";
try {

View File

@ -1,8 +1,8 @@
package hudson.util.io;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assume.assumeFalse;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import hudson.FilePath;
import hudson.Functions;
@ -12,19 +12,18 @@ import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.FileUtils;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.jvnet.hudson.test.Issue;
public class RewindableRotatingFileOutputStreamTest {
class RewindableRotatingFileOutputStreamTest {
@Rule
public TemporaryFolder tmp = new TemporaryFolder();
@TempDir
private File tmp;
@Test
public void rotation() throws IOException, InterruptedException {
File base = tmp.newFile("test.log");
void rotation() throws IOException, InterruptedException {
File base = File.createTempFile("test.log", null, tmp);
RewindableRotatingFileOutputStream os = new RewindableRotatingFileOutputStream(base, 3);
PrintWriter w = new PrintWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8), true);
for (int i = 0; i <= 4; i++) {
@ -45,10 +44,10 @@ public class RewindableRotatingFileOutputStreamTest {
@Issue("JENKINS-16634")
@Test
public void deletedFolder() throws Exception {
assumeFalse("Windows does not allow deleting a directory with a "
+ "file open, so this case should never occur", Functions.isWindows());
File dir = tmp.newFolder("dir");
void deletedFolder() throws Exception {
assumeFalse(Functions.isWindows(), "Windows does not allow deleting a directory with a "
+ "file open, so this case should never occur");
File dir = newFolder(tmp, "dir");
File base = new File(dir, "x.log");
RewindableRotatingFileOutputStream os = new RewindableRotatingFileOutputStream(base, 3);
for (int i = 0; i < 2; i++) {
@ -61,4 +60,13 @@ public class RewindableRotatingFileOutputStreamTest {
}
}
private static File newFolder(File root, String... subDirs) throws IOException {
String subFolder = String.join("/", subDirs);
File result = new File(root, subFolder);
if (!result.mkdirs()) {
throw new IOException("Couldn't create folders " + root);
}
return result;
}
}

View File

@ -24,9 +24,9 @@
package hudson.util.io;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeNoException;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import hudson.FilePath;
import hudson.Functions;
@ -46,21 +46,22 @@ import java.util.HashSet;
import java.util.Set;
import org.apache.tools.tar.TarEntry;
import org.apache.tools.tar.TarInputStream;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.jvnet.hudson.test.Issue;
public class TarArchiverTest {
class TarArchiverTest {
@Rule public TemporaryFolder tmp = new TemporaryFolder();
@TempDir
private File tmp;
/**
* Makes sure that permissions are properly stored in the tar file.
*/
@Issue("JENKINS-9397")
@Test public void permission() throws Exception {
@Test
void permission() throws Exception {
assumeFalse(Functions.isWindows());
File tar = File.createTempFile("test", "tar");
@ -115,26 +116,27 @@ public class TarArchiverTest {
try {
assertEquals(0, new LocalLauncher(StreamTaskListener.fromStdout()).launch().cmds(cmds).pwd(dir).join());
} catch (IOException x) { // perhaps restrict to x.message.contains("Cannot run program")? or "error=2, No such file or directory"?
assumeNoException("failed to run " + Arrays.toString(cmds), x);
assumeTrue(false, "failed to run " + Arrays.toString(cmds) + ": " + x);
}
}
@Issue("JENKINS-14922")
@Test public void brokenSymlinks() throws Exception {
@Test
void brokenSymlinks() throws Exception {
assumeFalse(Functions.isWindows());
File dir = tmp.getRoot();
File dir = tmp;
Util.createSymlink(dir, "nonexistent", "link", TaskListener.NULL);
try (OutputStream out = OutputStream.nullOutputStream()) {
new FilePath(dir).tar(out, "**");
}
}
@Ignore("TODO fails to add empty directories to archive")
@Disabled("TODO fails to add empty directories to archive")
@Issue("JENKINS-73837")
@Test
public void emptyDirectory() throws Exception {
Path tar = tmp.newFile("test.tar").toPath();
Path root = tmp.newFolder().toPath();
void emptyDirectory() throws Exception {
Path tar = File.createTempFile("test.tar", null, tmp).toPath();
Path root = newFolder(tmp, "junit").toPath();
Files.createDirectory(root.resolve("foo"));
Files.createDirectory(root.resolve("bar"));
Files.writeString(root.resolve("bar/file.txt"), "foobar", StandardCharsets.UTF_8);
@ -157,14 +159,15 @@ public class TarArchiverTest {
*/
@Issue("JENKINS-20187")
@Test public void growingFileTar() throws Exception {
File file = new File(tmp.getRoot(), "growing.file");
@Test
void growingFileTar() throws Exception {
File file = new File(tmp, "growing.file");
GrowingFileRunnable runnable1 = new GrowingFileRunnable(file);
Thread t1 = new Thread(runnable1);
t1.start();
try (OutputStream out = OutputStream.nullOutputStream()) {
new FilePath(tmp.getRoot()).tar(out, "**");
new FilePath(tmp).tar(out, "**");
}
runnable1.doFinish();
@ -204,4 +207,13 @@ public class TarArchiverTest {
}
}
private static File newFolder(File root, String... subDirs) throws IOException {
String subFolder = String.join("/", subDirs);
File result = new File(root, subFolder);
if (!result.mkdirs()) {
throw new IOException("Couldn't create folders " + root);
}
return result;
}
}

View File

@ -1,8 +1,10 @@
package hudson.util.io;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import hudson.FilePath;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@ -15,28 +17,27 @@ import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import org.junit.Assume;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.jvnet.hudson.test.Issue;
public class ZipArchiverTest {
class ZipArchiverTest {
@Rule public TemporaryFolder tmp = new TemporaryFolder();
@TempDir
private File tmp;
@Issue("JENKINS-9942")
@Test
public void backwardsSlashesOnWindows() throws IOException {
void backwardsSlashesOnWindows() throws IOException {
// create foo/bar/baz/Test.txt
Path baz = tmp.newFolder().toPath().resolve("foo").resolve("bar").resolve("baz");
Path baz = newFolder(tmp, "junit").toPath().resolve("foo").resolve("bar").resolve("baz");
Files.createDirectories(baz);
Path tmpFile = baz.resolve("Test.txt");
Files.createFile(tmpFile);
// a file to store the zip archive in
Path zipFile = Files.createTempFile(tmp.getRoot().toPath(), "test", ".zip");
Path zipFile = Files.createTempFile(tmp.toPath(), "test", ".zip");
// create zip from tmpDir
try (ZipArchiver archiver = new ZipArchiver(Files.newOutputStream(zipFile))) {
@ -53,19 +54,19 @@ public class ZipArchiverTest {
}
@Test
public void huge64bitFile() throws IOException {
void huge64bitFile() throws IOException {
// create huge64bitFileTest.txt
Path hugeFile = tmp.newFolder().toPath().resolve("huge64bitFileTest.txt");
Path hugeFile = newFolder(tmp, "junit").toPath().resolve("huge64bitFileTest.txt");
long length = 4L * 1024 * 1024 * 1024 + 2;
try (RandomAccessFile largeFile = new RandomAccessFile(hugeFile.toFile(), "rw")) {
largeFile.setLength(length);
} catch (IOException e) {
// We probably don't have enough free disk space. That's ok, we'll skip this test...
Assume.assumeNoException(e);
assumeTrue(false, e.toString());
}
// a file to store the zip archive in
Path zipFile = Files.createTempFile(tmp.getRoot().toPath(), "test", ".zip");
Path zipFile = Files.createTempFile(tmp.toPath(), "test", ".zip");
// create zip from tmpDir
try (ZipArchiver archiver = new ZipArchiver(Files.newOutputStream(zipFile))) {
@ -81,12 +82,12 @@ public class ZipArchiverTest {
}
}
@Ignore("TODO fails to add empty directories to archive")
@Disabled("TODO fails to add empty directories to archive")
@Issue("JENKINS-49296")
@Test
public void emptyDirectory() throws Exception {
Path zip = tmp.newFile("test.zip").toPath();
Path root = tmp.newFolder().toPath();
void emptyDirectory() throws Exception {
Path zip = File.createTempFile("test.zip", null, tmp).toPath();
Path root = newFolder(tmp, "junit").toPath();
Files.createDirectory(root.resolve("foo"));
Files.createDirectory(root.resolve("bar"));
Files.writeString(root.resolve("bar/file.txt"), "foobar", StandardCharsets.UTF_8);
@ -103,4 +104,13 @@ public class ZipArchiverTest {
}
assertEquals(Set.of("foo/", "bar/", "bar/file.txt"), names);
}
private static File newFolder(File root, String... subDirs) throws IOException {
String subFolder = String.join("/", subDirs);
File result = new File(root, subFolder);
if (!result.mkdirs()) {
throw new IOException("Couldn't create folders " + root);
}
return result;
}
}

View File

@ -1,24 +1,24 @@
package hudson.util.jna;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import hudson.Functions;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import org.junit.Test;
import org.junit.jupiter.api.Test;
public class GNUCLibraryTest {
class GNUCLibraryTest {
private static final int O_CREAT = "Linux".equals(System.getProperty("os.name")) ? 64 : 512;
private static final int O_RDWR = 2;
@Test
public void openTest() throws IOException {
void openTest() throws IOException {
assumeTrue(Functions.isGlibcSupported());
int fd = GNUCLibrary.LIBC.open("/dev/null", 0);
@ -42,7 +42,7 @@ public class GNUCLibraryTest {
}
@Test
public void closeTest() {
void closeTest() {
assumeTrue(Functions.isGlibcSupported());
int fd = GNUCLibrary.LIBC.open("/dev/null", 0);
@ -53,7 +53,7 @@ public class GNUCLibraryTest {
}
@Test
public void fcntlTest() {
void fcntlTest() {
assumeTrue(Functions.isGlibcSupported());
int fd = GNUCLibrary.LIBC.open("/dev/null", 0);
@ -72,7 +72,7 @@ public class GNUCLibraryTest {
}
@Test
public void renameTest() throws IOException {
void renameTest() throws IOException {
assumeTrue(Functions.isGlibcSupported());
Path oldFile = Files.createTempFile("renameTest", null);