blob: bc52c4102a37acf9b0b2e5c6deffdb4997e02b27 [file] [log] [blame]
/*
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockitousage.bugs;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static org.mockito.Mockito.*;
// issue 322
// the only evidence of this failing test was shown on a RHEL with IBM J9 JVM 64bits
//
// details
// java.fullversion=JRE 1.6.0 IBM J9 2.6 Linux amd64-64 20111113_94967 (JIT enabled, AOT enabled)
// Linux2.6.32-220.4.2.el6.x86_64 #1SMP Mon Feb 6 16:39:28EST 2012x86_64 x86_64 x86_64 GNU/Linux
public class ConcurrentModificationExceptionOnMultiThreadedVerificationTest {
int nThreads = 1;
static final int TIMES = 100;
static final int INTERVAL_MILLIS = 10;
ITarget target = Mockito.mock(ITarget.class);
ExecutorService fixedThreadPool;
@Before
public void setUp() {
target = Mockito.mock(ITarget.class);
fixedThreadPool = Executors.newFixedThreadPool(nThreads);
}
@Test
public void shouldSuccessfullyVerifyConcurrentInvocationsWithTimeout() throws Exception {
int potentialOverhead = 1000; // Leave 1000ms extra before timing out as leeway for test overheads
int expectedMaxTestLength = TIMES * INTERVAL_MILLIS + potentialOverhead;
reset(target);
startInvocations();
verify(target, timeout(expectedMaxTestLength).times(TIMES * nThreads)).targetMethod("arg");
verifyNoMoreInteractions(target);
}
private void startInvocations() throws InterruptedException,
ExecutionException {
for(int i=0; i<nThreads; i++) {
fixedThreadPool.submit(new TargetInvoker(i));
}
}
public class TargetInvoker implements Callable<Object> {
private final int seq;
TargetInvoker(int seq) {
this.seq = seq;
}
public Object call() throws Exception {
System.err.println("started " + seq);
for (int i = 0; i < TIMES; i++) {
Thread.yield();
target.targetMethod("arg");
Thread.sleep((long) INTERVAL_MILLIS);
}
System.err.println("finished" + seq);
return seq;
}
}
public interface ITarget {
String targetMethod(String arg);
}
}