1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package net.grinder.console.distribution;
23
24 import java.io.File;
25 import java.io.FileFilter;
26 import java.util.regex.Pattern;
27
28 import net.grinder.console.communication.DistributionControl;
29 import net.grinder.console.communication.ProcessControl;
30 import net.grinder.console.distribution.FileChangeWatcher.FileChangedListener;
31 import net.grinder.testutility.AbstractFileTestCase;
32 import net.grinder.testutility.AssertUtilities;
33 import net.grinder.testutility.CallData;
34 import net.grinder.testutility.FileUtilities;
35 import net.grinder.testutility.RandomStubFactory;
36 import net.grinder.util.Directory;
37
38
39
40
41
42
43
44 public class TestFileDistribution extends AbstractFileTestCase {
45
46 private final Pattern m_matchIgnoredPattern =
47 Pattern.compile("^.grinder/$");
48 private final Pattern m_matchAllPattern = Pattern.compile(".*");
49
50 private final RandomStubFactory<ProcessControl> m_processControlStubFactory =
51 RandomStubFactory.create(ProcessControl.class);
52 private final ProcessControl m_processControl =
53 m_processControlStubFactory.getStub();
54
55 public void testGetHandler() throws Exception {
56 final RandomStubFactory<DistributionControl> distributionControlStubFactory =
57 RandomStubFactory.create(DistributionControl.class);
58 final DistributionControl distributionControl =
59 distributionControlStubFactory.getStub();
60
61 final Directory directory1 = new Directory(getDirectory());
62
63 final FileDistributionImplementation fileDistribution =
64 new FileDistributionImplementation(distributionControl,
65 m_processControl,
66 directory1,
67 m_matchIgnoredPattern);
68
69 distributionControlStubFactory.assertNoMoreCalls();
70
71 assertNotNull(fileDistribution.getAgentCacheState());
72
73 final File anotherFile = new File(getDirectory(), "foo");
74 assertTrue(anotherFile.mkdir());
75 final Directory directory2 = new Directory(anotherFile);
76
77 final FileDistributionHandler fileDistributionHandler1 =
78 fileDistribution.getHandler();
79
80 distributionControlStubFactory.assertNoMoreCalls();
81
82
83 final FileDistributionHandler fileDistributionHandler2 =
84 fileDistribution.getHandler();
85
86 assertNotSame(fileDistributionHandler1, fileDistributionHandler2);
87 distributionControlStubFactory.assertNoMoreCalls();
88
89
90 fileDistribution.setDirectory(directory2);
91
92 final FileDistributionHandler fileDistributionHandler3 =
93 fileDistribution.getHandler();
94
95 assertNotSame(fileDistributionHandler1, fileDistributionHandler3);
96 assertNotSame(fileDistributionHandler2, fileDistributionHandler3);
97
98 distributionControlStubFactory.assertNoMoreCalls();
99 }
100
101 public void testScanDistributionFiles() throws Exception {
102 final RandomStubFactory<DistributionControl>
103 distributionControlStubFactory =
104 RandomStubFactory.create(DistributionControl.class);
105
106 final UpdateableAgentCacheStateStubFactory
107 agentCacheStateStubFactory =
108 new UpdateableAgentCacheStateStubFactory();
109
110 final UpdateableAgentCacheState agentCacheState =
111 agentCacheStateStubFactory.getStub();
112
113 final RandomStubFactory<FileChangedListener> fileListenerStubFactory =
114 RandomStubFactory.create(FileChangedListener.class);
115
116 final Directory directory = new Directory(getDirectory());
117 agentCacheStateStubFactory.override_setDirectory(null, directory);
118 agentCacheStateStubFactory.override_setFileFilterPattern(
119 null, m_matchIgnoredPattern);
120
121 final FileDistributionImplementation fileDistribution =
122 new FileDistributionImplementation(
123 distributionControlStubFactory.getStub(),
124 agentCacheState);
125 fileDistribution.addFileChangedListener(fileListenerStubFactory.getStub());
126
127 fileDistribution.scanDistributionFiles();
128
129 final CallData filesChangedCall =
130 fileListenerStubFactory.assertSuccess("filesChanged", File[].class);
131 final File[] changedFiles = (File[])(filesChangedCall.getParameters()[0]);
132 assertEquals(1, changedFiles.length);
133 assertTrue(changedFiles[0].equals(directory.getFile()));
134
135 fileListenerStubFactory.assertNoMoreCalls();
136
137 final File file1 = new File(getDirectory(), "file1");
138 assertTrue(file1.createNewFile());
139 final File file2 = new File(getDirectory(), "file2");
140 assertTrue(file2.createNewFile());
141 final File oldFile = new File(getDirectory(), "file3");
142 assertTrue(oldFile.createNewFile());
143 assertTrue(oldFile.setLastModified(0));
144 assertTrue(file2.setLastModified(file1.lastModified() + 5000));
145
146 assertTrue(file1.delete());
147 assertTrue(file1.createNewFile());
148 assertTrue(file2.delete());
149 assertTrue(file2.createNewFile());
150 assertTrue(file2.setLastModified(file1.lastModified() + 5000));
151
152 fileDistribution.scanDistributionFiles();
153 assertEquals(file1.lastModified(),
154 agentCacheStateStubFactory.getEarliestOutOfDateTime());
155
156 final CallData filesChangedCall2 =
157 fileListenerStubFactory.assertSuccess("filesChanged", File[].class);
158 final File[] changedFiles2 = (File[])(filesChangedCall2.getParameters()[0]);
159 assertEquals(3, changedFiles2.length);
160 AssertUtilities.assertArrayContainsAll(
161 changedFiles2,
162 new File[] { directory.getFile(), file1, file2 } );
163
164 fileListenerStubFactory.assertNoMoreCalls();
165
166
167
168 final File file4 = new File(getDirectory(), "file4");
169 assertTrue(file4.createNewFile());
170 agentCacheStateStubFactory.resetOutOfDate();
171 fileDistribution.scanDistributionFiles();
172 assertEquals(file4.lastModified(),
173 agentCacheStateStubFactory.getEarliestOutOfDateTime());
174 fileListenerStubFactory.resetCallHistory();
175
176 fileDistribution.setDirectory(directory);
177 fileDistribution.setFileFilterPattern(m_matchAllPattern);
178 fileDistribution.scanDistributionFiles();
179 fileListenerStubFactory.assertNoMoreCalls();
180
181
182 agentCacheStateStubFactory.resetOutOfDate();
183 final File testDirectory = new File(getDirectory(), "test");
184 assertTrue(testDirectory.mkdir());
185 fileDistribution.setDirectory(new Directory(testDirectory));
186
187
188 fileDistribution.setFileFilterPattern(m_matchIgnoredPattern);
189 fileDistribution.scanDistributionFiles();
190 fileListenerStubFactory.resetCallHistory();
191
192 assertTrue(testDirectory.setLastModified(
193 testDirectory.lastModified() + 5000));
194
195 final File directory1 = new File(getDirectory(), "test/dir1");
196 assertTrue(directory1.mkdir());
197 final File oldDirectory = new File(getDirectory(), "test/dir3");
198 assertTrue(oldDirectory.mkdir());
199 final File directory2 = new File(getDirectory(), "test/dir3/dir2");
200 assertTrue(directory2.mkdir());
201 assertTrue(oldDirectory.setLastModified(0));
202 assertTrue(file2.setLastModified(file1.lastModified() + 5000));
203
204 fileDistribution.scanDistributionFiles();
205
206 assertEquals(Long.MAX_VALUE,
207 agentCacheStateStubFactory.getEarliestOutOfDateTime());
208
209 final CallData directoriesChangedCall =
210 fileListenerStubFactory.assertSuccess("filesChanged", File[].class);
211 final File[] changedDirectories =
212 (File[])(directoriesChangedCall.getParameters()[0]);
213 assertEquals(3, changedDirectories.length);
214 AssertUtilities.assertArrayContainsAll(changedDirectories,
215 new File[] { testDirectory, directory1, directory2 } );
216
217 fileListenerStubFactory.assertNoMoreCalls();
218
219
220 fileDistribution.setDirectory(directory);
221 fileDistribution.scanDistributionFiles();
222 assertEquals(0, agentCacheStateStubFactory.getEarliestOutOfDateTime());
223 fileListenerStubFactory.resetCallHistory();
224
225
226 final Directory subdirectory =
227 new Directory(new File(getDirectory(), "subdirectory"));
228 subdirectory.create();
229 final File f1 = new File(subdirectory.getFile(), "file");
230 assertTrue(f1.createNewFile());
231
232 FileUtilities.setCanAccess(subdirectory.getFile(), false);
233
234 fileDistribution.setDirectory(subdirectory);
235 fileDistribution.scanDistributionFiles();
236
237 assertEquals(f1.lastModified(),
238 agentCacheStateStubFactory.getEarliestOutOfDateTime());
239
240 FileUtilities.setCanAccess(subdirectory.getFile(), true);
241 }
242
243 public static class UpdateableAgentCacheStateStubFactory
244 extends RandomStubFactory<UpdateableAgentCacheState> {
245
246 private long m_earliestOutOfDateTime = Long.MAX_VALUE;
247 private Directory m_directory;
248 private Pattern m_pattern;
249
250 public UpdateableAgentCacheStateStubFactory() {
251 super(UpdateableAgentCacheState.class);
252 }
253
254 public long getEarliestOutOfDateTime() {
255 return m_earliestOutOfDateTime;
256 }
257
258 public void override_setNewFileTime(Object proxy, long t) {
259 if (t < m_earliestOutOfDateTime) {
260 m_earliestOutOfDateTime = t;
261 }
262 }
263
264 public void resetOutOfDate() {
265 m_earliestOutOfDateTime = Long.MAX_VALUE;
266 }
267
268 public void override_setDirectory(Object proxy, Directory directory) {
269 m_directory = directory;
270 }
271
272 public void override_setFileFilterPattern(Object proxy,
273 Pattern fileFilterPattern) {
274 m_pattern = fileFilterPattern;
275 }
276
277 public CacheParameters override_getCacheParameters(Object proxy) {
278 return new CacheParametersImplementation(m_directory,
279 m_pattern);
280 }
281 }
282
283 public void testFilter() throws Exception {
284 final Pattern pattern = Pattern.compile("^a.*[^/]$|.*exclude.*|.*b/$");
285
286 final FileFilter filter =
287 new FileDistributionImplementation.FixedPatternFileFilter(10000L,
288 pattern);
289
290 final String[] acceptableFilenames = new String[] {
291 "DoesntStartWithA.acceptable",
292 "blah blah blah",
293 "blah-file-store",
294 };
295
296 for (int i = 0; i < acceptableFilenames.length; ++i) {
297 final File f = new File(getDirectory(), acceptableFilenames[i]);
298 assertTrue(f.createNewFile());
299 assertTrue(f.getPath() + " is acceptable", filter.accept(f));
300 }
301
302 final String[] unacceptableFileNames = new String[] {
303 "exclude me",
304 "a file beginning with a",
305 "a directory ending with b",
306 };
307
308 for (int i = 0; i < unacceptableFileNames.length; ++i) {
309 final File f = new File(getDirectory(), unacceptableFileNames[i]);
310 assertTrue(f.createNewFile());
311
312 assertTrue(f.getPath() + " is unacceptable", !filter.accept(f));
313 }
314
315 final File timeFile = new File(getDirectory(), "time file");
316 assertTrue(timeFile.createNewFile());
317 assertTrue(timeFile.getPath() + " is acceptable", filter.accept(timeFile));
318 assertTrue(timeFile.setLastModified(123L));
319 assertTrue(timeFile.getPath() + " is unacceptable",
320 !filter.accept(timeFile));
321
322
323
324 assertTrue(timeFile.setLastModified(101001L));
325 assertTrue(timeFile.getPath() + " is acceptable", filter.accept(timeFile));
326
327 final String[] acceptableDirectoryNames = new String[] {
328 "a directory ending with b.not",
329 "include me",
330 };
331
332 for (int i = 0; i < acceptableDirectoryNames.length; ++i) {
333 final File f = new File(getDirectory(), acceptableDirectoryNames[i]);
334 assertTrue(f.mkdir());
335 assertTrue(f.getPath() + " is acceptable", filter.accept(f));
336 }
337
338 final String[] unacceptableDirectoryNames = new String[] {
339 "a directory ending with b",
340 "exclude me",
341 };
342
343 for (int i = 0; i < unacceptableDirectoryNames.length; ++i) {
344 final File f = new File(getDirectory(), unacceptableDirectoryNames[i]);
345 assertTrue(f.getPath() + " is unacceptable", !filter.accept(f));
346 }
347
348 final File timeDirectory = new File(getDirectory(), "time directory");
349 assertTrue(timeDirectory.mkdir());
350 assertTrue(timeDirectory.getPath() + " is acceptable",
351 filter.accept(timeDirectory));
352 assertTrue(timeDirectory.setLastModified(123L));
353 assertTrue(timeDirectory.getPath() + " is acceptable",
354 filter.accept(timeDirectory));
355
356 final File fileStoreDirectory = new File(getDirectory(), "foo-file-store");
357 assertTrue(fileStoreDirectory.mkdir());
358 assertTrue(fileStoreDirectory.getPath() + " is acceptable",
359 filter.accept(fileStoreDirectory));
360
361 final File readMeFile = new File(fileStoreDirectory, "README.txt");
362 assertTrue(readMeFile.createNewFile());
363 assertTrue(fileStoreDirectory.getPath() + " is unacceptable",
364 !filter.accept(fileStoreDirectory));
365
366 assertTrue(readMeFile.delete());
367 assertTrue(fileStoreDirectory.getPath() + " is acceptable",
368 filter.accept(fileStoreDirectory));
369 }
370
371 public void testIsDistributableFile() throws Exception {
372 final Pattern pattern = Pattern.compile("^a.*[^/]$|.*exclude.*|.*b/$");
373
374 final FileDistributionImplementation fileDistribution =
375 new FileDistributionImplementation(
376 null, m_processControl, new Directory(getDirectory()), pattern);
377 final FileFilter filter = fileDistribution.getDistributionFileFilter();
378
379 final String[] acceptableFilenames = new String[] {
380 "DoesntStartWithA.acceptable",
381 "blah blah blah",
382 "blah-file-store",
383 };
384
385 for (int i = 0; i < acceptableFilenames.length; ++i) {
386 final File f = new File(getDirectory(), acceptableFilenames[i]);
387 assertTrue(f.createNewFile());
388 assertTrue(f.getPath() + " is distributable", filter.accept(f));
389 }
390
391 final String[] unacceptableFileNames = new String[] {
392 "exclude me",
393 "a file beginning with a",
394 "a directory ending with b",
395 };
396
397 for (int i = 0; i < unacceptableFileNames.length; ++i) {
398 final File f = new File(getDirectory(), unacceptableFileNames[i]);
399 assertTrue(f.createNewFile());
400
401 assertTrue(f.getPath() + " is not distributable", !filter.accept(f));
402 }
403
404
405 fileDistribution.setFileFilterPattern(Pattern.compile(".*exclude.*"));
406
407 assertTrue(!filter.accept(new File(getDirectory(), "exclude me")));
408 assertTrue(
409 filter.accept(new File(getDirectory(), "a file begining with a")));
410
411 }
412 }