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);
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);
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
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
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
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 }