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 static org.junit.Assert.fail;
      8 
      9 import org.junit.Test;
     10 import org.mockito.Mockito;
     11 import org.mockito.invocation.InvocationOnMock;
     12 import org.mockito.stubbing.Answer;
     13 
     14 import java.util.concurrent.ExecutorService;
     15 import java.util.concurrent.Executors;
     16 import java.util.concurrent.TimeUnit;
     17 import java.util.concurrent.atomic.AtomicInteger;
     18 
     19 //see bug 190
     20 public class ShouldNotDeadlockAnswerExecutionTest {
     21 
     22     @Test
     23     public void failIfMockIsSharedBetweenThreads() throws Exception {
     24         Service service = Mockito.mock(Service.class);
     25         ExecutorService threads = Executors.newCachedThreadPool();
     26         AtomicInteger counter = new AtomicInteger(2);
     27 
     28         // registed answer on verySlowMethod
     29 
     30         Mockito.when(service.verySlowMethod()).thenAnswer(new LockingAnswer(counter));
     31 
     32         // execute verySlowMethod twice in separate threads
     33 
     34         threads.execute(new ServiceRunner(service));
     35         threads.execute(new ServiceRunner(service));
     36 
     37         // waiting for threads to finish
     38 
     39         threads.shutdown();
     40 
     41         if (!threads.awaitTermination(1000, TimeUnit.MILLISECONDS)) {
     42             // threads were timed-out
     43             fail();
     44         }
     45     }
     46 
     47     @Test
     48     public void successIfEveryThreadHasItsOwnMock() throws Exception {
     49         Service service1 = Mockito.mock(Service.class);
     50         Service service2 = Mockito.mock(Service.class);
     51         ExecutorService threads = Executors.newCachedThreadPool();
     52         AtomicInteger counter = new AtomicInteger(2);
     53 
     54         // registed answer on verySlowMethod
     55 
     56         Mockito.when(service1.verySlowMethod()).thenAnswer(new LockingAnswer(counter));
     57         Mockito.when(service2.verySlowMethod()).thenAnswer(new LockingAnswer(counter));
     58 
     59         // execute verySlowMethod twice in separate threads
     60 
     61         threads.execute(new ServiceRunner(service1));
     62         threads.execute(new ServiceRunner(service2));
     63 
     64         // waiting for threads to finish
     65 
     66         threads.shutdown();
     67 
     68         if (!threads.awaitTermination(500, TimeUnit.MILLISECONDS)) {
     69             // threads were timed-out
     70             fail();
     71         }
     72     }
     73 
     74     static class LockingAnswer implements Answer<String> {
     75 
     76         private AtomicInteger counter;
     77 
     78         public LockingAnswer(AtomicInteger counter) {
     79             this.counter = counter;
     80         }
     81 
     82         /**
     83          * Decrement counter and wait until counter has value 0
     84          */
     85         public String answer(InvocationOnMock invocation) throws Throwable {
     86             counter.decrementAndGet();
     87 
     88             while (counter.get() != 0) {
     89                 Thread.sleep(10);
     90             }
     91 
     92             return null;
     93         }
     94 
     95     }
     96 
     97     static class ServiceRunner implements Runnable {
     98 
     99         private Service service;
    100 
    101         public ServiceRunner(Service service) {
    102             this.service = service;
    103         }
    104 
    105         public void run() {
    106             service.verySlowMethod();
    107         }
    108 
    109     }
    110 
    111     interface Service {
    112 
    113         String verySlowMethod();
    114 
    115     }
    116 
    117 }
    118 
    119