package utils
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"reflect"
"regexp"
"sort"
"testing"
)
func MustMkdirAll(t *testing.T, path string, perm os.FileMode) {
t.Helper()
if err := os.MkdirAll(path, perm); err != nil {
t.Fatalf("Failed to create directory %s: %v", path, err)
}
}
func MustSymlink(t *testing.T, target string, path string) {
t.Helper()
if err := os.Symlink(target, path); err != nil {
t.Fatalf("Failed to create symlink %s: %v", path, err)
}
}
func MustWriteFile(t *testing.T, path string, perm os.FileMode, contents string) {
t.Helper()
if err := ioutil.WriteFile(path, []byte(contents), perm); err != nil {
t.Fatalf("Failed to create file %s: %v", path, err)
}
}
func RequireRoot(t *testing.T, skipReason string) *UnixUser {
t.Helper()
if os.Getuid() != 0 {
t.Skipf(skipReason)
}
root, err := LookupUID(os.Getuid())
if err != nil {
t.Fatalf("Failed to get details about root user: %v", err)
}
t.Logf("Running test as: %v", root)
return root
}
func DirEquals(path1 string, path2 string) error {
names := make([]map[string]os.FileMode, 2)
for i, path := range []string{path1, path2} {
dirents, err := ioutil.ReadDir(path)
if err != nil {
return fmt.Errorf("failed to read contents of directory %s: %v", path, err)
}
names[i] = make(map[string]os.FileMode, len(dirents))
for _, dirent := range dirents {
names[i][dirent.Name()] = dirent.Mode()
}
}
if !reflect.DeepEqual(names[0], names[1]) {
return fmt.Errorf("contents of directory %s do not match %s; got %v, want %v", path1, path2, names[1], names[0])
}
return nil
}
func DirEntryNamesEqual(path string, wantNames []string) error {
dirents, err := ioutil.ReadDir(path)
if err != nil {
return fmt.Errorf("failed to read contents of directory %s: %v", path, err)
}
var names []string
for _, dirent := range dirents {
names = append(names, dirent.Name())
}
sort.Strings(names)
if !reflect.DeepEqual(names, wantNames) {
return fmt.Errorf("got entries %v for directory %s; want %v", names, path, wantNames)
}
return nil
}
func FileEquals(path string, wantContents string) error {
contents, err := ioutil.ReadFile(path)
if err != nil {
return err
}
if string(contents) != wantContents {
return fmt.Errorf("file %s doesn't match expected contents: got '%s', want '%s'", path, contents, wantContents)
}
return nil
}
func runAs(user *UnixUser, arg ...string) error {
cmd := exec.Command(arg[0], arg[1:]...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
SetCredential(cmd, user)
return cmd.Run()
}
func runAsSilent(user *UnixUser, arg ...string) error {
cmd := exec.Command(arg[0], arg[1:]...)
SetCredential(cmd, user)
return cmd.Run()
}
func CreateFileAsUser(path string, user *UnixUser) error {
return runAs(user, "touch", path)
}
func MkdirAsUser(path string, user *UnixUser) error {
return runAs(user, "mkdir", path)
}
func MkfifoAsUser(path string, user *UnixUser) error {
return runAs(user, "mkfifo", path)
}
func MoveAsUser(source string, target string, user *UnixUser) error {
return runAs(user, "mv", source, target)
}
func SymlinkAsUser(target string, path string, user *UnixUser) error {
return runAs(user, "ln", "-s", target, path)
}
func FileExistsAsUser(path string, user *UnixUser) error {
return runAsSilent(user, "cat", path)
}
func MatchesRegexp(pattern string, s string) bool {
match, err := regexp.MatchString(pattern, s)
if err != nil {
panic(fmt.Sprintf("invalid regexp %s: %v; this is a bug in the test code", pattern, err))
}
return match
}