mirror of
https://github.com/jenkinsci/jenkins.git
synced 2026-11-15 21:12:15 +00:00
moving into positions to be merged into the mainline
This commit is contained in:
1 parent
e290de6a0e
commit
00b0ebcdf8
9 files changed
-22
No files matched your search
@@ -0,0 +1,197 @@
|
||||
package ll;
|
||||
|
||||
import ll.Attempt2.Direction;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.SortedMap;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public class Attempt2Test extends Assert {
|
||||
// A=1, B=3, C=5
|
||||
@Rule
|
||||
public FakeMapBuilder aBuilder = new FakeMapBuilder();
|
||||
private FakeMap a;
|
||||
|
||||
// empty map
|
||||
@Rule
|
||||
public FakeMapBuilder bBuilder = new FakeMapBuilder();
|
||||
private FakeMap b;
|
||||
|
||||
@Rule
|
||||
public FakeMapBuilder localBuilder = new FakeMapBuilder();
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
a = aBuilder.add(1, "A").add(3, "B").add(5, "C").make();
|
||||
|
||||
b = bBuilder.make();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lookup() {
|
||||
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");
|
||||
|
||||
assertNull(b.get(1));
|
||||
assertNull(b.get(3));
|
||||
assertNull(b.get(5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void idempotentLookup() {
|
||||
for (int i=0; i<5; i++) {
|
||||
a.get(1).asserts(1,"A");
|
||||
a.get((Object)1).asserts(1, "A");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lookupWithBogusKeyType() {
|
||||
assertNull(a.get(null));
|
||||
assertNull(a.get("foo"));
|
||||
assertNull(a.get(this));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void firstKey() {
|
||||
assertEquals(1, a.firstKey().intValue());
|
||||
|
||||
try {
|
||||
b.firstKey();
|
||||
fail();
|
||||
} catch (NoSuchElementException e) {
|
||||
// as expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lastKey() {
|
||||
assertEquals(5, a.lastKey().intValue());
|
||||
try {
|
||||
b.lastKey();
|
||||
fail();
|
||||
} catch (NoSuchElementException e) {
|
||||
// as expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void search() {
|
||||
// searching toward non-existent direction
|
||||
assertNull(a.search( 99, Direction.ASC));
|
||||
assertNull(a.search(-99, Direction.DESC));
|
||||
}
|
||||
|
||||
/**
|
||||
* If load fails, search needs to gracefully handle it
|
||||
*/
|
||||
@Test
|
||||
public void unloadableData() throws IOException {
|
||||
FakeMap m = localBuilder.add(1, "A").addUnloadable("B").add(5, "C").make();
|
||||
|
||||
assertNull(m.search(3,Direction.EXACT));
|
||||
m.search(3,Direction.DESC).asserts(1,"A");
|
||||
m.search(3,Direction.ASC ).asserts(5,"C");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void eagerLoading() throws IOException {
|
||||
Map.Entry[] b = a.entrySet().toArray(new Map.Entry[3]);
|
||||
((Build)b[0].getValue()).asserts(1,"A");
|
||||
((Build)b[1].getValue()).asserts(3,"B");
|
||||
((Build)b[2].getValue()).asserts(5,"C");
|
||||
}
|
||||
|
||||
@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));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fastSubMap() throws Exception {
|
||||
SortedMap<Integer,Build> m = a.subMap(2, 99);
|
||||
assertEquals(2, m.size());
|
||||
|
||||
Build[] b = m.values().toArray(new Build[2]);
|
||||
assertEquals(2,b.length);
|
||||
b[0].asserts(3,"B");
|
||||
b[1].asserts(5,"C");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void identity() {
|
||||
assertTrue(a.equals(a));
|
||||
assertTrue(!a.equals(b));
|
||||
a.hashCode();
|
||||
b.hashCode();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package ll;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public class FakeMap extends Attempt2<Build> {
|
||||
public FakeMap(File dir) {
|
||||
super(dir);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getNumberOf(Build 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();
|
||||
return new Build(Integer.parseInt(n),id);
|
||||
}
|
||||
}
|
||||
|
||||
class Build {
|
||||
final int n;
|
||||
final String id;
|
||||
|
||||
Build(int n, String id) {
|
||||
this.n = n;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void asserts(int n, String id) {
|
||||
assert this.n==n;
|
||||
assert this.id.equals(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package ll;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Builder for creating a {@link FakeMap}
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public class FakeMapBuilder implements TestRule {
|
||||
private File dir;
|
||||
|
||||
public FakeMapBuilder() {
|
||||
}
|
||||
|
||||
public FakeMapBuilder add(int n, String id) throws IOException {
|
||||
verifyId(id);
|
||||
File build = new File(dir,id);
|
||||
build.mkdir();
|
||||
FileUtils.write(new File(build, "n"), Integer.toString(n));
|
||||
FileUtils.write(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.write(new File(build, "n"), Integer.toString(actual));
|
||||
FileUtils.write(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));
|
||||
build.mkdir();
|
||||
return this;
|
||||
}
|
||||
|
||||
public FakeMap make() {
|
||||
return new FakeMap(dir);
|
||||
}
|
||||
|
||||
public Statement apply(final Statement base, Description description) {
|
||||
return new Statement() {
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
dir = File.createTempFile("lazyload","test");
|
||||
dir.delete();
|
||||
dir.mkdirs();
|
||||
try {
|
||||
base.evaluate();
|
||||
} finally {
|
||||
FileUtils.deleteDirectory(dir);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package ll;
|
||||
|
||||
import ll.SortedStringList;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public class SortedStringListTest extends Assert {
|
||||
SortedStringList l = new SortedStringList(new ArrayList<String>(Arrays.asList("B","D","F")));
|
||||
|
||||
@Test
|
||||
public void testCeil() {
|
||||
assertEquals(0,l.ceil("A"));
|
||||
assertEquals(0,l.ceil("B"));
|
||||
assertEquals(1,l.ceil("C"));
|
||||
assertEquals(1,l.ceil("D"));
|
||||
assertEquals(2,l.ceil("E"));
|
||||
assertEquals(2,l.ceil("F"));
|
||||
assertEquals(3,l.ceil("G"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFloor() {
|
||||
assertEquals(-1,l.floor("A"));
|
||||
assertEquals(0,l.floor("B"));
|
||||
assertEquals(0,l.floor("C"));
|
||||
assertEquals(1,l.floor("D"));
|
||||
assertEquals(1,l.floor("E"));
|
||||
assertEquals(2,l.floor("F"));
|
||||
assertEquals(2,l.floor("G"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLower() {
|
||||
assertEquals(-1,l.lower("A"));
|
||||
assertEquals(-1,l.lower("B"));
|
||||
assertEquals(0,l.lower("C"));
|
||||
assertEquals(0,l.lower("D"));
|
||||
assertEquals(1,l.lower("E"));
|
||||
assertEquals(1,l.lower("F"));
|
||||
assertEquals(2,l.lower("G"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHigher() {
|
||||
assertEquals(0,l.higher("A"));
|
||||
assertEquals(1,l.higher("B"));
|
||||
assertEquals(1,l.higher("C"));
|
||||
assertEquals(2,l.higher("D"));
|
||||
assertEquals(2,l.higher("E"));
|
||||
assertEquals(3,l.higher("F"));
|
||||
assertEquals(3,l.higher("G"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRange() {
|
||||
assertTrue(l.isInRange(0));
|
||||
assertTrue(l.isInRange(1));
|
||||
assertTrue(l.isInRange(2));
|
||||
|
||||
assertFalse(l.isInRange(-1));
|
||||
assertFalse(l.isInRange(3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void remove() {
|
||||
l.remove("nosuchthing");
|
||||
assertEquals(3,l.size());
|
||||
|
||||
l.remove("B");
|
||||
assertEquals(2, l.size());
|
||||
assertEquals("D",l.get(0));
|
||||
assertEquals("F",l.get(1));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user