mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-02-09 00:41:47 +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 Path watchedPath;
|
||||||
private Set<WatchedFile> watchedFiles;
|
private Set<WatchedFile> watchedFiles;
|
||||||
|
|
||||||
public FileWatcher(File folder, ErrorHandler errorHandler) {
|
public FileWatcher(
|
||||||
this(folder, errorHandler, new HashSet<>());
|
File folder,
|
||||||
|
ErrorHandler errorHandler
|
||||||
|
) {
|
||||||
|
this(folder.toPath(), errorHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileWatcher(
|
public FileWatcher(
|
||||||
File folder,
|
Path watchedPath,
|
||||||
ErrorHandler errorHandler,
|
ErrorHandler errorHandler
|
||||||
Set<WatchedFile> watchedFiles
|
|
||||||
) {
|
) {
|
||||||
this.errorHandler = errorHandler;
|
this.errorHandler = errorHandler;
|
||||||
this.running = false;
|
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) {
|
public void addToWatchlist(WatchedFile watchedFile) {
|
||||||
@ -73,6 +76,7 @@ public class FileWatcher extends Thread {
|
|||||||
runLoop(watcher);
|
runLoop(watcher);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
errorHandler.log(L.ERROR, this.getClass(), e);
|
errorHandler.log(L.ERROR, this.getClass(), e);
|
||||||
|
interrupt();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
interrupt();
|
interrupt();
|
||||||
}
|
}
|
||||||
@ -107,7 +111,7 @@ public class FileWatcher extends Thread {
|
|||||||
} else {
|
} else {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Path modifiedFile = ((WatchEvent<Path>) event).context();
|
Path modifiedFile = ((WatchEvent<Path>) event).context();
|
||||||
actOnModification(modifiedFile);
|
actOnModification(watchedPath.resolve(modifiedFile));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,4 +126,8 @@ public class FileWatcher extends Thread {
|
|||||||
running = false;
|
running = false;
|
||||||
super.interrupt();
|
super.interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isRunning() {
|
||||||
|
return running;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,22 +23,26 @@ import java.nio.file.Path;
|
|||||||
import java.util.Objects;
|
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
|
* @author Rsl1122
|
||||||
*/
|
*/
|
||||||
public class WatchedFile {
|
public class WatchedFile {
|
||||||
|
|
||||||
private final File file;
|
private final Path watchedPath;
|
||||||
private final VoidFunction onChange;
|
private final VoidFunction onChange;
|
||||||
|
|
||||||
public WatchedFile(File file, 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;
|
this.onChange = onChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void modified(Path modifiedPath) {
|
public void modified(Path modifiedPath) {
|
||||||
if (modifiedPath != null && file.toPath().equals(modifiedPath)) {
|
if (watchedPath.equals(modifiedPath)) {
|
||||||
onChange.apply();
|
onChange.apply();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -48,11 +52,11 @@ public class WatchedFile {
|
|||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
WatchedFile that = (WatchedFile) o;
|
WatchedFile that = (WatchedFile) o;
|
||||||
return Objects.equals(file, that.file);
|
return Objects.equals(watchedPath, that.watchedPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
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