Merge commit '711b3325adf629585d60aa5a2bcac1d49b8324ae'

This commit is contained in:
CloudBees DEV@Cloud committed 2014-12-23 16:59:01 +00:00
commit 4c474cea6f
24 files changed
+858 -1428

No files matched your search

@@ -24,12 +24,7 @@
package hudson.model;
import hudson.Util;
import hudson.model.Run.Artifact;
import hudson.util.StreamTaskListener;
import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import java.util.concurrent.Callable;
@@ -87,32 +82,6 @@ public class RunTest {
}
@Bug(15587)
@Test
public void testParseTimestampFromBuildDir() throws Exception {
//Assume.assumeTrue(!Functions.isWindows() || (NTFS && JAVA7) || ...);
String buildDateTime = "2012-12-21_04-02-28";
int buildNumber = 155;
StreamTaskListener l = StreamTaskListener.fromStdout();
File tempDir = Util.createTempDir();
File buildDir = new File(tempDir, buildDateTime);
assertEquals(true, buildDir.mkdir());
File buildDirSymLink = new File(tempDir, Integer.toString(buildNumber));
try {
buildDir.mkdir();
Util.createSymlink(tempDir, buildDir.getAbsolutePath(), buildDirSymLink.getName(), l);
long time = Run.parseTimestampFromBuildDir(buildDirSymLink);
assertEquals(buildDateTime, Run.ID_FORMATTER.get().format(new Date(time)));
} finally {
Util.deleteRecursive(tempDir);
}
}
private List<? extends Run<?, ?>.Artifact> createArtifactList(String... paths) throws Exception {
Run r = new Run(new StubJob(), 0) {};
Run.ArtifactList list = r.new ArtifactList();
@@ -0,0 +1,152 @@
/*
* The MIT License
*
* Copyright 2014 Jesse Glick.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package jenkins.model;
import hudson.Util;
import hudson.util.StreamTaskListener;
import java.io.File;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.TimeZone;
import java.util.TreeMap;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.rules.TemporaryFolder;
public class RunIdMigratorTest {
@Rule public TemporaryFolder tmp = new TemporaryFolder();
/** Ensures that legacy timestamps are interpreted in a predictable time zone. */
@BeforeClass public static void timezone() {
TimeZone.setDefault(TimeZone.getTimeZone("EST"));
}
@BeforeClass public static void logging() {
RunIdMigrator.LOGGER.setLevel(Level.ALL);
Handler handler = new ConsoleHandler();
handler.setLevel(Level.ALL);
RunIdMigrator.LOGGER.addHandler(handler);
}
private RunIdMigrator migrator;
private File dir;
@Before public void init() {
migrator = new RunIdMigrator();
dir = tmp.getRoot();
}
@Test public void newJob() throws Exception {
migrator.created(dir);
assertEquals("{legacyIds=''}", summarize());
assertEquals(0, migrator.findNumber("whatever"));
migrator.delete(dir, "1");
migrator = new RunIdMigrator();
assertFalse(migrator.migrate(dir, null));
assertEquals("{legacyIds=''}", summarize());
}
@Test public void legacy() throws Exception {
write("2014-01-02_03-04-05/build.xml", "<?xml version='1.0' encoding='UTF-8'?>\n<run>\n <stuff>ok</stuff>\n <number>99</number>\n <otherstuff>ok</otherstuff>\n</run>");
link("99", "2014-01-02_03-04-05");
link("lastFailedBuild", "-1");
link("lastSuccessfulBuild", "99");
assertEquals("{2014-01-02_03-04-05={build.xml='<?xml version='1.0' encoding='UTF-8'?>\n<run>\n <stuff>ok</stuff>\n <number>99</number>\n <otherstuff>ok</otherstuff>\n</run>'}, 99=→2014-01-02_03-04-05, lastFailedBuild=→-1, lastSuccessfulBuild=→99}", summarize());
assertTrue(migrator.migrate(dir, null));
assertEquals("{99={build.xml='<?xml version='1.0' encoding='UTF-8'?>\n<run>\n <stuff>ok</stuff>\n <id>2014-01-02_03-04-05</id>\n <timestamp>1388649845000</timestamp>\n <otherstuff>ok</otherstuff>\n</run>'}, lastFailedBuild=→-1, lastSuccessfulBuild=→99, legacyIds='2014-01-02_03-04-05 99\n'}", summarize());
assertEquals(99, migrator.findNumber("2014-01-02_03-04-05"));
migrator = new RunIdMigrator();
assertFalse(migrator.migrate(dir, null));
assertEquals(99, migrator.findNumber("2014-01-02_03-04-05"));
migrator.delete(dir, "2014-01-02_03-04-05");
FileUtils.deleteDirectory(new File(dir, "99"));
new File(dir, "lastSuccessfulBuild").delete();
assertEquals("{lastFailedBuild=→-1, legacyIds=''}", summarize());
}
@Test public void reverseImmediately() throws Exception {
File root = dir;
dir = new File(dir, "jobs/somefolder/jobs/someproject/promotions/OK/builds");
write("99/build.xml", "<?xml version='1.0' encoding='UTF-8'?>\n<run>\n <stuff>ok</stuff>\n <id>2014-01-02_03-04-05</id>\n <timestamp>1388649845000</timestamp>\n <otherstuff>ok</otherstuff>\n</run>");
link("lastFailedBuild", "-1");
link("lastSuccessfulBuild", "99");
write("legacyIds", "2014-01-02_03-04-05 99\n");
assertEquals("{99={build.xml='<?xml version='1.0' encoding='UTF-8'?>\n<run>\n <stuff>ok</stuff>\n <id>2014-01-02_03-04-05</id>\n <timestamp>1388649845000</timestamp>\n <otherstuff>ok</otherstuff>\n</run>'}, lastFailedBuild=→-1, lastSuccessfulBuild=→99, legacyIds='2014-01-02_03-04-05 99\n'}", summarize());
RunIdMigrator.main(root.getAbsolutePath());
assertEquals("{2014-01-02_03-04-05={build.xml='<?xml version='1.0' encoding='UTF-8'?>\n<run>\n <stuff>ok</stuff>\n <number>99</number>\n <otherstuff>ok</otherstuff>\n</run>'}, 99=→2014-01-02_03-04-05, lastFailedBuild=→-1, lastSuccessfulBuild=→99}", summarize());
}
@Test public void reverseAfterNewBuilds() throws Exception {
File root = dir;
dir = new File(dir, "jobs/someproject/modules/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 {
FileUtils.write(new File(dir, file), text);
}
private void link(String symlink, String dest) throws Exception {
Util.createSymlink(dir, dest, symlink, new StreamTaskListener(System.out, Charset.defaultCharset()));
}
private String summarize() throws Exception {
return summarize(dir);
}
private static String summarize(File dir) throws Exception {
File[] kids = dir.listFiles();
Map<String,String> m = new TreeMap<String,String>();
for (File kid : kids) {
String notation;
String symlink = Util.resolveSymlink(kid);
if (symlink != null) {
notation = "→" + symlink;
} else if (kid.isFile()) {
notation = "'" + FileUtils.readFileToString(kid) + "'";
} else if (kid.isDirectory()) {
notation = summarize(kid);
} else {
notation = "?";
}
m.put(kid.getName(), notation);
}
return m.toString();
}
}
@@ -66,7 +66,7 @@ public class AbstractLazyLoadRunMapTest extends Assert {
return new FakeMap(getDir()) {
@Override
protected BuildReference<Build> createReference(Build r) {
return new BuildReference<Build>(getIdOf(r), /* pretend referent expired */ null);
return new BuildReference<Build>(Integer.toString(r.n), /* pretend referent expired */ null);
}
};
}
@@ -80,7 +80,7 @@ public class AbstractLazyLoadRunMapTest extends Assert {
@Before
public void setUp() throws Exception {
a = aBuilder.add(1, "A").add(3, "B").add(5, "C").make();
a = aBuilder.add(1).add(3).add(5).make();
b = bBuilder.make();
}
@@ -88,11 +88,11 @@ public class AbstractLazyLoadRunMapTest extends Assert {
@Test
public void lookup() {
assertNull(a.get(0));
a.get(1).asserts(1, "A");
a.get(1).asserts(1);
assertNull(a.get(2));
a.get(3).asserts(3, "B");
a.get(3).asserts(3);
assertNull(a.get(4));
a.get(5).asserts(5, "C");
a.get(5).asserts(5);
assertNull(a.get(6));
assertNull(b.get(1));
@@ -108,8 +108,8 @@ public class AbstractLazyLoadRunMapTest extends Assert {
@Test
public void idempotentLookup() {
for (int i=0; i<5; i++) {
a.get(1).asserts(1,"A");
a.get((Object)1).asserts(1, "A");
a.get(1).asserts(1);
a.get((Object)1).asserts(1);
}
}
@@ -153,24 +153,24 @@ public class AbstractLazyLoadRunMapTest extends Assert {
@Bug(19418)
@Test
public void searchExactWhenIndexedButSoftReferenceExpired() throws IOException {
final FakeMap m = localExpiredBuilder.add(1, "A").add(2, "B").make();
final FakeMap m = localExpiredBuilder.add(1).add(2).make();
// force index creation
m.entrySet();
m.search(1, Direction.EXACT).asserts(1, "A");
m.search(1, Direction.EXACT).asserts(1);
assertNull(m.search(3, Direction.EXACT));
assertNull(m.search(0, Direction.EXACT));
}
@Bug(22681)
@Test public void exactSearchShouldNotReload() throws Exception {
FakeMap m = localBuilder.add(1, "A").add(2, "B").make();
FakeMap m = localBuilder.add(1).add(2).make();
assertNull(m.search(0, Direction.EXACT));
Build a = m.search(1, Direction.EXACT);
a.asserts(1, "A");
a.asserts(1);
Build b = m.search(2, Direction.EXACT);
b.asserts(2, "B");
b.asserts(2);
assertNull(m.search(0, Direction.EXACT));
assertSame(a, m.search(1, Direction.EXACT));
assertSame(b, m.search(2, Direction.EXACT));
@@ -186,82 +186,19 @@ public class AbstractLazyLoadRunMapTest extends Assert {
*/
@Test
public void unloadableData() throws IOException {
FakeMap m = localBuilder.add(1, "A").addUnloadable("B").add(5, "C").make();
FakeMap m = localBuilder.add(1).addUnloadable(3).add(5).make();
assertNull(m.search(3, Direction.EXACT));
m.search(3,Direction.DESC).asserts(1, "A");
m.search(3, Direction.ASC ).asserts(5, "C");
m.search(3,Direction.DESC).asserts(1);
m.search(3, Direction.ASC ).asserts(5);
}
@Test
public void eagerLoading() throws IOException {
Map.Entry[] b = a.entrySet().toArray(new Map.Entry[3]);
((Build)b[0].getValue()).asserts(5, "C");
((Build)b[1].getValue()).asserts(3, "B");
((Build)b[2].getValue()).asserts(1, "A");
}
@Test
public void fastLookup() throws IOException {
FakeMap a = localBuilder.addBoth(1, "A").addBoth(3, "B").addBoth(5, "C"). make();
a.get(1).asserts(1,"A");
assertNull(a.get(2));
a.get(3).asserts(3, "B");
assertNull(a.get(4));
a.get(5).asserts(5, "C");
}
@Test
public void fastSearch() throws IOException {
FakeMap a = localBuilder.addBoth(1, "A").addBoth(3, "B").addBoth(5, "C").addBoth(7, "D").make();
// we should be using the cache to find the entry efficiently
a.search(6, Direction.ASC).asserts(7, "D");
a.search(2, Direction.DESC).asserts(1, "A");
}
@Test
public void bogusCache() throws IOException {
FakeMap a = localBuilder.addUnloadableCache(1).make();
assertNull(a.get(1));
}
@Test
public void bogusCacheAndHiddenRealData() throws IOException {
FakeMap a = localBuilder.addUnloadableCache(1).add(1, "A").make();
a.get(1).asserts(1, "A");
}
@Test
public void bogusCache2() throws IOException {
FakeMap a = localBuilder.addBogusCache(1, 3, "A").make();
assertNull(a.get(1));
a.get(3).asserts(3,"A");
}
@Test
public void incompleteCache() throws IOException {
FakeMapBuilder setup = localBuilder.addBoth(1, "A").add(3, "B").addBoth(5, "C");
// each test uses a fresh map since cache lookup causes additional loads
// to verify the results
// if we just rely on cache,
// it'll pick up 5:C as the first ascending value,
// but we should be then verifying this by loading B, so in the end we should
// find the correct value
setup.make().search(2, Direction.ASC).asserts(3,"B");
setup.make().search(4, Direction.DESC).asserts(3,"B");
// variation of the cache based search where we find the outer-most value via cache
setup.make().search(0, Direction.ASC).asserts(1,"A");
setup.make().search(6, Direction.DESC).asserts(5,"C");
// variation of the cache search where the cache tells us that we are searching
// in the direction that doesn't have any records
assertNull(setup.make().search(0, Direction.DESC));
assertNull(setup.make().search(6, Direction.ASC));
((Build)b[0].getValue()).asserts(5);
((Build)b[1].getValue()).asserts(3);
((Build)b[2].getValue()).asserts(1);
}
@Test
@@ -271,8 +208,8 @@ public class AbstractLazyLoadRunMapTest extends Assert {
Build[] b = m.values().toArray(new Build[2]);
assertEquals(2, b.length);
b[0].asserts(5, "C");
b[1].asserts(3, "B");
b[0].asserts(5);
b[1].asserts(3);
}
@Test
@@ -287,77 +224,55 @@ public class AbstractLazyLoadRunMapTest extends Assert {
@Test
public void indexOutOfBounds() throws Exception {
FakeMapBuilder f = localBuilder;
f.add(100,"A")
.addUnloadable("B")
.addUnloadable("C")
.addUnloadable("D")
.addUnloadable("E")
.addUnloadable("F")
.addUnloadable("G")
.add(200,"H")
.add(201, "I");
f.add(100)
.addUnloadable(150)
.addUnloadable(151)
.addUnloadable(152)
.addUnloadable(153)
.addUnloadable(154)
.addUnloadable(155)
.add(200)
.add(201);
FakeMap map = f.make();
Build x = map.search(Integer.MAX_VALUE, Direction.DESC);
assert x.n==201;
}
@Bug(15652)
@Test public void outOfOrder() throws Exception {
FakeMap map = localBuilder
.add( 4, "2012-A")
.add( 5, "2012-B")
.add( 6, "2012-C")
.add( 7, "2012-D")
.add( 8, "2012-E")
.add( 9, "2012-F")
.add(10, "2012-G")
.add(11, "2012-H")
.add(12, "2012-I")
.add( 1, "2013-A")
.add( 7, "2013-B")
.add( 9, "2013-C")
.add(10, "2013-D")
.add(11, "2013-E")
.make();
map.entrySet(); // forces Index to be populated
assertNull(map.search(3, Direction.DESC));
}
@Bug(18065)
@Test public void all() throws Exception {
assertEquals("[]", a.getLoadedBuilds().keySet().toString());
Set<Map.Entry<Integer,Build>> entries = a.entrySet();
assertEquals("[]", a.getLoadedBuilds().keySet().toString());
assertFalse(entries.isEmpty());
assertEquals("5 since it is the latest, and 3 because, well, .search and pivot is weird", "[5, 3]", a.getLoadedBuilds().keySet().toString());
assertEquals(5, a.getById("C").n);
assertEquals("[5, 3]", a.getLoadedBuilds().keySet().toString());
assertEquals("A", a.getByNumber(1).id);
assertEquals("[5, 3, 1]", a.getLoadedBuilds().keySet().toString());
assertEquals("5 since it is the latest", "[5]", a.getLoadedBuilds().keySet().toString());
assertEquals(5, a.getById("5").n);
assertEquals("[5]", a.getLoadedBuilds().keySet().toString());
assertEquals(1, a.getByNumber(1).n);
assertEquals("[5, 1]", a.getLoadedBuilds().keySet().toString());
a.purgeCache();
assertEquals("[]", a.getLoadedBuilds().keySet().toString());
Iterator<Map.Entry<Integer,Build>> iterator = entries.iterator();
assertEquals("iterator starts off checking for newest build, so for this crazy logic see above", "[5, 3]", a.getLoadedBuilds().keySet().toString());
assertEquals("[5]", a.getLoadedBuilds().keySet().toString());
assertTrue(iterator.hasNext());
assertEquals("[5, 3]", a.getLoadedBuilds().keySet().toString());
assertEquals("[5]", a.getLoadedBuilds().keySet().toString());
Map.Entry<Integer,Build> entry = iterator.next();
assertEquals("[5, 3]", a.getLoadedBuilds().keySet().toString());
assertEquals(5, entry.getKey().intValue());
assertEquals("[5, 3]", a.getLoadedBuilds().keySet().toString());
assertEquals("C", entry.getValue().id);
assertEquals(5, entry.getValue().n);
assertEquals("[5, 3]", a.getLoadedBuilds().keySet().toString());
assertTrue(iterator.hasNext());
entry = iterator.next();
assertEquals(3, entry.getKey().intValue());
assertEquals(".next() precomputes the one after that too", "[5, 3, 1]", a.getLoadedBuilds().keySet().toString());
assertEquals("B", entry.getValue().id);
assertEquals(3, entry.getValue().n);
assertEquals("[5, 3, 1]", a.getLoadedBuilds().keySet().toString());
assertTrue(iterator.hasNext());
entry = iterator.next();
assertEquals(1, entry.getKey().intValue());
assertEquals("[5, 3, 1]", a.getLoadedBuilds().keySet().toString());
assertEquals("A", entry.getValue().id);
assertEquals(1, entry.getValue().n);
assertEquals("[5, 3, 1]", a.getLoadedBuilds().keySet().toString());
assertFalse(iterator.hasNext());
}
@@ -375,7 +290,7 @@ public class AbstractLazyLoadRunMapTest extends Assert {
assertTrue(itr.hasNext());
Entry<Integer, Build> e = itr.next();
assertEquals((Integer)5,e.getKey());
e.getValue().asserts(5, "C");
e.getValue().asserts(5);
// now that the first entry is returned, we expect there to be two loaded
assertTrue(a.getLoadedBuilds().size() < 3);
@@ -384,7 +299,7 @@ public class AbstractLazyLoadRunMapTest extends Assert {
assertTrue(itr.hasNext());
e = itr.next();
assertEquals((Integer)3, e.getKey());
e.getValue().asserts(3,"B");
e.getValue().asserts(3);
// repeat the process for the third one
assertTrue(a.getLoadedBuilds().size() <= 3);
@@ -393,7 +308,7 @@ public class AbstractLazyLoadRunMapTest extends Assert {
assertTrue(itr.hasNext());
e = itr.next();
assertEquals((Integer) 1, e.getKey());
e.getValue().asserts(1,"A");
e.getValue().asserts(1);
assertFalse(itr.hasNext());
assertEquals(3, a.getLoadedBuilds().size());
@@ -417,7 +332,7 @@ public class AbstractLazyLoadRunMapTest extends Assert {
@Issue("JENKINS-25655")
@Test public void entrySetChanges() {
assertEquals(3, a.entrySet().size());
a.put(new Build(7, "D"));
a.put(new Build(7));
assertEquals(4, a.entrySet().size());
}
@@ -26,7 +26,6 @@ package jenkins.model.lazy;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
/**
@@ -42,50 +41,27 @@ public class FakeMap extends AbstractLazyLoadRunMap<Build> {
return build.n;
}
@Override
protected String getIdOf(Build build) {
return build.id;
}
@Override
protected FilenameFilter createDirectoryFilter() {
return new FilenameFilter() {
public boolean accept(File dir, String name) {
try {
Integer.parseInt(name);
return false;
} catch (NumberFormatException e) {
return true;
}
}
};
}
@Override
protected Build retrieve(File dir) throws IOException {
String n = FileUtils.readFileToString(new File(dir, "n")).trim();
String id = FileUtils.readFileToString(new File(dir, "id")).trim();
//new Exception("loading " + id + " #" + n).printStackTrace();
return new Build(Integer.parseInt(n),id);
//new Exception("loading #" + n).printStackTrace();
return new Build(Integer.parseInt(n));
}
}
class Build {
final int n;
final String id;
Build(int n, String id) {
Build(int n) {
this.n = n;
this.id = id;
}
public void asserts(int n, String id) {
public void asserts(int n) {
assert this.n==n;
assert this.id.equals(id);
}
@Override public String toString() {
return "Build #" + n + " [" + id + "] @" + hashCode();
return "Build #" + n + " @" + hashCode();
}
}
@@ -46,59 +46,19 @@ public class FakeMapBuilder implements TestRule {
public FakeMapBuilder() {
}
public FakeMapBuilder add(int n, String id) throws IOException {
verifyId(id);
File build = new File(dir,id);
build.mkdir();
public FakeMapBuilder add(int n) throws IOException {
File build = new File(dir, Integer.toString(n));
FileUtils.writeStringToFile(new File(build, "n"), Integer.toString(n));
FileUtils.writeStringToFile(new File(build,"id"),id);
return this;
}
/**
* Adds a symlink from n to build id.
*
* (in test we should ideally create a symlink, but we fake the test
* by actually making it a directory and staging the same data.)
*/
public FakeMapBuilder addCache(int n, String id) throws IOException {
return addBogusCache(n,n,id);
}
public FakeMapBuilder addBogusCache(int label, int actual, String id) throws IOException {
verifyId(id);
File build = new File(dir,Integer.toString(label));
build.mkdir();
FileUtils.writeStringToFile(new File(build, "n"), Integer.toString(actual));
FileUtils.writeStringToFile(new File(build,"id"),id);
return this;
}
public FakeMapBuilder addBoth(int n, String id) throws IOException {
return add(n,id).addCache(n,id);
}
private void verifyId(String id) {
try {
Integer.parseInt(id);
throw new IllegalMonitorStateException("ID cannot be a number");
} catch (NumberFormatException e) {
// OK
}
}
/**
* Adds a build record under the givn ID but make it unloadable,
* which will cause a failure when a load is attempted on this build ID.
*/
public FakeMapBuilder addUnloadable(String id) throws IOException {
File build = new File(dir,id);
build.mkdir();
return this;
}
public FakeMapBuilder addUnloadableCache(int n) throws IOException {
File build = new File(dir,String.valueOf(n));
public FakeMapBuilder addUnloadable(int n) throws IOException {
File build = new File(dir, Integer.toString(n));
build.mkdir();
return this;
}
@@ -1,5 +1,6 @@
package jenkins.model.lazy;
import static org.junit.Assert.*;
import org.junit.Test;
/**
@@ -12,6 +13,25 @@ public class SortedIntListTest {
l.add(0);
l.add(5);
l.add(10);
System.out.println(l.lower(Integer.MAX_VALUE));
assertEquals(2, l.lower(Integer.MAX_VALUE));
}
@Test public void ceil() {
SortedIntList l = new SortedIntList(5);
l.add(1);
l.add(3);
l.add(5);
assertEquals(0, l.ceil(0));
assertEquals(0, l.ceil(1));
assertEquals(1, l.ceil(2));
assertEquals(1, l.ceil(3));
assertEquals(2, l.ceil(4));
assertEquals(2, l.ceil(5));
assertEquals(3, l.ceil(6));
assertTrue(l.isInRange(0));
assertTrue(l.isInRange(1));
assertTrue(l.isInRange(2));
assertFalse(l.isInRange(3));
}
}