85 lines
2.2 KiB
Go
85 lines
2.2 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// fake is a machine for a test: a tree standing in for /proc and /sys, a statfs answering from a table,
|
|
// a runner answering from a table, and a wait that turns the tree into its second reading.
|
|
type fake struct {
|
|
t *testing.T
|
|
root string
|
|
later map[string]string
|
|
gone []string
|
|
space map[string]FSStat
|
|
answers map[string]string
|
|
calls []string
|
|
waited time.Duration
|
|
}
|
|
|
|
func newFake(t *testing.T) *fake {
|
|
t.Helper()
|
|
return &fake{t: t, root: t.TempDir(), later: map[string]string{}, space: map[string]FSStat{}, answers: map[string]string{}}
|
|
}
|
|
|
|
func (f *fake) machine() *Machine {
|
|
return &Machine{
|
|
Root: f.root,
|
|
Run: func(_ context.Context, name string, args ...string) (string, error) {
|
|
line := strings.TrimSpace(name + " " + strings.Join(args, " "))
|
|
f.calls = append(f.calls, line)
|
|
if out, ok := f.answers[line]; ok {
|
|
return out, nil
|
|
}
|
|
return "", fmt.Errorf("%s: not found", name)
|
|
},
|
|
Wait: func(d time.Duration) {
|
|
f.waited += d
|
|
for p, c := range f.later {
|
|
f.file(p, c)
|
|
}
|
|
for _, p := range f.gone {
|
|
os.RemoveAll(filepath.Join(f.root, p))
|
|
}
|
|
},
|
|
Statfs: func(path string) (FSStat, error) {
|
|
rel, _ := filepath.Rel(f.root, path)
|
|
s, ok := f.space[filepath.Clean("/"+filepath.ToSlash(rel))]
|
|
if !ok {
|
|
return FSStat{}, fmt.Errorf("no such filesystem")
|
|
}
|
|
return s, nil
|
|
},
|
|
}
|
|
}
|
|
|
|
// file writes a file under the fake root.
|
|
func (f *fake) file(path, content string) {
|
|
f.t.Helper()
|
|
full := filepath.Join(f.root, path)
|
|
if err := os.MkdirAll(filepath.Dir(full), 0o755); err != nil {
|
|
f.t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(full, []byte(content), 0o644); err != nil {
|
|
f.t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// dir makes a directory under the fake root: sysfs's entries that are links on a real machine are
|
|
// directories here, because the module only lists their names.
|
|
func (f *fake) dir(path string) {
|
|
f.t.Helper()
|
|
if err := os.MkdirAll(filepath.Join(f.root, path), 0o755); err != nil {
|
|
f.t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// then is a file's content at the second reading.
|
|
func (f *fake) then(path, content string) { f.later[path] = content }
|