1 package org.apache.archiva.common.filelock;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import edu.umd.cs.mtc.MultithreadedTestCase;
23 import edu.umd.cs.mtc.TestFramework;
24 import org.junit.Assert;
25 import org.junit.Before;
26 import org.junit.Test;
27 import org.junit.runner.RunWith;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30 import org.springframework.test.context.ContextConfiguration;
31 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
32
33 import javax.inject.Inject;
34 import javax.inject.Named;
35 import java.io.File;
36 import java.io.FileNotFoundException;
37 import java.io.FileOutputStream;
38 import java.io.IOException;
39 import java.nio.file.FileAlreadyExistsException;
40 import java.nio.file.Files;
41 import java.nio.file.Path;
42 import java.nio.file.Paths;
43 import java.nio.file.StandardCopyOption;
44 import java.util.concurrent.atomic.AtomicInteger;
45
46
47
48
49
50
51 @RunWith(SpringJUnit4ClassRunner.class)
52 @ContextConfiguration(locations = {"classpath*:/META-INF/spring-context.xml"})
53 public class DefaultFileLockManagerTest {
54
55 final Logger logger = LoggerFactory.getLogger(getClass());
56
57 @Inject
58 @Named(value = "fileLockManager#default")
59 FileLockManager fileLockManager;
60
61 class ConcurrentFileWrite
62 extends MultithreadedTestCase {
63
64
65 AtomicInteger success = new AtomicInteger(0);
66
67 FileLockManager fileLockManager;
68
69 File file = new File(System.getProperty("buildDirectory"), "foo.txt");
70
71 File largeJar = new File(System.getProperty("basedir"), "src/test/cassandra-all-2.0.3.jar");
72
73 ConcurrentFileWrite(FileLockManager fileLockManager)
74 throws IOException {
75 this.fileLockManager = fileLockManager;
76
77
78 }
79
80 @Override
81 public void initialize() {
82
83 }
84
85
86
87 private void copyFile(Path source, Path destination) {
88 int attempts = 10;
89 boolean finished = false;
90 while (!finished && attempts-- > 0) {
91 try {
92 Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING,
93 StandardCopyOption.COPY_ATTRIBUTES);
94 finished = true;
95 } catch (IOException ex) {
96
97 }
98 }
99 }
100
101 public void thread1()
102 throws FileLockException, FileLockTimeoutException, IOException {
103 try {
104 logger.info("thread1");
105 Lock lock = fileLockManager.writeFileLock(this.file);
106 try {
107 lock.getFile().delete();
108 copyFile(largeJar.toPath(), lock.getFile().toPath());
109 } finally {
110 fileLockManager.release(lock);
111 }
112 logger.info("thread1 ok");
113 success.incrementAndGet();
114 } catch (Throwable e) {
115 logger.error("Error occured " + e.getMessage());
116 e.printStackTrace();
117 throw e;
118 }
119 }
120
121 public void thread2()
122 throws FileLockException, FileLockTimeoutException, IOException {
123 try {
124 logger.info("thread2");
125 Lock lock = fileLockManager.writeFileLock(this.file);
126 try {
127 lock.getFile().delete();
128 copyFile(largeJar.toPath(), lock.getFile().toPath());
129 } finally {
130 fileLockManager.release(lock);
131 }
132 logger.info("thread2 ok");
133 success.incrementAndGet();
134 } catch (Throwable e) {
135 logger.error("Error occured " + e.getMessage());
136 e.printStackTrace();
137 throw e;
138 }
139
140 }
141
142 public void thread3()
143 throws FileLockException, FileLockTimeoutException, IOException {
144 try {
145 logger.info("thread3");
146 Lock lock = fileLockManager.readFileLock(this.file);
147 try {
148 Files.copy(Paths.get(lock.getFile().getPath()),
149 new FileOutputStream(File.createTempFile("foo", ".jar")));
150 } finally {
151 fileLockManager.release(lock);
152 }
153 logger.info("thread3 ok");
154 success.incrementAndGet();
155 } catch (Throwable e) {
156 logger.error("Error occured " + e.getMessage());
157 e.printStackTrace();
158 throw e;
159 }
160
161 }
162
163 public void thread4()
164 throws FileLockException, FileLockTimeoutException, IOException {
165 try {
166 logger.info("thread4");
167 Lock lock = fileLockManager.writeFileLock(this.file);
168 try {
169 lock.getFile().delete();
170 copyFile(largeJar.toPath(), lock.getFile().toPath());
171 } finally {
172 fileLockManager.release(lock);
173 }
174 logger.info("thread4 ok");
175 success.incrementAndGet();
176 } catch (Throwable e) {
177 logger.error("Error occured " + e.getMessage());
178 e.printStackTrace();
179 throw e;
180 }
181
182 }
183
184 public void thread5()
185 throws FileLockException, FileLockTimeoutException, IOException {
186 try {
187 logger.info("thread5");
188 Lock lock = fileLockManager.writeFileLock(this.file);
189 try {
190 lock.getFile().delete();
191 copyFile(largeJar.toPath(), lock.getFile().toPath());
192 } finally {
193 fileLockManager.release(lock);
194 }
195 logger.info("thread5 ok");
196 success.incrementAndGet();
197 } catch (Throwable e) {
198 logger.error("Error occured " + e.getMessage());
199 e.printStackTrace();
200 throw e;
201 }
202
203 }
204
205 public void thread6()
206 throws FileLockException, FileLockTimeoutException, IOException {
207 try {
208 logger.info("thread6");
209 Lock lock = fileLockManager.readFileLock(this.file);
210 try {
211 Files.copy(lock.getFile().toPath(), new FileOutputStream(File.createTempFile("foo", ".jar")));
212 } finally {
213 fileLockManager.release(lock);
214 }
215 logger.info("thread6 ok");
216 success.incrementAndGet();
217 } catch (Throwable e) {
218 logger.error("Error occured " + e.getMessage());
219 e.printStackTrace();
220 throw e;
221 }
222
223 }
224
225 public void thread7()
226 throws FileLockException, FileLockTimeoutException, IOException {
227 try {
228 logger.info("thread7");
229 Lock lock = fileLockManager.writeFileLock(this.file);
230 try {
231 lock.getFile().delete();
232 copyFile(largeJar.toPath(), lock.getFile().toPath());
233 } finally {
234 fileLockManager.release(lock);
235 }
236 logger.info("thread7 ok");
237 success.incrementAndGet();
238 } catch (Throwable e) {
239 logger.error("Error occured " + e.getMessage());
240 e.printStackTrace();
241 throw e;
242 }
243
244 }
245
246 public void thread8()
247 throws FileLockException, FileLockTimeoutException, IOException {
248 try {
249 logger.info("thread8");
250 Lock lock = fileLockManager.readFileLock(this.file);
251 try {
252 Files.copy(lock.getFile().toPath(), new FileOutputStream(File.createTempFile("foo", ".jar")));
253 } finally {
254 fileLockManager.release(lock);
255 }
256 logger.info("thread8 ok");
257 success.incrementAndGet();
258 } catch (Throwable e) {
259 logger.error("Error occured " + e.getMessage());
260 e.printStackTrace();
261 throw e;
262 }
263
264 }
265
266 public void thread9()
267 throws FileLockException, FileLockTimeoutException, IOException {
268 try {
269 logger.info("thread9");
270 Lock lock = fileLockManager.writeFileLock(this.file);
271 try {
272 lock.getFile().delete();
273 copyFile(largeJar.toPath(), lock.getFile().toPath());
274 } finally {
275 fileLockManager.release(lock);
276 }
277 logger.info("thread9 ok");
278 success.incrementAndGet();
279 } catch (Throwable e) {
280 logger.error("Error occured " + e.getMessage());
281 e.printStackTrace();
282 throw e;
283 }
284 }
285
286 public void thread10()
287 throws FileLockException, FileLockTimeoutException, IOException {
288 try {
289 logger.info("thread10");
290 Lock lock = fileLockManager.readFileLock(this.file);
291 try {
292 Files.copy(lock.getFile().toPath(), new FileOutputStream(File.createTempFile("foo", ".jar")));
293 } finally {
294 fileLockManager.release(lock);
295 }
296 logger.info("thread10 ok");
297 success.incrementAndGet();
298 } catch (Throwable e) {
299 logger.error("Error occured " + e.getMessage());
300 e.printStackTrace();
301 throw e;
302 }
303
304 }
305
306
307 }
308
309
310 @Before
311 public void initialize() {
312 fileLockManager.setSkipLocking(false);
313 fileLockManager.clearLockFiles();
314 }
315
316 @Test
317 public void testWrite()
318 throws Throwable {
319 ConcurrentFileWrite concurrentFileWrite = new ConcurrentFileWrite(fileLockManager);
320
321 TestFramework.runManyTimes(concurrentFileWrite, 10, TestFramework.DEFAULT_CLOCKPERIOD, 20);
322 logger.info("success: {}", concurrentFileWrite.success);
323 Assert.assertEquals(100, concurrentFileWrite.success.intValue());
324 }
325
326
327 }