samples/reentrant/test/org/apidesign/reentrant/CriticalSectionBase.java
author Jaroslav Tulach <jtulach@netbeans.org>
Sat, 14 Jun 2008 18:51:38 +0200
changeset 263 7e8e995065c5
parent 112 64308321f7bd
permissions -rw-r--r--
Tests of all modules are executed and can fail the build
     1 package org.apidesign.reentrant;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Iterator;
     5 import java.util.List;
     6 import org.junit.Test;
     7 import static org.junit.Assert.*;
     8 
     9 public abstract class CriticalSectionBase {
    10     protected abstract CriticalSection<Integer> create();
    11     protected boolean reentrantJustOnce() {
    12         return false;
    13     }
    14 
    15     // BEGIN: reentrant.ok.call
    16     @Test
    17     public void testCriticalSectionWith15() {
    18         final CriticalSection<Integer> cs = create();
    19         testFor15(cs);
    20     }
    21     // END: reentrant.ok.call
    22     
    23     final void testFor15(CriticalSection<Integer> cs) {
    24         cs.assignPilot(15);
    25 
    26         List<Integer> ints = new ArrayList<Integer>();
    27         ints.add(8);
    28         ints.add(11);
    29         ints.add(10);
    30         ints.add(5);
    31         ints.add(12);
    32         ints.add(18);
    33         ints.add(13);
    34         ints.add(7);
    35 
    36         int cnt = cs.sumBigger(ints);
    37 
    38         assertEquals("18 is bigger than 15", 1, cnt);
    39         
    40     }
    41     
    42     @Test 
    43     public void teaseCriticalSectionWithReentrantCalls() {
    44         if (Boolean.getBoolean("no.failures")) return;
    45         
    46         final CriticalSection<Integer> cs = create();
    47         
    48         cs.assignPilot(10);
    49         
    50         class ChangePilotTo15 implements Runnable {
    51             // BEGIN: reentrant.forbidden.call
    52             // if this runnable is called from inside the critical section,
    53             // and the locks are non-reentrant then it throws an exception
    54             public void run() {
    55                 testFor15(cs);
    56             }
    57             // END: reentrant.forbidden.call
    58         }
    59         
    60         List<Integer> ints = new MyCollection(new ChangePilotTo15(), 3);
    61         ints.add(8);
    62         ints.add(11);
    63         ints.add(10);
    64         ints.add(5);
    65         ints.add(12);
    66         ints.add(18);
    67         ints.add(13);
    68         ints.add(7);
    69         
    70         int cnt = cs.sumBigger(ints);
    71         
    72         assertEquals("11, 12, 18, 13 are bigger than 10", 4, cnt);
    73         
    74         assertEquals("Global count is sum of ints(e.g. 4) plus result of testFor15(e.g. 1)", 5, cs.getCount());
    75     }
    76 
    77     class MyCollection extends ArrayList<Integer> {
    78         private Runnable callback;
    79         private final int callbackBeforeIndex;
    80 
    81         public MyCollection(Runnable callback, int callbackAtIndex) {
    82             this.callback = callback;
    83             this.callbackBeforeIndex = callbackAtIndex;
    84         }
    85 
    86         @Override
    87         public Iterator<Integer> iterator() {
    88             final Iterator<Integer> delegate = super.iterator();
    89             class It implements Iterator<Integer> {
    90                 private int index;
    91                 
    92                 public boolean hasNext() {
    93                     return delegate.hasNext();
    94                 }
    95 
    96                 public Integer next() {
    97                     if (index++ == callbackBeforeIndex) {
    98                         if (callback != null) {
    99                             callback.run();
   100                         }
   101                         if (reentrantJustOnce()) {
   102                             callback = null;
   103                         }
   104                     }
   105                     
   106                     return delegate.next();
   107                 }
   108 
   109                 public void remove() {
   110                     delegate.remove();
   111                 }
   112             } // end of It
   113             
   114             return new It();
   115         }
   116     }
   117 }