View Javadoc

1   package com.atlassian.plugin.cache.filecache.impl;
2   
3   import junit.framework.TestCase;
4   
5   import java.io.ByteArrayOutputStream;
6   import java.io.File;
7   import java.util.concurrent.CyclicBarrier;
8   
9   public class TestCachedFile extends TestCase {
10  
11  
12      public void testNormalOperation() throws Exception {
13          File tmp = File.createTempFile("TestCachedFile", "test");
14          tmp.delete();
15  
16          final MockFileCacheStreamProvider streamProvider = new MockFileCacheStreamProvider("foo");
17          final ByteArrayOutputStream out = new ByteArrayOutputStream();
18          
19          CachedFile cf = new CachedFile(tmp);
20          assertFalse(tmp.exists());
21  
22          cf.stream(out, streamProvider);
23          assertTrue(tmp.exists());
24          assertEquals(1, streamProvider.callCount);
25          assertEquals("foo", new String(out.toByteArray()));
26  
27          out.reset();
28          cf.stream(out, streamProvider);
29          assertTrue(tmp.exists());
30          assertEquals(1, streamProvider.callCount); // second time round, it should use the cache, not the streamProvider
31          assertEquals("foo", new String(out.toByteArray()));
32  
33          cf.deleteWhenPossible();
34          assertFalse(tmp.exists());
35  
36          out.reset();
37          cf.stream(out, streamProvider);
38          assertFalse(tmp.exists());
39          assertEquals(2, streamProvider.callCount); // this time, it will have to use the streamProvider
40          assertEquals("foo", new String(out.toByteArray()));
41      }
42      
43      public void testImmediateDelete() throws Exception {
44          File tmp = File.createTempFile("TestCachedFile", "test");
45          tmp.delete();
46  
47          final MockFileCacheStreamProvider streamProvider = new MockFileCacheStreamProvider("foo");
48          final ByteArrayOutputStream out = new ByteArrayOutputStream();
49  
50          CachedFile cf = new CachedFile(tmp);
51          assertFalse(tmp.exists());
52  
53          cf.deleteWhenPossible();
54          assertFalse(tmp.exists());
55  
56          cf.stream(out, streamProvider);
57          assertFalse(tmp.exists());
58          assertEquals(1, streamProvider.callCount);
59          assertEquals("foo", new String(out.toByteArray()));
60      }
61      
62      public void testConcurrentReaders() throws Exception {
63          File tmp = File.createTempFile("TestCachedFile", "test");
64          tmp.delete();
65  
66          final CachedFile cf = new CachedFile(tmp);
67  
68          final CyclicBarrier start = new CyclicBarrier(3);
69  
70          class ReaderThread extends Thread {
71              final MockFileCacheStreamProvider streamProvider = new MockFileCacheStreamProvider("foo");
72              final ByteArrayOutputStream out = new ByteArrayOutputStream();
73              Exception caught;
74              @Override
75              public void run() {
76                  try {
77                      start.await();
78                      
79                      cf.stream(out,  streamProvider);
80                  } catch (Exception e) {
81                      caught = e;
82                  }
83              }
84          }
85  
86          ReaderThread r1 = new ReaderThread();
87          ReaderThread r2 = new ReaderThread();
88          r1.start();
89          r2.start();
90          start.await();
91          r1.join();
92          r2.join();
93  
94          assertNull(r1.caught);
95          assertNull(r2.caught);
96  
97          // should have been called once, by one of the threads.
98          assertEquals(1, r1.streamProvider.callCount + r2.streamProvider.callCount);
99          assertTrue(tmp.exists());
100     }
101     public void testConcurrentDeleteDuringRead() throws Exception {
102         File tmp = File.createTempFile("TestCachedFile", "test");
103         tmp.delete();
104 
105         final CachedFile cf = new CachedFile(tmp);
106 
107         final CyclicBarrier start = new CyclicBarrier(3);
108 
109         class ReaderThread extends Thread {
110             final MockFileCacheStreamProvider streamProvider = new MockFileCacheStreamProvider("foo");
111             final ByteArrayOutputStream out = new ByteArrayOutputStream();
112             Exception caught;
113             @Override
114             public void run() {
115                 try {
116                     start.await();
117 
118                     cf.stream(out,  streamProvider);
119                 } catch (Exception e) {
120                     caught = e;
121                 }
122             }
123         }
124 
125         ReaderThread r1 = new ReaderThread();
126         ReaderThread r2 = new ReaderThread();
127         r1.start();
128         r2.start();
129         start.await();
130         r1.join();
131         r2.join();
132 
133         assertNull(r1.caught);
134         assertNull(r2.caught);
135 
136         // should have been called once, by one of the threads.
137         assertEquals(1, r1.streamProvider.callCount + r2.streamProvider.callCount);
138         assertTrue(tmp.exists());
139     }
140 
141     public void testExceptionDuringClosingOfCachedFile() throws Exception {
142         File tmp = File.createTempFile("TestCachedFile", "test");
143         tmp.delete();
144 
145         ThrowingFileOpener fileOpener = new ThrowingFileOpener();
146         fileOpener.setOnClose(new RuntimeException("re-close"));
147         final CachedFile cf = new CachedFile(tmp, fileOpener);
148         
149         final MockFileCacheStreamProvider streamProvider = new MockFileCacheStreamProvider("foo");
150         final ByteArrayOutputStream out = new ByteArrayOutputStream();
151 
152         cf.stream(out, streamProvider);
153         // exceptions writing to cache aren't propagated
154         assertEquals(CachedFile.State.DELETED, cf.getState());
155     }
156 
157     public void testExceptionDuringInitialCaching() throws Exception {
158         File tmp = File.createTempFile("TestCachedFile", "test");
159         tmp.delete();
160 
161         final CachedFile cf = new CachedFile(tmp);
162 
163         final MockFileCacheStreamProvider streamProvider = new MockFileCacheStreamProvider("foo", new NullPointerException("bar"));
164         final ByteArrayOutputStream out = new ByteArrayOutputStream();
165 
166         try {
167             cf.stream(out, streamProvider);
168             fail("expected a NPE");
169         } catch (NullPointerException e) {
170             assertEquals("bar", e.getMessage());
171         }
172         assertEquals(CachedFile.State.DELETED, cf.getState());
173     }
174 
175 }