mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-02-02 13:31:29 +01:00
Test & fix for FileWatcher
- Test for modification listening - Fix for Path resolution when calling a WatchedFile
This commit is contained in:
parent
88f8653cb8
commit
3bdb85312c
@ -42,22 +42,25 @@ public class FileWatcher extends Thread {
|
||||
private Path watchedPath;
|
||||
private Set<WatchedFile> watchedFiles;
|
||||
|
||||
public FileWatcher(File folder, ErrorHandler errorHandler) {
|
||||
this(folder, errorHandler, new HashSet<>());
|
||||
public FileWatcher(
|
||||
File folder,
|
||||
ErrorHandler errorHandler
|
||||
) {
|
||||
this(folder.toPath(), errorHandler);
|
||||
}
|
||||
|
||||
public FileWatcher(
|
||||
File folder,
|
||||
ErrorHandler errorHandler,
|
||||
Set<WatchedFile> watchedFiles
|
||||
Path watchedPath,
|
||||
ErrorHandler errorHandler
|
||||
) {
|
||||
this.errorHandler = errorHandler;
|
||||
this.running = false;
|
||||
this.watchedFiles = watchedFiles;
|
||||
this.watchedFiles = new HashSet<>();
|
||||
|
||||
Verify.isTrue(folder.isDirectory(), () -> new IllegalArgumentException("Given File " + folder.getAbsolutePath() + " was not a folder."));
|
||||
|
||||
watchedPath = folder.toPath();
|
||||
Verify.isTrue(watchedPath.toFile().isDirectory(), () -> new IllegalArgumentException("Given File " + watchedPath.toString() + " was not a folder."));
|
||||
|
||||
this.watchedPath = watchedPath;
|
||||
}
|
||||
|
||||
public void addToWatchlist(WatchedFile watchedFile) {
|
||||
@ -73,6 +76,7 @@ public class FileWatcher extends Thread {
|
||||
runLoop(watcher);
|
||||
} catch (IOException e) {
|
||||
errorHandler.log(L.ERROR, this.getClass(), e);
|
||||
interrupt();
|
||||
} catch (InterruptedException e) {
|
||||
interrupt();
|
||||
}
|
||||
@ -107,7 +111,7 @@ public class FileWatcher extends Thread {
|
||||
} else {
|
||||
@SuppressWarnings("unchecked")
|
||||
Path modifiedFile = ((WatchEvent<Path>) event).context();
|
||||
actOnModification(modifiedFile);
|
||||
actOnModification(watchedPath.resolve(modifiedFile));
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,4 +126,8 @@ public class FileWatcher extends Thread {
|
||||
running = false;
|
||||
super.interrupt();
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return running;
|
||||
}
|
||||
}
|
||||
|
@ -23,22 +23,26 @@ import java.nio.file.Path;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* File with a consumer that is called if the file is modified.
|
||||
* File or Path with a function that is called if the file is modified.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class WatchedFile {
|
||||
|
||||
private final File file;
|
||||
private final Path watchedPath;
|
||||
private final VoidFunction onChange;
|
||||
|
||||
public WatchedFile(File file, VoidFunction onChange) {
|
||||
this.file = file;
|
||||
this(file.toPath(), onChange);
|
||||
}
|
||||
|
||||
public WatchedFile(Path path, VoidFunction onChange) {
|
||||
this.watchedPath = path;
|
||||
this.onChange = onChange;
|
||||
}
|
||||
|
||||
public void modified(Path modifiedPath) {
|
||||
if (modifiedPath != null && file.toPath().equals(modifiedPath)) {
|
||||
if (watchedPath.equals(modifiedPath)) {
|
||||
onChange.apply();
|
||||
}
|
||||
}
|
||||
@ -48,11 +52,11 @@ public class WatchedFile {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
WatchedFile that = (WatchedFile) o;
|
||||
return Objects.equals(file, that.file);
|
||||
return Objects.equals(watchedPath, that.watchedPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(file);
|
||||
return Objects.hash(watchedPath);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,62 @@
|
||||
package com.djrapitops.plan.utilities.file;
|
||||
|
||||
import com.jayway.awaitility.Awaitility;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.platform.runner.JUnitPlatform;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junitpioneer.jupiter.TempDirectory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@RunWith(JUnitPlatform.class)
|
||||
@ExtendWith(TempDirectory.class)
|
||||
class FileWatcherTest {
|
||||
|
||||
private Path temporaryDir;
|
||||
|
||||
@BeforeEach
|
||||
void setUpTemporaryDir(@TempDirectory.TempDir Path dir) {
|
||||
temporaryDir = dir;
|
||||
}
|
||||
|
||||
@Test
|
||||
void fileWatcherCallsWatchedFile() throws IOException {
|
||||
FileWatcher underTest = new FileWatcher(temporaryDir, null);
|
||||
File modified = temporaryDir.resolve("modifiedFile").toFile();
|
||||
|
||||
AtomicBoolean methodWasCalled = new AtomicBoolean(false);
|
||||
WatchedFile watchedFile = new WatchedFile(modified, () -> methodWasCalled.set(true));
|
||||
underTest.addToWatchlist(watchedFile);
|
||||
|
||||
try {
|
||||
underTest.start();
|
||||
Awaitility.await()
|
||||
.atMost(5, TimeUnit.SECONDS)
|
||||
.until(underTest::isRunning);
|
||||
|
||||
// Modification should trigger a watch event here.
|
||||
createAndModifyFile(modified);
|
||||
|
||||
Awaitility.await()
|
||||
.atMost(1, TimeUnit.SECONDS)
|
||||
.until(methodWasCalled::get);
|
||||
} finally {
|
||||
underTest.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
private void createAndModifyFile(File modified) throws IOException {
|
||||
modified.createNewFile();
|
||||
Files.write(modified.toPath(), Collections.singletonList("DataToWrite"), StandardCharsets.UTF_8);
|
||||
Files.write(modified.toPath(), Collections.singletonList("OverWrite"), StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user