1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
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 }