View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.eclipse.aether.internal.impl;
20  
21  import java.io.File;
22  import java.nio.charset.StandardCharsets;
23  import java.util.ArrayList;
24  import java.util.Collections;
25  import java.util.HashMap;
26  import java.util.List;
27  import java.util.Map;
28  import java.util.Properties;
29  
30  import org.eclipse.aether.internal.test.util.TestFileUtils;
31  import org.junit.Test;
32  
33  import static org.junit.Assert.*;
34  
35  /**
36   */
37  public class DefaultTrackingFileManagerTest {
38  
39      @Test
40      public void testRead() throws Exception {
41          TrackingFileManager tfm = new DefaultTrackingFileManager();
42  
43          File propFile = TestFileUtils.createTempFile("#COMMENT\nkey1=value1\nkey2 : value2");
44          Properties props = tfm.read(propFile);
45  
46          assertNotNull(props);
47          assertEquals(String.valueOf(props), 2, props.size());
48          assertEquals("value1", props.get("key1"));
49          assertEquals("value2", props.get("key2"));
50  
51          assertTrue("Leaked file: " + propFile, propFile.delete());
52  
53          props = tfm.read(propFile);
54          assertNull(String.valueOf(props), props);
55      }
56  
57      @Test
58      public void testReadNoFileLeak() throws Exception {
59          TrackingFileManager tfm = new DefaultTrackingFileManager();
60  
61          for (int i = 0; i < 1000; i++) {
62              File propFile = TestFileUtils.createTempFile("#COMMENT\nkey1=value1\nkey2 : value2");
63              assertNotNull(tfm.read(propFile));
64              assertTrue("Leaked file: " + propFile, propFile.delete());
65          }
66      }
67  
68      @Test
69      public void testUpdate() throws Exception {
70          TrackingFileManager tfm = new DefaultTrackingFileManager();
71  
72          // NOTE: The excessive repetitions are to check the update properly truncates the file
73          File propFile =
74                  TestFileUtils.createTempFile("key1=value1\nkey2 : value2\n".getBytes(StandardCharsets.UTF_8), 1000);
75  
76          Map<String, String> updates = new HashMap<>();
77          updates.put("key1", "v");
78          updates.put("key2", null);
79  
80          tfm.update(propFile, updates);
81  
82          Properties props = tfm.read(propFile);
83  
84          assertNotNull(props);
85          assertEquals(String.valueOf(props), 1, props.size());
86          assertEquals("v", props.get("key1"));
87          assertNull(String.valueOf(props.get("key2")), props.get("key2"));
88      }
89  
90      @Test
91      public void testUpdateNoFileLeak() throws Exception {
92          TrackingFileManager tfm = new DefaultTrackingFileManager();
93  
94          Map<String, String> updates = new HashMap<>();
95          updates.put("k", "v");
96  
97          for (int i = 0; i < 1000; i++) {
98              File propFile = TestFileUtils.createTempFile("#COMMENT\nkey1=value1\nkey2 : value2");
99              assertNotNull(tfm.update(propFile, updates));
100             assertTrue("Leaked file: " + propFile, propFile.delete());
101         }
102     }
103 
104     @Test
105     public void testLockingOnCanonicalPath() throws Exception {
106         final TrackingFileManager tfm = new DefaultTrackingFileManager();
107 
108         final File propFile = TestFileUtils.createTempFile("#COMMENT\nkey1=value1\nkey2 : value2");
109 
110         final List<Throwable> errors = Collections.synchronizedList(new ArrayList<>());
111 
112         Thread[] threads = new Thread[4];
113         for (int i = 0; i < threads.length; i++) {
114             String path = propFile.getParent();
115             for (int j = 0; j < i; j++) {
116                 path += "/.";
117             }
118             path += "/" + propFile.getName();
119             final File file = new File(path);
120 
121             threads[i] = new Thread(() -> {
122                 try {
123                     for (int i1 = 0; i1 < 1000; i1++) {
124                         assertNotNull(tfm.read(file));
125                         HashMap<String, String> update = new HashMap<>();
126                         update.put("wasHere", Thread.currentThread().getName() + "-" + i1);
127                         tfm.update(file, update);
128                     }
129                 } catch (Throwable e) {
130                     errors.add(e);
131                 }
132             });
133         }
134 
135         for (Thread thread1 : threads) {
136             thread1.start();
137         }
138 
139         for (Thread thread : threads) {
140             thread.join();
141         }
142 
143         assertEquals(Collections.emptyList(), errors);
144     }
145 }