mirror of
https://github.com/jenkinsci/jenkins.git
synced 2026-11-15 13:02:19 +00:00
Merge branch 'master' into JENKINS-26445-pagination-search
* master: (256 commits) Noting #1817 Noting #1825 updated changelog for release [maven-release-plugin] prepare for next development iteration [maven-release-plugin] prepare release jenkins-1.629 [JENKINS-30139] Oleg wants to keep the data accessible so we have to go for immutable [JENKINS-30139] Forgot to change this one [JENKINS-30139] Add @Restricted to prevent external use of internal data [JENKINS-30139] Switch from a big fat lock to a concurrent collection [JENKINS-30374] Update obsolete help message updated changelog for release [maven-release-plugin] prepare for next development iteration [maven-release-plugin] prepare release jenkins-1.628 noting merge of PR#1816 - use slf4j interceptors Manage commons-logging and log4j as provided, include slf4j adapters for tests. Exclude commons-logging and log4j in dangerous scopes compile and runtime in plugins as well. Only exclude commons-logging and log4j in dangerous scopes compile and runtime. Reintroduce enforcer rules as suggested by @jtnord. Document allBuilds for Job remote access API Include slf4j-jdk14 during tests. ... Conflicts: war/src/main/webapp/scripts/hudson-behavior.js
This commit is contained in:
commit
a305e3dc93
223 files changed
+3309
-978
No files matched your search
@@ -371,7 +371,7 @@ public class FilePathTest {
|
||||
// Decompress
|
||||
FilePath outDir = new FilePath(temp.newFolder(filePrefix + "_out"));
|
||||
final FilePath outFile = outDir.child(tempFile.getName());
|
||||
tmpDirPath.child( filePrefix + ".tar").untar(outDir, TarCompression.NONE);
|
||||
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());
|
||||
}
|
||||
@@ -659,4 +659,35 @@ public class FilePathTest {
|
||||
// test conflict subdir
|
||||
src.moveAllChildrenTo(dst);
|
||||
}
|
||||
|
||||
@Issue("JENKINS-10629")
|
||||
@Test
|
||||
public void testEOFbrokenFlush() throws IOException, InterruptedException {
|
||||
final File srcFolder = temp.newFolder("src");
|
||||
// simulate magic structure with magic sizes:
|
||||
// |- dir/pom.xml (2049)
|
||||
// |- pom.xml (2049)
|
||||
// \- small.tar (1537)
|
||||
final File smallTar = new File(srcFolder, "small.tar");
|
||||
givenSomeContentInFile(smallTar, 1537);
|
||||
final File dir = new File(srcFolder, "dir");
|
||||
dir.mkdirs();
|
||||
final File pomFile = new File(dir, "pom.xml");
|
||||
givenSomeContentInFile(pomFile, 2049);
|
||||
FileUtils.copyFileToDirectory(pomFile, srcFolder);
|
||||
|
||||
final File archive = temp.newFile("archive.tar");
|
||||
|
||||
// Compress archive
|
||||
final FilePath tmpDirPath = new FilePath(srcFolder);
|
||||
int tarred = tmpDirPath.tar(new FileOutputStream(archive), "**");
|
||||
assertEquals("One file should have been compressed", 3, tarred);
|
||||
|
||||
// Decompress
|
||||
final File dstFolder = temp.newFolder("dst");
|
||||
dstFolder.mkdirs();
|
||||
FilePath outDir = new FilePath(dstFolder);
|
||||
// and now fail when flush is bad!
|
||||
tmpDirPath.child("../" + archive.getName()).untar(outDir, TarCompression.NONE);
|
||||
}
|
||||
}
|
||||
@@ -24,17 +24,26 @@
|
||||
*/
|
||||
package hudson;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.hasItem;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.hamcrest.BaseMatcher;
|
||||
import org.hamcrest.Description;
|
||||
import org.junit.Assume;
|
||||
@@ -42,12 +51,13 @@ import org.junit.Test;
|
||||
import org.jvnet.hudson.test.Issue;
|
||||
|
||||
import hudson.util.StreamTaskListener;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.internal.AssumptionViolatedException;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@@ -248,7 +258,17 @@ public class UtilTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void deleteFile() throws Exception {
|
||||
@Test
|
||||
public void testDeleteFile() throws Exception {
|
||||
File f = tmp.newFile();
|
||||
// Test: File is deleted
|
||||
mkfiles(f);
|
||||
Util.deleteFile(f);
|
||||
assertFalse("f exists after calling Util.deleteFile", f.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteFile_onWindows() throws Exception {
|
||||
Assume.assumeTrue(Functions.isWindows());
|
||||
Class<?> c;
|
||||
try {
|
||||
@@ -256,23 +276,118 @@ public class UtilTest {
|
||||
} catch (ClassNotFoundException x) {
|
||||
throw new AssumptionViolatedException("prior to JDK 7", x);
|
||||
}
|
||||
File d = tmp.getRoot();
|
||||
try {
|
||||
File f = new File(d, "f");
|
||||
OutputStream os = new FileOutputStream(f);
|
||||
File f = tmp.newFile();
|
||||
// Test: If we cannot delete a file, we throw explaining why
|
||||
mkfiles(f);
|
||||
lockFileForDeletion(f);
|
||||
try {
|
||||
Util.deleteFile(f);
|
||||
fail("should not have been deletable");
|
||||
} catch (IOException x) {
|
||||
assertEquals(c, x.getClass());
|
||||
} finally {
|
||||
os.close();
|
||||
assertThat(calcExceptionHierarchy(x), hasItem(c));
|
||||
assertThat(x.getMessage(), containsString(f.getPath()));
|
||||
}
|
||||
} finally {
|
||||
Util.deleteRecursive(d);
|
||||
unlockFilesForDeletion();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteRecursive() throws Exception {
|
||||
final File dir = tmp.newFolder();
|
||||
final File d1 = new File(dir, "d1");
|
||||
final File d2 = new File(dir, "d2");
|
||||
final File f1 = new File(dir, "f1");
|
||||
final File d1f1 = new File(d1, "d1f1");
|
||||
final File d2f2 = new File(d2, "d1f2");
|
||||
// Test: Files and directories are deleted
|
||||
mkdirs(dir, d1, d2);
|
||||
mkfiles(f1, d1f1, d2f2);
|
||||
Util.deleteRecursive(dir);
|
||||
assertFalse("dir exists", dir.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteRecursive_onWindows() throws Exception {
|
||||
Assume.assumeTrue(Functions.isWindows());
|
||||
final File dir = tmp.newFolder();
|
||||
final File d1 = new File(dir, "d1");
|
||||
final File d2 = new File(dir, "d2");
|
||||
final File f1 = new File(dir, "f1");
|
||||
final File d1f1 = new File(d1, "d1f1");
|
||||
final File d2f2 = new File(d2, "d1f2");
|
||||
try {
|
||||
// Test: If we cannot delete a file, we throw
|
||||
mkdirs(dir, d1, d2);
|
||||
mkfiles(f1, d1f1, d2f2);
|
||||
lockFileForDeletion(d1f1);
|
||||
try {
|
||||
Util.deleteRecursive(dir);
|
||||
fail("Expected IOException");
|
||||
} catch (IOException x) {
|
||||
assertTrue("dir exists", dir.exists());
|
||||
assertTrue("d1 exists", d1.exists());
|
||||
assertTrue("d1f1 exists", d1f1.exists());
|
||||
assertThat(x.getMessage(), containsString(dir.getPath()));
|
||||
}
|
||||
} finally {
|
||||
unlockFilesForDeletion();
|
||||
}
|
||||
}
|
||||
|
||||
/** Creates multiple directories. */
|
||||
private static void mkdirs(File... dirs) {
|
||||
for( File d : dirs ) {
|
||||
d.mkdir();
|
||||
assertTrue(d.getPath(), d.isDirectory());
|
||||
}
|
||||
}
|
||||
|
||||
/** Creates multiple files, each containing their filename as text content. */
|
||||
private static void mkfiles(File... files) throws IOException {
|
||||
for( File f : files )
|
||||
FileUtils.write(f, f.getName());
|
||||
}
|
||||
|
||||
/** Means of unlocking all the files we have locked, indexed by {@link File}. */
|
||||
private final Map<File, Callable<Void>> unlockFileCallables = new HashMap<File, Callable<Void>>();
|
||||
|
||||
/** Prevents a file from being deleted, so we can stress the deletion code's retries. */
|
||||
private void lockFileForDeletion(File f) throws IOException, InterruptedException {
|
||||
assert !unlockFileCallables.containsKey(f) : f + " is already locked." ;
|
||||
// Limitation: Only works on Windows. On unix we can delete anything we can create.
|
||||
// On unix, can't use "chmod a-w" on the dir as the code-under-test undoes that.
|
||||
// On unix, can't use "chattr +i" because that needs root.
|
||||
// On unix, can't use "chattr +u" because ext fs ignores it.
|
||||
// On Windows, we can't delete files that are open for reading, so we use that.
|
||||
assert Functions.isWindows();
|
||||
final InputStream s = new FileInputStream(f);
|
||||
unlockFileCallables.put(f, new Callable<Void>() {
|
||||
public Void call() throws IOException { s.close(); return null; };
|
||||
});
|
||||
}
|
||||
|
||||
/** Undoes a call to {@link #lockFileForDeletion(File)}. */
|
||||
private void unlockFileForDeletion(File f) throws Exception {
|
||||
unlockFileCallables.remove(f).call();
|
||||
}
|
||||
|
||||
/** Undoes all calls to {@link #lockFileForDeletion(File)}. */
|
||||
private void unlockFilesForDeletion() throws Exception {
|
||||
while( !unlockFileCallables.isEmpty() ) {
|
||||
unlockFileForDeletion(unlockFileCallables.keySet().iterator().next());
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns all classes in the exception hierarchy. */
|
||||
private static Iterable<Class<?>> calcExceptionHierarchy(Throwable t) {
|
||||
final List<Class<?>> result = Lists.newArrayList();
|
||||
for( ; t!=null ; t = t.getCause())
|
||||
result.add(t.getClass());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHtmlEscape() {
|
||||
assertEquals("<br>", Util.escape("\n"));
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.util.Collection;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
@@ -44,6 +45,27 @@ public class ItemsTest {
|
||||
assertEquals("foo/bar", Items.getCanonicalName(foo, "./bar"));
|
||||
assertEquals("foo/bar/baz/qux", Items.getCanonicalName(foo_bar, "baz/qux"));
|
||||
assertEquals("foo/baz/qux", Items.getCanonicalName(foo_bar, "../baz/qux"));
|
||||
|
||||
try {
|
||||
Items.getCanonicalName(root, "..");
|
||||
fail();
|
||||
} catch (IllegalArgumentException ex) {
|
||||
assertEquals("Illegal relative path '..' within context ''", ex.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
Items.getCanonicalName(foo, "../..");
|
||||
fail();
|
||||
} catch (IllegalArgumentException ex) {
|
||||
assertEquals("Illegal relative path '../..' within context 'foo'", ex.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
Items.getCanonicalName(root, "foo/../..");
|
||||
fail();
|
||||
} catch (IllegalArgumentException ex) {
|
||||
assertEquals("Illegal relative path 'foo/../..' within context ''", ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -89,7 +89,7 @@ public class ParametersActionTest {
|
||||
|
||||
@Test
|
||||
@Issue("JENKINS-15094")
|
||||
public void checkNullParamaterValues() {
|
||||
public void checkNullParameterValues() {
|
||||
SubTask subtask = mock(SubTask.class);
|
||||
Build build = mock(Build.class);
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2015 Kanstantsin Shautsou
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package hudson.triggers;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.jvnet.hudson.test.Issue;
|
||||
|
||||
/**
|
||||
* @author Kanstantsin Shautsou
|
||||
*/
|
||||
public class SCMTriggerTest {
|
||||
@Issue({"JENKINS-29790", "JENKINS-29945"})
|
||||
@Test
|
||||
public void testNoNPE() throws Exception {
|
||||
final SCMTrigger scmTrigger = new SCMTrigger("");
|
||||
|
||||
scmTrigger.run();
|
||||
scmTrigger.run(null);
|
||||
scmTrigger.getProjectActions();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2015 Kanstantsin Shautsou
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package hudson.triggers;
|
||||
|
||||
import antlr.ANTLRException;
|
||||
import org.junit.Test;
|
||||
import org.jvnet.hudson.test.Issue;
|
||||
|
||||
/**
|
||||
* @author Kanstantsin Shautsou
|
||||
*/
|
||||
public class TimerTriggerTest {
|
||||
@Issue("JENKINS-29790")
|
||||
@Test
|
||||
public void testNoNPE() throws ANTLRException {
|
||||
new TimerTrigger("").run();
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ public class ArgumentListBuilderTest {
|
||||
builder.add("arg");
|
||||
builder.add("other", "arguments");
|
||||
|
||||
assertFalse("There shouldnt be any masked arguments", builder.hasMaskedArguments());
|
||||
assertFalse("There should not be any masked arguments", builder.hasMaskedArguments());
|
||||
boolean[] array = builder.toMaskArray();
|
||||
assertNotNull("The mask array should not be null", array);
|
||||
assertThat("The mask array was incorrect", array, is(new boolean[] { false, false, false }));
|
||||
@@ -166,7 +166,7 @@ public class ArgumentListBuilderTest {
|
||||
ArgumentListBuilder builder = new ArgumentListBuilder();
|
||||
builder.addKeyValuePairs(null, KEY_VALUES);
|
||||
|
||||
assertFalse("There shouldnt be any masked arguments", builder.hasMaskedArguments());
|
||||
assertFalse("There should not be any masked arguments", builder.hasMaskedArguments());
|
||||
boolean[] array = builder.toMaskArray();
|
||||
assertNotNull("The mask array should not be null", array);
|
||||
assertThat("The mask array was incorrect", array, is(new boolean[] { false, false, false }));
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2015, CloudBees, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package hudson.util;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:tom.fennelly@gmail.com">tom.fennelly@gmail.com</a>
|
||||
*/
|
||||
public class MultipartFormDataParserTest {
|
||||
|
||||
@Test
|
||||
public void testIsMultipart() throws Exception {
|
||||
Assert.assertFalse("Wrongly identified \"multipart/form-data\"", MultipartFormDataParser.isMultiPartForm(null));
|
||||
Assert.assertFalse("Wrongly identified \"multipart/form-data\"", MultipartFormDataParser.isMultiPartForm("blah"));
|
||||
|
||||
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"));
|
||||
}
|
||||
}
|
||||
@@ -128,6 +128,26 @@ public class RunIdMigratorTest {
|
||||
assertEquals("{1=→2014-01-02_03-04-05, 2014-01-02_03-04-05={build.xml='<?xml version='1.0' encoding='UTF-8'?>\n<run>\n <stuff>ok</stuff>\n <number>1</number>\n <otherstuff>ok</otherstuff>\n</run>'}}", summarize());
|
||||
}
|
||||
|
||||
@Test public void reverseMatrixAfterNewBuilds() throws Exception {
|
||||
File root = dir;
|
||||
dir = new File(dir, "jobs/someproject/Environment=prod/builds");
|
||||
write("1/build.xml", "<?xml version='1.0' encoding='UTF-8'?>\n<run>\n <stuff>ok</stuff>\n <timestamp>1388649845000</timestamp>\n <otherstuff>ok</otherstuff>\n</run>");
|
||||
write("legacyIds", "");
|
||||
assertEquals("{1={build.xml='<?xml version='1.0' encoding='UTF-8'?>\n<run>\n <stuff>ok</stuff>\n <timestamp>1388649845000</timestamp>\n <otherstuff>ok</otherstuff>\n</run>'}, legacyIds=''}", summarize());
|
||||
RunIdMigrator.main(root.getAbsolutePath());
|
||||
assertEquals("{1=→2014-01-02_03-04-05, 2014-01-02_03-04-05={build.xml='<?xml version='1.0' encoding='UTF-8'?>\n<run>\n <stuff>ok</stuff>\n <number>1</number>\n <otherstuff>ok</otherstuff>\n</run>'}}", summarize());
|
||||
}
|
||||
|
||||
@Test public void reverseMavenAfterNewBuilds() throws Exception {
|
||||
File root = dir;
|
||||
dir = new File(dir, "jobs/someproject/test$test/builds");
|
||||
write("1/build.xml", "<?xml version='1.0' encoding='UTF-8'?>\n<run>\n <stuff>ok</stuff>\n <timestamp>1388649845000</timestamp>\n <otherstuff>ok</otherstuff>\n</run>");
|
||||
write("legacyIds", "");
|
||||
assertEquals("{1={build.xml='<?xml version='1.0' encoding='UTF-8'?>\n<run>\n <stuff>ok</stuff>\n <timestamp>1388649845000</timestamp>\n <otherstuff>ok</otherstuff>\n</run>'}, legacyIds=''}", summarize());
|
||||
RunIdMigrator.main(root.getAbsolutePath());
|
||||
assertEquals("{1=→2014-01-02_03-04-05, 2014-01-02_03-04-05={build.xml='<?xml version='1.0' encoding='UTF-8'?>\n<run>\n <stuff>ok</stuff>\n <number>1</number>\n <otherstuff>ok</otherstuff>\n</run>'}}", summarize());
|
||||
}
|
||||
|
||||
// TODO test sane recovery from various error conditions
|
||||
|
||||
private void write(String file, String text) throws Exception {
|
||||
|
||||
Reference in new issue
Block a user