Home | History | Annotate | Download | only in bugs
      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
     35     public void setUp() {
     36         target = Mockito.mock(ITarget.class);
     37         fixedThreadPool = Executors.newFixedThreadPool(nThreads);
     38     }
     39 
     40     @Test
     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 
     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 
     64         TargetInvoker(int seq) {
     65             this.seq = seq;
     66         }
     67 
     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 {
     82         String targetMethod(String arg);
     83     }
     84 
     85 }
     86