mirror of
https://github.com/jenkinsci/jenkins.git
synced 2026-11-15 13:02:19 +00:00
Merge branch 'master' of github.com:jenkinsci/jenkins into 2.0
Conflicts: cli/pom.xml core/pom.xml plugins/pom.xml pom.xml test/pom.xml war/pom.xml
This commit is contained in:
commit
9cab873461
42 files changed
+1294
-731
No files matched your search
@@ -23,6 +23,7 @@
|
||||
*/
|
||||
package jenkins.model.lazy;
|
||||
|
||||
import java.io.File;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import jenkins.model.lazy.AbstractLazyLoadRunMap.Direction;
|
||||
@@ -31,13 +32,19 @@ import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Level;
|
||||
import jenkins.util.Timer;
|
||||
import org.junit.BeforeClass;
|
||||
import org.jvnet.hudson.test.Issue;
|
||||
|
||||
@@ -72,6 +79,29 @@ public class AbstractLazyLoadRunMapTest {
|
||||
}
|
||||
};
|
||||
|
||||
private final Map<Integer,Semaphore> slowBuilderStartSemaphores = new HashMap<>();
|
||||
private final Map<Integer,Semaphore> slowBuilderEndSemaphores = new HashMap<>();
|
||||
private final Map<Integer,AtomicInteger> slowBuilderLoadCount = new HashMap<>();
|
||||
@Rule
|
||||
public FakeMapBuilder slowBuilder = new FakeMapBuilder() {
|
||||
@Override
|
||||
public FakeMap make() {
|
||||
return new FakeMap(getDir()) {
|
||||
@Override
|
||||
protected Build retrieve(File dir) throws IOException {
|
||||
Build b = super.retrieve(dir);
|
||||
slowBuilderStartSemaphores.get(b.n).release();
|
||||
try {
|
||||
slowBuilderEndSemaphores.get(b.n).acquire();
|
||||
} catch (InterruptedException x) {
|
||||
throw new IOException(x);
|
||||
}
|
||||
slowBuilderLoadCount.get(b.n).incrementAndGet();
|
||||
return b;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpClass() {
|
||||
@@ -358,4 +388,36 @@ public class AbstractLazyLoadRunMapTest {
|
||||
assertTrue(a.entrySet().contains(e));
|
||||
}
|
||||
}
|
||||
|
||||
@Issue("JENKINS-22767")
|
||||
@Test
|
||||
public void slowRetrieve() throws Exception {
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
slowBuilder.add(i);
|
||||
slowBuilderStartSemaphores.put(i, new Semaphore(0));
|
||||
slowBuilderEndSemaphores.put(i, new Semaphore(0));
|
||||
slowBuilderLoadCount.put(i, new AtomicInteger());
|
||||
}
|
||||
final FakeMap m = slowBuilder.make();
|
||||
Future<Build> firstLoad = Timer.get().submit(new Callable<Build>() {
|
||||
@Override
|
||||
public Build call() throws Exception {
|
||||
return m.getByNumber(2);
|
||||
}
|
||||
});
|
||||
Future<Build> secondLoad = Timer.get().submit(new Callable<Build>() {
|
||||
@Override
|
||||
public Build call() throws Exception {
|
||||
return m.getByNumber(2);
|
||||
}
|
||||
});
|
||||
slowBuilderStartSemaphores.get(2).acquire(1);
|
||||
// now one of them is inside retrieve(…); the other is waiting for the lock
|
||||
slowBuilderEndSemaphores.get(2).release(2); // allow both to proceed
|
||||
Build first = firstLoad.get();
|
||||
Build second = secondLoad.get();
|
||||
assertEquals(1, slowBuilderLoadCount.get(2).get());
|
||||
assertSame(second, first);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user