1 /* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 package org.mockitousage.bugs; 6 7 import static org.mockito.Mockito.*; 8 9 import java.util.concurrent.Callable; 10 import java.util.concurrent.ExecutionException; 11 import java.util.concurrent.ExecutorService; 12 import java.util.concurrent.Executors; 13 14 import org.junit.Before; 15 import org.junit.Test; 16 import org.mockito.Mockito; 17 18 // issue 322 19 // the only evidence of this failing test was shown on a RHEL with IBM J9 JVM 64bits 20 // 21 // details 22 // java.fullversion=JRE 1.6.0 IBM J9 2.6 Linux amd64-64 20111113_94967 (JIT enabled, AOT enabled) 23 // Linux2.6.32-220.4.2.el6.x86_64 #1SMP Mon Feb 6 16:39:28EST 2012x86_64 x86_64 x86_64 GNU/Linux 24 public class ConcurrentModificationExceptionOnMultiThreadedVerificationTest { 25 26 int nThreads = 1; 27 28 static final int TIMES = 100; 29 static final int INTERVAL_MILLIS = 10; 30 31 ITarget target = Mockito.mock(ITarget.class); 32 ExecutorService fixedThreadPool; 33 34 @Before setUp()35 public void setUp() { 36 target = Mockito.mock(ITarget.class); 37 fixedThreadPool = Executors.newFixedThreadPool(nThreads); 38 } 39 40 @Test shouldSuccessfullyVerifyConcurrentInvocationsWithTimeout()41 public void shouldSuccessfullyVerifyConcurrentInvocationsWithTimeout() throws Exception { 42 int potentialOverhead = 43 1000; // Leave 1000ms extra before timing out as leeway for test overheads 44 int expectedMaxTestLength = TIMES * INTERVAL_MILLIS + potentialOverhead; 45 46 reset(target); 47 startInvocations(); 48 49 verify(target, timeout(expectedMaxTestLength).times(TIMES * nThreads)).targetMethod("arg"); 50 verifyNoMoreInteractions(target); 51 } 52 startInvocations()53 private void startInvocations() throws InterruptedException, ExecutionException { 54 55 for (int i = 0; i < nThreads; i++) { 56 fixedThreadPool.submit(new TargetInvoker(i)); 57 } 58 } 59 60 public class TargetInvoker implements Callable<Object> { 61 private final int seq; 62 TargetInvoker(int seq)63 TargetInvoker(int seq) { 64 this.seq = seq; 65 } 66 call()67 public Object call() throws Exception { 68 System.err.println("started " + seq); 69 for (int i = 0; i < TIMES; i++) { 70 Thread.yield(); 71 target.targetMethod("arg"); 72 Thread.sleep((long) INTERVAL_MILLIS); 73 } 74 System.err.println("finished" + seq); 75 return seq; 76 } 77 } 78 79 public interface ITarget { targetMethod(String arg)80 String targetMethod(String arg); 81 } 82 } 83