Add renamed children pathNodes to target parent

Otherwise future renames may miss Renamed calls.

PiperOrigin-RevId: 254060946
This commit is contained in:
Michael Pratt 2019-06-19 13:39:57 -07:00 committed by gVisor bot
parent 29f9e4fa87
commit 9d2efaac5a
2 changed files with 59 additions and 3 deletions

View File

@ -269,14 +269,14 @@ type fileGenerator func(*Harness, string, p9.File) (*Mock, *Mock, p9.File)
func walkHelper(h *Harness, name string, dir p9.File) (parentBackend *Mock, walkedBackend *Mock, walked p9.File) {
_, parent, err := dir.Walk(nil)
if err != nil {
h.t.Fatalf("got walk err %v, want nil", err)
h.t.Fatalf("Walk(nil) got err %v, want nil", err)
}
defer parent.Close()
parentBackend = h.Pop(parent)
_, walked, err = parent.Walk([]string{name})
if err != nil {
h.t.Fatalf("got walk err %v, want nil", err)
h.t.Fatalf("Walk(%s) got err %v, want nil", name, err)
}
walkedBackend = h.Pop(walked)
@ -854,6 +854,62 @@ func TestRenameAtInvalid(t *testing.T) {
}
}
// TestRenameSecondOrder tests that indirect rename targets continue to receive
// Renamed calls after a rename of its renamed parent. i.e.,
//
// 1. Create /one/file
// 2. Create /directory
// 3. Rename /one -> /directory/one
// 4. Rename /directory -> /three/foo
// 5. file from (1) should still receive Renamed.
//
// This is a regression test for b/135219260.
func TestRenameSecondOrder(t *testing.T) {
h, c := NewHarness(t)
defer h.Finish()
rootBackend, root := newRoot(h, c)
defer root.Close()
// Walk to /one.
_, oneBackend, oneFile := walkHelper(h, "one", root)
defer oneFile.Close()
// Walk to and generate /one/file.
//
// walkHelper re-walks to oneFile, so we need the second backend,
// which will also receive Renamed calls.
oneSecondBackend, fileBackend, fileFile := walkHelper(h, "file", oneFile)
defer fileFile.Close()
// Walk to and generate /directory.
_, directoryBackend, directoryFile := walkHelper(h, "directory", root)
defer directoryFile.Close()
// Rename /one to /directory/one.
rootBackend.EXPECT().RenameAt("one", directoryBackend, "one").Return(nil)
expectRenamed(oneBackend, []string{}, directoryBackend, "one")
expectRenamed(oneSecondBackend, []string{}, directoryBackend, "one")
expectRenamed(fileBackend, []string{}, oneBackend, "file")
if err := renameAt(h, root, directoryFile, "one", "one", false); err != nil {
h.t.Fatalf("got rename err %v, want nil", err)
}
// Walk to /three.
_, threeBackend, threeFile := walkHelper(h, "three", root)
defer threeFile.Close()
// Rename /directory to /three/foo.
rootBackend.EXPECT().RenameAt("directory", threeBackend, "foo").Return(nil)
expectRenamed(directoryBackend, []string{}, threeBackend, "foo")
expectRenamed(oneBackend, []string{}, directoryBackend, "one")
expectRenamed(oneSecondBackend, []string{}, directoryBackend, "one")
expectRenamed(fileBackend, []string{}, oneBackend, "file")
if err := renameAt(h, root, threeFile, "directory", "foo", false); err != nil {
h.t.Fatalf("got rename err %v, want nil", err)
}
}
func TestReadlink(t *testing.T) {
for name := range newTypeMap(nil) {
t.Run(name, func(t *testing.T) {

View File

@ -264,7 +264,7 @@ func (f *fidRef) renameChildTo(oldName string, target *fidRef, newName string) {
})
// Replace the previous (now deleted) path node.
f.pathNode.children.Store(newName, origPathNode)
target.pathNode.children.Store(newName, origPathNode)
// Call Renamed on everything above.
notifyNameChange(origPathNode)