Drop watches of directories that leave the tree
A directory moved out of a watched tree kept its kernel watches, so later changes inside it were reported under the old path. Its watches and those of its subdirectories are now removed on `MOVED_FROM`. Watches the kernel reports as `IGNORED` are forgotten as well, so a reused descriptor number cannot map to a stale path.
This commit is contained in:
@@ -58,4 +58,29 @@ struct RecursiveEventTests {
|
||||
#expect(createEvent != nil, "Expected CREATE for '\(filepath)', got: \(events)")
|
||||
}
|
||||
}
|
||||
|
||||
@Test func stopsReportingForDirectoriesMovedOutOfTheWatchedTree() async throws {
|
||||
try await withTempDir { dir in
|
||||
let root = "\(dir)/Root"
|
||||
let outside = "\(dir)/Outside"
|
||||
let movedSource = "\(root)/Moved"
|
||||
let movedDestination = "\(outside)/Moved"
|
||||
let filename = "created-after-move.txt"
|
||||
try FileManager.default.createDirectory(atPath: movedSource, withIntermediateDirectories: true)
|
||||
try FileManager.default.createDirectory(atPath: outside, withIntermediateDirectories: true)
|
||||
|
||||
let events = try await getEventsForTrigger(
|
||||
in: root,
|
||||
mask: [.create, .movedFrom],
|
||||
recursive: .withAutomaticSubtreeWatching
|
||||
) { _ in
|
||||
try FileManager.default.moveItem(atPath: movedSource, toPath: movedDestination)
|
||||
try await Task.sleep(for: .milliseconds(400))
|
||||
try createFile(at: "\(movedDestination)/\(filename)", contents: "hello")
|
||||
}
|
||||
|
||||
let staleEvent = events.first { $0.mask.contains(.create) && $0.path.lastComponent?.string == filename }
|
||||
#expect(staleEvent == nil, "Did not expect CREATE for '\(filename)' after its directory left the tree, got: \(events)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user