package files import ( "context" "errors" "os" "path/filepath" "testing" "time" ) func TestInstanceDataRemoverDeletesExistingDirectory(t *testing.T) { root := t.TempDir() target := filepath.Join(root, "profile") if err := os.MkdirAll(filepath.Join(target, "Default"), 0o700); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(target, "Local State"), []byte("state"), 0o600); err != nil { t.Fatal(err) } remover := NewInstanceDataRemover() if err := remover.RemoveInstanceData(context.Background(), target); err != nil { t.Fatal(err) } if _, err := os.Lstat(target); !errors.Is(err, os.ErrNotExist) { t.Fatalf("target still exists or could not be inspected: %v", err) } } func TestInstanceDataRemoverRejectsUnsafePathsBeforeDeletion(t *testing.T) { called := false remover := newInstanceDataRemover(func(string) (os.FileInfo, error) { return nil, os.ErrNotExist }, func(string) error { called = true return nil }) for _, path := range []string{"", "relative-profile", filepath.VolumeName(t.TempDir()) + string(filepath.Separator)} { if err := remover.RemoveInstanceData(context.Background(), path); !errors.Is(err, ErrUnsafeInstanceDataDirectory) { t.Fatalf("path %q error = %v", path, err) } } if called { t.Fatal("unsafe path reached removal") } } func TestInstanceDataRemoverRejectsFilesAndLinks(t *testing.T) { file := filepath.Join(t.TempDir(), "not-a-directory") if err := os.WriteFile(file, []byte("data"), 0o600); err != nil { t.Fatal(err) } if err := NewInstanceDataRemover().RemoveInstanceData(context.Background(), file); !errors.Is(err, ErrInstanceDataNotDirectory) { t.Fatalf("file error = %v", err) } linkInfo := fakeFileInfo{mode: os.ModeSymlink | 0o777} remover := newInstanceDataRemover(func(string) (os.FileInfo, error) { return linkInfo, nil }, func(string) error { t.Fatal("link reached removal") return nil }) if err := remover.RemoveInstanceData(context.Background(), t.TempDir()); !errors.Is(err, ErrUnsafeInstanceDataDirectory) { t.Fatalf("link error = %v", err) } } func TestInstanceDataRemoverHonorsCanceledContext(t *testing.T) { target := filepath.Join(t.TempDir(), "profile") if err := os.Mkdir(target, 0o700); err != nil { t.Fatal(err) } ctx, cancel := context.WithCancel(context.Background()) cancel() if err := NewInstanceDataRemover().RemoveInstanceData(ctx, target); !errors.Is(err, context.Canceled) { t.Fatalf("error = %v", err) } if _, err := os.Lstat(target); err != nil { t.Fatalf("canceled deletion changed target: %v", err) } } type fakeFileInfo struct { mode os.FileMode sys any } func (f fakeFileInfo) Name() string { return "fake" } func (f fakeFileInfo) Size() int64 { return 0 } func (f fakeFileInfo) Mode() os.FileMode { return f.mode } func (f fakeFileInfo) ModTime() time.Time { return time.Time{} } func (f fakeFileInfo) IsDir() bool { return f.mode.IsDir() } func (f fakeFileInfo) Sys() any { return f.sys }