View Javadoc
1   package org.apache.archiva.common.filelock;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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  //import org.apache.commons.io.IOUtils;
47  
48  /**
49   * @author Olivier Lamy
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              //file.createNewFile();
77  
78          }
79  
80          @Override
81          public void initialize() {
82  
83          }
84  
85          // Files.copy is not atomic so have to try several times in
86          // a multithreaded test
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         //concurrentFileWrite.setTrace( true );
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 }