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.engine.agent;
23
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertFalse;
26 import static org.junit.Assert.assertNotNull;
27 import static org.junit.Assert.assertTrue;
28 import static org.junit.Assert.fail;
29 import static org.mockito.Matchers.contains;
30 import static org.mockito.Matchers.isA;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.times;
33 import static org.mockito.Mockito.verify;
34 import static org.mockito.Mockito.verifyNoMoreInteractions;
35
36 import java.io.File;
37 import java.io.FileOutputStream;
38 import java.io.OutputStream;
39 import java.util.Random;
40
41 import net.grinder.communication.CommunicationException;
42 import net.grinder.communication.Message;
43 import net.grinder.communication.MessageDispatchSender;
44 import net.grinder.communication.SimpleMessage;
45 import net.grinder.messages.agent.CacheHighWaterMark;
46 import net.grinder.messages.agent.ClearCacheMessage;
47 import net.grinder.messages.agent.DistributeFileMessage;
48 import net.grinder.messages.agent.DistributionCacheCheckpointMessage;
49 import net.grinder.messages.agent.StubCacheHighWaterMark;
50 import net.grinder.testutility.AbstractJUnit4FileTestCase;
51 import net.grinder.testutility.FileUtilities;
52 import net.grinder.util.Directory;
53 import net.grinder.util.FileContents;
54
55 import org.junit.Test;
56 import org.slf4j.Logger;
57
58
59
60
61
62
63
64 public class TestFileStore extends AbstractJUnit4FileTestCase {
65
66 private static final Random s_random = new Random();
67
68 @Test public void testConstruction() throws Exception {
69
70 File.createTempFile("file", "", getDirectory());
71 assertEquals(1, getDirectory().list().length);
72
73 final FileStore fileStore = new FileStore(getDirectory(), null);
74 final File currentDirectory = fileStore.getDirectory().getFile();
75 assertNotNull(currentDirectory);
76
77 assertTrue(
78 currentDirectory.getPath().startsWith(getDirectory().getPath()));
79
80
81
82
83 assertEquals(1, getDirectory().list().length);
84 assertTrue(!currentDirectory.exists());
85
86
87 final File file1 = File.createTempFile("file", "", getDirectory());
88
89 try {
90 new FileStore(file1, null);
91 fail("Expected FileStoreException");
92 }
93 catch (FileStore.FileStoreException e) {
94 }
95
96
97
98 assertTrue(file1.delete());
99 assertTrue(file1.mkdir());
100 assertTrue(new File(file1, "current").createNewFile());
101
102 try {
103 new FileStore(file1, null);
104 fail("Expected FileStoreException");
105 }
106 catch (FileStore.FileStoreException e) {
107 }
108
109
110 final File readOnlyDirectory = new File(getDirectory(), "directory");
111 assertTrue(readOnlyDirectory.mkdir());
112 assertTrue(readOnlyDirectory.setReadOnly());
113
114 try {
115 new FileStore(readOnlyDirectory, null);
116 fail("Expected FileStoreException");
117 }
118 catch (FileStore.FileStoreException e) {
119 }
120
121
122
123 final File notThere = new File(getDirectory(), "notThere");
124 new FileStore(notThere, null);
125 }
126
127 @Test public void testSender() throws Exception {
128
129 final Logger logger = mock(Logger.class);
130
131 final FileStore fileStore = new FileStore(getDirectory(), logger);
132
133 final MessageDispatchSender messageDispatcher = new MessageDispatchSender();
134 fileStore.registerMessageHandlers(messageDispatcher);
135
136
137 final Message message0 = new SimpleMessage();
138 messageDispatcher.send(message0);
139 verifyNoMoreInteractions(logger);
140
141
142 messageDispatcher.shutdown();
143 verifyNoMoreInteractions(logger);
144
145
146 final File sourceDirectory = new File(getDirectory(), "source");
147 assertTrue(sourceDirectory.mkdirs());
148
149 final File file0 = new File(sourceDirectory, "dir/file0");
150 assertTrue(file0.getParentFile().mkdirs());
151 final OutputStream outputStream = new FileOutputStream(file0);
152 final byte[] bytes = new byte[500];
153 s_random.nextBytes(bytes);
154 outputStream.write(bytes);
155 outputStream.close();
156
157 final FileContents fileContents0 =
158 new FileContents(sourceDirectory, new File("dir/file0"));
159
160 final File readmeFile = new File(getDirectory(), "README.txt");
161 final File incomingDirectoryFile = new File(getDirectory(), "incoming");
162 final File currentDirectoryFile = new File(getDirectory(), "current");
163 assertEquals(currentDirectoryFile, fileStore.getDirectory().getFile());
164
165
166 assertTrue(!readmeFile.exists());
167 assertTrue(!incomingDirectoryFile.exists());
168 assertTrue(!currentDirectoryFile.exists());
169
170 final Message message1 = new DistributeFileMessage(fileContents0);
171
172
173 FileUtilities.setCanAccess(getDirectory(), false);
174
175 try {
176 messageDispatcher.send(message1);
177 fail("Expected CommunicationException");
178 }
179 catch (CommunicationException e) {
180 }
181
182 FileUtilities.setCanAccess(getDirectory(), true);
183
184 verify(logger).error(contains("Could not create directory"));
185
186 assertFalse(incomingDirectoryFile.delete());
187
188 messageDispatcher.send(message1);
189 verify(logger).info(contains("Updating file store"),
190 isA(FileContents.class));
191
192
193 assertTrue(readmeFile.exists());
194 assertTrue(incomingDirectoryFile.exists());
195 assertTrue(!currentDirectoryFile.exists());
196
197 final File targetFile = new File(incomingDirectoryFile, "dir/file0");
198 assertTrue(targetFile.canRead());
199
200 assertEquals(currentDirectoryFile, fileStore.getDirectory().getFile());
201
202
203 assertTrue(readmeFile.exists());
204 assertTrue(incomingDirectoryFile.exists());
205 assertTrue(currentDirectoryFile.exists());
206
207
208 new Directory(currentDirectoryFile).deleteContents();
209 assertTrue(currentDirectoryFile.delete());
210 assertTrue(currentDirectoryFile.createNewFile());
211
212 try {
213 fileStore.getDirectory();
214 fail("Expected FileStoreException");
215 }
216 catch (FileStore.FileStoreException e) {
217 }
218
219
220 assertTrue(currentDirectoryFile.delete());
221 fileStore.getDirectory();
222
223
224 assertTrue(targetFile.setReadOnly());
225
226 try {
227 messageDispatcher.send(message1);
228 fail("Expected CommunicationException");
229 }
230 catch (CommunicationException e) {
231 }
232
233 verify(logger, times(2)).info(contains("Updating file store"),
234 isA(FileContents.class));
235
236 verify(logger).error(contains("Failed to create file"));
237
238 final Message message2 = new ClearCacheMessage();
239
240 FileUtilities.setCanAccess(targetFile, false);
241
242 FileUtilities.setCanAccess(targetFile.getParentFile(), false);
243
244 try {
245 messageDispatcher.send(message2);
246 fail("Expected CommunicationException");
247 }
248 catch (CommunicationException e) {
249 }
250
251 FileUtilities.setCanAccess(targetFile.getParentFile(), true);
252 FileUtilities.setCanAccess(targetFile, true);
253
254 verify(logger).info(contains("Clearing file store"));
255 verify(logger).error(contains("Could not delete"));
256
257 messageDispatcher.send(message2);
258 verify(logger, times(2)).info(contains("Clearing file store"));
259 verifyNoMoreInteractions(logger);
260
261 assertTrue(!targetFile.canRead());
262
263 assertEquals(currentDirectoryFile, fileStore.getDirectory().getFile());
264 }
265
266 @Test public void testFileStoreException() throws Exception {
267 final Exception nested = new Exception("");
268 final FileStore.FileStoreException e =
269 new FileStore.FileStoreException("bite me", nested);
270
271 assertEquals(nested, e.getCause());
272 }
273
274 @Test public void testDistributionCheckpointMessage() throws Exception {
275 final FileStore fileStore = new FileStore(getDirectory(), null);
276
277 final CacheHighWaterMark outOfDateCacheHighWaterMark =
278 fileStore.getCacheHighWaterMark();
279 assertEquals(-1, outOfDateCacheHighWaterMark.getTime());
280 assertFalse(outOfDateCacheHighWaterMark.isForSameCache(
281 outOfDateCacheHighWaterMark));
282
283 final MessageDispatchSender messageDispatcher = new MessageDispatchSender();
284 fileStore.registerMessageHandlers(messageDispatcher);
285
286 final CacheHighWaterMark cacheHighWaterMark =
287 new StubCacheHighWaterMark("", 123);
288 final Message message =
289 new DistributionCacheCheckpointMessage(cacheHighWaterMark);
290
291 messageDispatcher.send(message);
292
293 assertEquals(cacheHighWaterMark, fileStore.getCacheHighWaterMark());
294 }
295 }