Compare commits
No commits in common. "bfd1125449bc78532d231b6f75e3dd5e0d2c031a" and "daf58bd4dcd8a023e5fb6ffef7473387999f1c7c" have entirely different histories.
bfd1125449
...
daf58bd4dc
4 changed files with 7 additions and 249 deletions
|
|
@ -253,12 +253,6 @@ fn thread_fn(
|
||||||
}
|
}
|
||||||
gop.value_ptr.* = ot;
|
gop.value_ptr.* = ot;
|
||||||
}
|
}
|
||||||
// A directory that appears via move-in carries existing children
|
|
||||||
// that will never generate FILE_ACTION_ADDED events. Scan its
|
|
||||||
// contents into the cache so subsequent deletes resolve their
|
|
||||||
// type. Scanning a genuinely new (empty) directory is a no-op.
|
|
||||||
if (ot == .dir and event_type == .created)
|
|
||||||
scan_path_types_into(allocator, path_types, full_path);
|
|
||||||
break :blk ot;
|
break :blk ot;
|
||||||
};
|
};
|
||||||
// Suppress FILE_ACTION_MODIFIED on directories: these are
|
// Suppress FILE_ACTION_MODIFIED on directories: these are
|
||||||
|
|
|
||||||
|
|
@ -643,146 +643,6 @@ fn testRenameThenModify(comptime Watcher: type, allocator: std.mem.Allocator) !v
|
||||||
try std.testing.expect(rename_idx < modify_idx);
|
try std.testing.expect(rename_idx < modify_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn testMoveOutFile(comptime Watcher: type, allocator: std.mem.Allocator) !void {
|
|
||||||
const TH = MakeTestHandler(Watcher);
|
|
||||||
|
|
||||||
const watched = try makeTempDir(allocator);
|
|
||||||
defer {
|
|
||||||
removeTempDir(watched);
|
|
||||||
allocator.free(watched);
|
|
||||||
}
|
|
||||||
const other = try makeTempDir(allocator);
|
|
||||||
defer {
|
|
||||||
removeTempDir(other);
|
|
||||||
allocator.free(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
const th = try TH.init(allocator);
|
|
||||||
defer th.deinit();
|
|
||||||
|
|
||||||
var watcher = try Watcher.init(allocator, &th.handler);
|
|
||||||
defer watcher.deinit();
|
|
||||||
try watcher.watch(watched);
|
|
||||||
|
|
||||||
const src_path = try std.fs.path.join(allocator, &.{ watched, "moveme.txt" });
|
|
||||||
defer allocator.free(src_path);
|
|
||||||
const dst_path = try std.fs.path.join(allocator, &.{ other, "moveme.txt" });
|
|
||||||
defer allocator.free(dst_path);
|
|
||||||
|
|
||||||
{
|
|
||||||
const f = try std.fs.createFileAbsolute(src_path, .{});
|
|
||||||
f.close();
|
|
||||||
}
|
|
||||||
try drainEvents(Watcher, &watcher);
|
|
||||||
|
|
||||||
try std.fs.renameAbsolute(src_path, dst_path);
|
|
||||||
try drainEvents(Watcher, &watcher);
|
|
||||||
|
|
||||||
// File moved out of the watched tree: appears as deleted (INotify, Windows)
|
|
||||||
// or renamed (kqueue, which holds a vnode fd and sees NOTE_RENAME).
|
|
||||||
const src_gone = th.hasChange(src_path, .deleted, .file) or
|
|
||||||
th.hasChange(src_path, .renamed, .file);
|
|
||||||
try std.testing.expect(src_gone);
|
|
||||||
// No event for the destination - it is in an unwatched directory.
|
|
||||||
try std.testing.expect(!th.hasChange(dst_path, .created, .file));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn testMoveInFile(comptime Watcher: type, allocator: std.mem.Allocator) !void {
|
|
||||||
const TH = MakeTestHandler(Watcher);
|
|
||||||
|
|
||||||
const watched = try makeTempDir(allocator);
|
|
||||||
defer {
|
|
||||||
removeTempDir(watched);
|
|
||||||
allocator.free(watched);
|
|
||||||
}
|
|
||||||
const other = try makeTempDir(allocator);
|
|
||||||
defer {
|
|
||||||
removeTempDir(other);
|
|
||||||
allocator.free(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
const th = try TH.init(allocator);
|
|
||||||
defer th.deinit();
|
|
||||||
|
|
||||||
var watcher = try Watcher.init(allocator, &th.handler);
|
|
||||||
defer watcher.deinit();
|
|
||||||
try watcher.watch(watched);
|
|
||||||
|
|
||||||
const src_path = try std.fs.path.join(allocator, &.{ other, "moveme.txt" });
|
|
||||||
defer allocator.free(src_path);
|
|
||||||
const dst_path = try std.fs.path.join(allocator, &.{ watched, "moveme.txt" });
|
|
||||||
defer allocator.free(dst_path);
|
|
||||||
|
|
||||||
{
|
|
||||||
const f = try std.fs.createFileAbsolute(src_path, .{});
|
|
||||||
f.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
try std.fs.renameAbsolute(src_path, dst_path);
|
|
||||||
try drainEvents(Watcher, &watcher);
|
|
||||||
|
|
||||||
// File moved into the watched tree: appears as created.
|
|
||||||
try std.testing.expect(th.hasChange(dst_path, .created, .file));
|
|
||||||
// No event for the source - it was in an unwatched directory.
|
|
||||||
try std.testing.expect(!th.hasChange(src_path, .deleted, .file));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn testMoveInSubdir(comptime Watcher: type, allocator: std.mem.Allocator) !void {
|
|
||||||
const TH = MakeTestHandler(Watcher);
|
|
||||||
|
|
||||||
const watched = try makeTempDir(allocator);
|
|
||||||
defer {
|
|
||||||
removeTempDir(watched);
|
|
||||||
allocator.free(watched);
|
|
||||||
}
|
|
||||||
const other = try makeTempDir(allocator);
|
|
||||||
defer {
|
|
||||||
removeTempDir(other);
|
|
||||||
allocator.free(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
const th = try TH.init(allocator);
|
|
||||||
defer th.deinit();
|
|
||||||
|
|
||||||
var watcher = try Watcher.init(allocator, &th.handler);
|
|
||||||
defer watcher.deinit();
|
|
||||||
try watcher.watch(watched);
|
|
||||||
|
|
||||||
const src_sub = try std.fs.path.join(allocator, &.{ other, "sub" });
|
|
||||||
defer allocator.free(src_sub);
|
|
||||||
const dst_sub = try std.fs.path.join(allocator, &.{ watched, "sub" });
|
|
||||||
defer allocator.free(dst_sub);
|
|
||||||
const src_file = try std.fs.path.join(allocator, &.{ src_sub, "f.txt" });
|
|
||||||
defer allocator.free(src_file);
|
|
||||||
const dst_file = try std.fs.path.join(allocator, &.{ dst_sub, "f.txt" });
|
|
||||||
defer allocator.free(dst_file);
|
|
||||||
|
|
||||||
// Create subdir with a file in the unwatched root, then move it in.
|
|
||||||
try std.fs.makeDirAbsolute(src_sub);
|
|
||||||
{
|
|
||||||
const f = try std.fs.createFileAbsolute(src_file, .{});
|
|
||||||
f.close();
|
|
||||||
}
|
|
||||||
try std.fs.renameAbsolute(src_sub, dst_sub);
|
|
||||||
try drainEvents(Watcher, &watcher);
|
|
||||||
|
|
||||||
try std.testing.expect(th.hasChange(dst_sub, .created, .dir));
|
|
||||||
|
|
||||||
// Delete the file inside the moved-in subdir.
|
|
||||||
try std.fs.deleteFileAbsolute(dst_file);
|
|
||||||
try drainEvents(Watcher, &watcher);
|
|
||||||
|
|
||||||
// Object type must be .file, not .unknown - backend must have seeded
|
|
||||||
// the path_types cache when the subdir was moved in.
|
|
||||||
try std.testing.expect(th.hasChange(dst_file, .deleted, .file));
|
|
||||||
|
|
||||||
// Delete the now-empty subdir.
|
|
||||||
try std.fs.deleteDirAbsolute(dst_sub);
|
|
||||||
try drainEvents(Watcher, &watcher);
|
|
||||||
|
|
||||||
try std.testing.expect(th.hasChange(dst_sub, .deleted, .dir));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Test blocks - each runs its case across all available variants.
|
// Test blocks - each runs its case across all available variants.
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
@ -864,21 +724,3 @@ test "rename-then-modify: rename event precedes the subsequent modify event" {
|
||||||
try testRenameThenModify(nw.Create(variant), std.testing.allocator);
|
try testRenameThenModify(nw.Create(variant), std.testing.allocator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test "moving a file out of the watched tree appears as deleted or renamed" {
|
|
||||||
inline for (comptime std.enums.values(nw.Variant)) |variant| {
|
|
||||||
try testMoveOutFile(nw.Create(variant), std.testing.allocator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
test "moving a file into the watched tree appears as created" {
|
|
||||||
inline for (comptime std.enums.values(nw.Variant)) |variant| {
|
|
||||||
try testMoveInFile(nw.Create(variant), std.testing.allocator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
test "moving a subdir into the watched tree: contents can be deleted with correct types" {
|
|
||||||
inline for (comptime std.enums.values(nw.Variant)) |variant| {
|
|
||||||
try testMoveInSubdir(nw.Create(variant), std.testing.allocator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,12 @@ if (-not (Test-Path $NW)) {
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
$TESTDIR = Join-Path $env:TEMP "nightwatch_manual_$PID"
|
$TESTDIR = Join-Path $env:TEMP "nightwatch_manual_$PID"
|
||||||
$TESTDIR2 = Join-Path $env:TEMP "nightwatch_manual2_$PID"
|
$TESTDIR2 = Join-Path $env:TEMP "nightwatch_manual2_$PID"
|
||||||
$UNWATCHED = Join-Path $env:TEMP "nightwatch_unwatched_$PID"
|
New-Item -ItemType Directory -Path $TESTDIR | Out-Null
|
||||||
New-Item -ItemType Directory -Path $TESTDIR | Out-Null
|
New-Item -ItemType Directory -Path $TESTDIR2 | Out-Null
|
||||||
New-Item -ItemType Directory -Path $TESTDIR2 | Out-Null
|
|
||||||
New-Item -ItemType Directory -Path $UNWATCHED | Out-Null
|
|
||||||
|
|
||||||
Write-Host "--- watching $TESTDIR and $TESTDIR2 (unwatched: $UNWATCHED) ---"
|
Write-Host "--- watching $TESTDIR and $TESTDIR2 ---"
|
||||||
Write-Host "--- starting nightwatch (Ctrl-C to stop early) ---"
|
Write-Host "--- starting nightwatch (Ctrl-C to stop early) ---"
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
|
|
||||||
|
|
@ -106,47 +104,9 @@ Write-Host "[op] rename subA: dir1 -> dir2 (subdir across roots)"
|
||||||
Move-Item -Path "$TESTDIR\subA" -Destination "$TESTDIR2\subA2"
|
Move-Item -Path "$TESTDIR\subA" -Destination "$TESTDIR2\subA2"
|
||||||
Start-Sleep -Milliseconds 500
|
Start-Sleep -Milliseconds 500
|
||||||
|
|
||||||
Write-Host ""
|
|
||||||
Write-Host "# move in/out (one side unwatched)"
|
|
||||||
Write-Host ""
|
|
||||||
|
|
||||||
Write-Host "[op] touch outfile.txt in dir1"
|
|
||||||
New-Item -ItemType File -Path "$TESTDIR\outfile.txt" | Out-Null
|
|
||||||
Start-Sleep -Milliseconds 400
|
|
||||||
|
|
||||||
Write-Host "[op] move outfile.txt: dir1 -> unwatched (move out)"
|
|
||||||
Move-Item -Path "$TESTDIR\outfile.txt" -Destination "$UNWATCHED\outfile.txt"
|
|
||||||
Start-Sleep -Milliseconds 400
|
|
||||||
|
|
||||||
Write-Host "[op] move outfile.txt: unwatched -> dir1 (move in)"
|
|
||||||
Move-Item -Path "$UNWATCHED\outfile.txt" -Destination "$TESTDIR\outfile.txt"
|
|
||||||
Start-Sleep -Milliseconds 400
|
|
||||||
|
|
||||||
Write-Host "[op] delete outfile.txt"
|
|
||||||
Remove-Item -Path "$TESTDIR\outfile.txt"
|
|
||||||
Start-Sleep -Milliseconds 400
|
|
||||||
|
|
||||||
Write-Host "[op] mkdir unwatched\subdir with a file"
|
|
||||||
New-Item -ItemType Directory -Path "$UNWATCHED\subdir" | Out-Null
|
|
||||||
New-Item -ItemType File -Path "$UNWATCHED\subdir\inside.txt" | Out-Null
|
|
||||||
Start-Sleep -Milliseconds 400
|
|
||||||
|
|
||||||
Write-Host "[op] move unwatched\subdir -> dir1\subdir (move subdir in)"
|
|
||||||
Move-Item -Path "$UNWATCHED\subdir" -Destination "$TESTDIR\subdir"
|
|
||||||
Start-Sleep -Milliseconds 400
|
|
||||||
|
|
||||||
Write-Host "[op] delete dir1\subdir\inside.txt"
|
|
||||||
Remove-Item -Path "$TESTDIR\subdir\inside.txt"
|
|
||||||
Start-Sleep -Milliseconds 400
|
|
||||||
|
|
||||||
Write-Host "[op] rmdir dir1\subdir"
|
|
||||||
Remove-Item -Path "$TESTDIR\subdir"
|
|
||||||
Start-Sleep -Milliseconds 500
|
|
||||||
|
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
Write-Host "--- done, stopping nightwatch ---"
|
Write-Host "--- done, stopping nightwatch ---"
|
||||||
Stop-Process -Id $proc.Id -ErrorAction SilentlyContinue
|
Stop-Process -Id $proc.Id -ErrorAction SilentlyContinue
|
||||||
$proc.WaitForExit()
|
$proc.WaitForExit()
|
||||||
Remove-Item -Recurse -Force -Path $TESTDIR
|
Remove-Item -Recurse -Force -Path $TESTDIR
|
||||||
Remove-Item -Recurse -Force -Path $TESTDIR2
|
Remove-Item -Recurse -Force -Path $TESTDIR2
|
||||||
Remove-Item -Recurse -Force -Path $UNWATCHED
|
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,7 @@ fi
|
||||||
|
|
||||||
TESTDIR=$(mktemp -d)
|
TESTDIR=$(mktemp -d)
|
||||||
TESTDIR2=$(mktemp -d)
|
TESTDIR2=$(mktemp -d)
|
||||||
UNWATCHED=$(mktemp -d)
|
echo "--- watching $TESTDIR and $TESTDIR2 ---"
|
||||||
echo "--- watching $TESTDIR and $TESTDIR2 (unwatched: $UNWATCHED) ---"
|
|
||||||
echo "--- starting nightwatch (Ctrl-C to stop early) ---"
|
echo "--- starting nightwatch (Ctrl-C to stop early) ---"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
|
@ -102,45 +101,8 @@ echo "[op] rename subA: dir1 -> dir2 (subdir across roots)"
|
||||||
mv "$TESTDIR/subA" "$TESTDIR2/subA2"
|
mv "$TESTDIR/subA" "$TESTDIR2/subA2"
|
||||||
sleep 0.5
|
sleep 0.5
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "# move in/out (one side unwatched)"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "[op] touch outfile.txt in dir1"
|
|
||||||
touch "$TESTDIR/outfile.txt"
|
|
||||||
sleep 0.4
|
|
||||||
|
|
||||||
echo "[op] move outfile.txt: dir1 -> unwatched (move out)"
|
|
||||||
mv "$TESTDIR/outfile.txt" "$UNWATCHED/outfile.txt"
|
|
||||||
sleep 0.4
|
|
||||||
|
|
||||||
echo "[op] move outfile.txt: unwatched -> dir1 (move in)"
|
|
||||||
mv "$UNWATCHED/outfile.txt" "$TESTDIR/outfile.txt"
|
|
||||||
sleep 0.4
|
|
||||||
|
|
||||||
echo "[op] delete outfile.txt"
|
|
||||||
rm "$TESTDIR/outfile.txt"
|
|
||||||
sleep 0.4
|
|
||||||
|
|
||||||
echo "[op] mkdir unwatched/subdir with a file"
|
|
||||||
mkdir "$UNWATCHED/subdir"
|
|
||||||
touch "$UNWATCHED/subdir/inside.txt"
|
|
||||||
sleep 0.4
|
|
||||||
|
|
||||||
echo "[op] move unwatched/subdir -> dir1/subdir (move subdir in)"
|
|
||||||
mv "$UNWATCHED/subdir" "$TESTDIR/subdir"
|
|
||||||
sleep 0.4
|
|
||||||
|
|
||||||
echo "[op] delete dir1/subdir/inside.txt"
|
|
||||||
rm "$TESTDIR/subdir/inside.txt"
|
|
||||||
sleep 0.4
|
|
||||||
|
|
||||||
echo "[op] rmdir dir1/subdir"
|
|
||||||
rmdir "$TESTDIR/subdir"
|
|
||||||
sleep 0.5
|
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "--- done, stopping nightwatch ---"
|
echo "--- done, stopping nightwatch ---"
|
||||||
kill $NW_PID 2>/dev/null
|
kill $NW_PID 2>/dev/null
|
||||||
wait $NW_PID 2>/dev/null
|
wait $NW_PID 2>/dev/null
|
||||||
rm -rf "$TESTDIR" "$TESTDIR2" "$UNWATCHED"
|
rm -rf "$TESTDIR" "$TESTDIR2"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue