diff options
| author | Ophestra <cat@gensokyo.uk> | 2025-11-12 23:03:22 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2025-11-12 23:03:22 +0900 |
| commit | b5630f6883c874d458d9ae3c666cfb7ae5e3121d (patch) | |
| tree | e2c488165211b1f68b9eaef8469d92a81ba37f43 /test/internal/sandbox/fs.go | |
| parent | 17ffdb2dcf3bb5c8edf277a017cecd8e71a2e26b (diff) | |
test: move package sandbox internal
This should never be used outside vm tests.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'test/internal/sandbox/fs.go')
| -rw-r--r-- | test/internal/sandbox/fs.go | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/test/internal/sandbox/fs.go b/test/internal/sandbox/fs.go new file mode 100644 index 00000000..36d6c6d3 --- /dev/null +++ b/test/internal/sandbox/fs.go @@ -0,0 +1,102 @@ +//go:build testtool + +package sandbox + +import ( + "errors" + "fmt" + "io/fs" + "path" + "strings" +) + +var ( + ErrFSBadLength = errors.New("bad dir length") + ErrFSBadData = errors.New("data differs") + ErrFSBadMode = errors.New("mode differs") + ErrFSInvalidEnt = errors.New("invalid entry condition") +) + +type FS struct { + Mode fs.FileMode `json:"mode"` + Dir map[string]*FS `json:"dir"` + Data *string `json:"data"` +} + +func printDir(prefix string, dir []fs.DirEntry) { + names := make([]string, len(dir)) + for i, ent := range dir { + name := ent.Name() + if ent.IsDir() { + name += "/" + } + names[i] = fmt.Sprintf("%q", name) + } + printf("[FAIL] d %s: %s", prefix, strings.Join(names, " ")) +} + +func (s *FS) Compare(prefix string, e fs.FS) error { + if s.Data != nil { + if s.Dir != nil { + panic("invalid state") + } + panic("invalid compare call") + } + + if s.Dir == nil { + printf("[ OK ] s %s", prefix) + return nil + } + + var dir []fs.DirEntry + if d, err := fs.ReadDir(e, prefix); err != nil { + return err + } else if len(d) != len(s.Dir) { + printDir(prefix, d) + return ErrFSBadLength + } else { + dir = d + } + + for _, got := range dir { + name := got.Name() + + if want, ok := s.Dir[name]; !ok { + printDir(prefix, dir) + return fs.ErrNotExist + } else if want.Dir != nil && !got.IsDir() { + printDir(prefix, dir) + return ErrFSInvalidEnt + } else { + name = path.Join(prefix, name) + + if fi, err := got.Info(); err != nil { + return err + } else if fi.Mode() != want.Mode { + printf("[FAIL] m %s: %x, want %x", + name, uint32(fi.Mode()), uint32(want.Mode)) + return ErrFSBadMode + } + + if want.Data != nil { + if want.Dir != nil { + panic("invalid state") + } + if v, err := fs.ReadFile(e, name); err != nil { + return err + } else if string(v) != *want.Data { + printf("[FAIL] f %s", name) + printf("got: %s", v) + printf("want: %s", *want.Data) + return ErrFSBadData + } + printf("[ OK ] f %s", name) + } else if err := want.Compare(name, e); err != nil { + return err + } + } + } + printf("[ OK ] d %s", prefix) + + return nil +} |
