/*
* Copyright (C) 2012-2016 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.nifty.ssl;
import com.google.common.collect.ImmutableSet;
import io.airlift.units.Duration;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
public class PollingMultiFileWatcherTest {
private static class TestWatcher {
private final Set<File> filesToWatch;
private final PollingMultiFileWatcher watcher;
private final AtomicReference<Set<File>> updatedFiles;
TestWatcher(Set<File> filesToWatch, Duration initialDelay, Duration interval) {
this.filesToWatch = ImmutableSet.copyOf(filesToWatch);
watcher = new PollingMultiFileWatcher(initialDelay, interval);
updatedFiles = new AtomicReference<>(ImmutableSet.of());
}
private void onFilesUpdated(Set<File> modifiedFiles) {
updatedFiles.set(modifiedFiles);
}
Set<File> getUpdatedFilesSinceLastTime() {
Set<File> emptySet = ImmutableSet.of();
return updatedFiles.getAndSet(emptySet);
}
void start() {
watcher.start(filesToWatch, this::onFilesUpdated);
}
void shutdown() {
watcher.shutdown();
}
PollingMultiFileWatcher.Stats getStats() {
return watcher.getStats();
}
}
private File file1 = null;
private File file2 = null;
private TestWatcher poller = null;
@BeforeMethod
public void setUp() throws InterruptedException, IOException {
file1 = File.createTempFile("abstract_multi_file_poller_test", "file1");
Files.write(file1.toPath(), new byte[]{1}, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
file2 = File.createTempFile("abstract_multi_file_poller_test", "file2");
Files.write(file2.toPath(), new byte[]{2}, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
poller = new TestWatcher(ImmutableSet.of(file1, file2),
Duration.valueOf("0 ms"),
Duration.valueOf("100 ms"));
long callbacksSucceeded = poller.getStats().getCallbacksSucceeded();
poller.start();
while (poller.getStats().getCallbacksSucceeded() < callbacksSucceeded + 1) {
Thread.sleep(25);
}
Assert.assertEquals(poller.getUpdatedFilesSinceLastTime(), ImmutableSet.of(file1, file2));
}
@AfterMethod(alwaysRun = true)
public void tearDown() throws IOException {
if (poller != null) {
poller.shutdown();
poller = null;
}
if (file1 != null) {
Files.deleteIfExists(file1.toPath());
file1 = null;
}
if (file2 != null) {
Files.deleteIfExists(file2.toPath());
file2 = null;
}
}
@Test
public void testSingleFileUpdate() throws InterruptedException, IOException {
long fileChanges = poller.getStats().getFileChangesDetected();
Files.write(file1.toPath(), new byte[]{11}, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
while (fileChanges == poller.getStats().getFileChangesDetected()) {
Thread.sleep(25);
}
Assert.assertEquals(poller.getUpdatedFilesSinceLastTime(), ImmutableSet.of(file1));
}
@Test
public void testMultiFileUpdate() throws InterruptedException, IOException {
long fileChanges = poller.getStats().getFileChangesDetected();
Files.write(file1.toPath(), new byte[]{11}, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
Files.write(file2.toPath(), new byte[]{22}, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
while (poller.getStats().getFileChangesDetected() < fileChanges + 2) {
Thread.sleep(25);
}
Assert.assertEquals(poller.getUpdatedFilesSinceLastTime(), ImmutableSet.of(file1, file2));
}
@Test
public void testNoChanges() throws InterruptedException, IOException {
long pollCycles = poller.getStats().getPollCycles();
while (poller.getStats().getPollCycles() == pollCycles) {
Thread.sleep(25);
}
Assert.assertEquals(poller.getUpdatedFilesSinceLastTime().size(), 0);
}
@Test
public void testDelete() throws InterruptedException, IOException {
// When a file is deleted, we should not get an update about it
long pollCycles = poller.getStats().getPollCycles();
Files.deleteIfExists(file2.toPath());
while (pollCycles == poller.getStats().getPollCycles()) {
Thread.sleep(25);
}
Assert.assertEquals(poller.getUpdatedFilesSinceLastTime().size(), 0);
}
}