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 org.junit.Before; 8 import org.junit.Test; 9 import org.mockito.Mockito; 10 11 import java.util.concurrent.Callable; 12 import java.util.concurrent.ExecutionException; 13 import java.util.concurrent.ExecutorService; 14 import java.util.concurrent.Executors; 15 16 import static 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 = 1000; // Leave 1000ms extra before timing out as leeway for test overheads 43 int expectedMaxTestLength = TIMES * INTERVAL_MILLIS + potentialOverhead; 44 45 reset(target); 46 startInvocations(); 47 48 verify(target, timeout(expectedMaxTestLength).times(TIMES * nThreads)).targetMethod("arg"); 49 verifyNoMoreInteractions(target); 50 } 51 startInvocations()52 private void startInvocations() throws InterruptedException, 53 ExecutionException { 54 55 for(int i=0; i<nThreads; i++) { 56 fixedThreadPool.submit(new TargetInvoker(i)); 57 } 58 59 } 60 61 public class TargetInvoker implements Callable<Object> { 62 private final int seq; 63 TargetInvoker(int seq)64 TargetInvoker(int seq) { 65 this.seq = seq; 66 } 67 call()68 public Object call() throws Exception { 69 System.err.println("started " + seq); 70 for (int i = 0; i < TIMES; i++) { 71 Thread.yield(); 72 target.targetMethod("arg"); 73 Thread.sleep((long) INTERVAL_MILLIS); 74 } 75 System.err.println("finished" + seq); 76 return seq; 77 } 78 79 } 80 81 public interface ITarget { targetMethod(String arg)82 String targetMethod(String arg); 83 } 84 85 } 86