View Javadoc
1   package org.pojomatic.internal;
2   
3   import static org.testng.Assert.*;
4   import org.testng.annotations.Test;
5   import java.util.concurrent.atomic.AtomicBoolean;
6   
7   public class SelfPopulatingMapTest {
8     /**
9      * Test case which exposes a subtle threading bug
10     * @throws Exception
11     */
12    @Test public void testThreading() throws Exception {
13      final String token = "token";
14      final SelfPopulatingMap<String, String> selfPopulatingMap =
15        new SelfPopulatingMap<String, String>() {
16        @Override protected String create(String key) {
17          try {
18            Thread.sleep(10); // ensure that two threads have time to collide.
19          }
20          catch (InterruptedException e) {}
21          return new String(key);
22        }
23      };
24  
25      int numThreads = 2;
26      Thread[] threads = new Thread[numThreads];
27      final String[] results = new String[numThreads];
28      for (int i = 0; i < threads.length; i++) {
29        final int threadNumber = i;
30        threads[i] = new Thread() {
31          @Override public void run() {
32            results[threadNumber] = selfPopulatingMap.get(token);
33          }
34        };
35      }
36      for (Thread t: threads) {
37        t.start();
38      }
39      for (Thread t: threads) {
40        t.join();
41      }
42      assertSame(results[1], results[0]);
43    }
44  
45    @Test
46    public void testBadConstructionFirstTime() {
47      final AtomicBoolean firstTime = new AtomicBoolean(false);
48      final SelfPopulatingMap<String, String> selfPopulatingMap =
49        new SelfPopulatingMap<String, String>() {
50        @Override protected String create(String key) {
51          if (firstTime.getAndSet(true)) {
52            return new String(key);
53          }
54          else {
55            throw new RuntimeException("first");
56          }
57        }
58      };
59  
60      try {
61        selfPopulatingMap.get("x");
62        fail("Exception expected");
63      }
64      catch(RuntimeException e) {
65        assertEquals(e.getMessage(), "first");
66      }
67  
68      assertEquals(selfPopulatingMap.get("x"), "x");
69    }
70  }