blob: 00e7fa769f50e0471aecdcde793c6f0cec77cd0c [file] [log] [blame]
/*
* Copyright 2012-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.facebook.buck.util;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.createStrictMock;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.eventbus.EventBus;
import org.easymock.Capture;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.nio.file.FileVisitor;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
public class ProjectFilesystemWatcherTest {
private EventBus eventBus;
private ProjectFilesystem filesystem;
private WatchService watchService;
private Path path;
private WatchKey key;
private WatchEvent<Path> event;
private Capture<FileVisitor<Path>> visitor;
private ProjectFilesystemWatcher watcher;
@Before
@SuppressWarnings("unchecked") // Needed to mock generic class.
public void setUp() throws IOException {
eventBus = createStrictMock(EventBus.class);
filesystem = createNiceMock(ProjectFilesystem.class);
watchService = createNiceMock(WatchService.class);
path = createNiceMock(Path.class);
key = createNiceMock(WatchKey.class);
event = createNiceMock(WatchEvent.class);
expect(filesystem.getRootPath()).andReturn(Paths.get("/"));
visitor = new Capture<>();
filesystem.walkFileTree(anyObject(Path.class), capture(visitor));
expect(path.normalize()).andReturn(path);
expect(path.register(anyObject(WatchService.class),
eq(StandardWatchEventKinds.ENTRY_CREATE),
eq(StandardWatchEventKinds.ENTRY_DELETE),
eq(StandardWatchEventKinds.ENTRY_MODIFY))).andReturn(key);
}
@Test
public void noEventsPostedWhenNoFilesChange() throws IOException {
// Return no events when WatchService is polled.
expect(watchService.poll()).andReturn(null);
replay(filesystem, eventBus, watchService, path, key, event);
// Pump ProjectFilesystemWatcher.
watcher = new ProjectFilesystemWatcher(
filesystem, eventBus, ImmutableSet.<String>of(), watchService);
visitor.getValue().preVisitDirectory(path, null);
watcher.postEvents();
// Check no events were posted to EventBus.
verify(filesystem, eventBus, watchService, path, key, event);
}
@Test
public void eventPostedWhenFileChanged() throws IOException {
// Return a single create event when WatchService polled.
expect(watchService.poll()).andReturn(key).andReturn(null);
expect(key.pollEvents()).andReturn(Lists.<WatchEvent<?>>newArrayList(event));
expect(filesystem.isPathChangeEvent(anyObject(WatchEvent.class))).andReturn(true).anyTimes();
expect(event.context()).andReturn(path);
expect(path.resolve(anyObject(Path.class))).andReturn(path);
expect(path.normalize()).andReturn(path);
expect(filesystem.isDirectory(
anyObject(Path.class), eq(LinkOption.NOFOLLOW_LINKS))).andReturn(false);
expect(key.reset()).andReturn(false);
eventBus.post(anyObject(WatchEvent.class));
replay(filesystem, eventBus, watchService, path, key, event);
// Pump ProjectFilesystemWatcher.
watcher = new ProjectFilesystemWatcher(
filesystem, eventBus, ImmutableSet.<String>of(), watchService);
visitor.getValue().preVisitDirectory(path, null);
watcher.postEvents();
// Check event was posted to EventBus.
verify(filesystem, eventBus, watchService, path, key, event);
}
@Test
public void noEventPostedWhenFileExcluded() throws IOException {
// Return a single modify event when WatchService polled.
expect(watchService.poll()).andReturn(key).andReturn(null);
expect(key.pollEvents()).andReturn(Lists.<WatchEvent<?>>newArrayList(event));
expect(filesystem.isPathChangeEvent(anyObject(WatchEvent.class))).andReturn(true).anyTimes();
expect(event.context()).andReturn(path);
expect(path.resolve(anyObject(Path.class))).andReturn(path);
expect(path.normalize()).andReturn(path);
expect(path.startsWith(anyObject(String.class))).andReturn(false).andReturn(true);
expect(key.reset()).andReturn(false);
replay(filesystem, eventBus, watchService, path, key, event);
// Pump ProjectFilesystemWatcher.
watcher = new ProjectFilesystemWatcher(
filesystem, eventBus, ImmutableSet.<String>of("/"), watchService);
visitor.getValue().preVisitDirectory(path, null);
watcher.postEvents();
// Check event was posted to EventBus.
verify(filesystem, eventBus, watchService, path, key, event);
}
}