package pkgtools import ( "crypto/md5" "fmt" "io" "os" "path" "testing" "github.com/stretchr/testify/require" ) func lstree(p string) ([]string, error) { entries, err := os.ReadDir(p) if err != nil { return nil, err } var files []string for _, e := range entries { fPath := path.Join(p, e.Name()) if e.Type().IsDir() { tree, err := lstree(fPath) if err != nil { return nil, err } for _, f := range tree { files = append(files, path.Join(e.Name(), f)) } continue } if e.Type().IsRegular() { files = append(files, e.Name()) } } return files, nil } func shasum(path string) (string, error) { f, err := os.Open(path) if err != nil { return "", err } defer f.Close() hash := md5.New() _, err = io.Copy(hash, f) if err != nil { return "", err } return fmt.Sprintf("%x", hash.Sum(nil)), nil } func mapKeys(arg map[string]string) []string { var ret []string for k := range arg { ret = append(ret, k) } return ret } func requireDirContents( t *testing.T, expected string, actual string, msgAndArgs ...interface{}, ) { expTree := map[string]string{} files, err := lstree(expected) require.NoError(t, err) for _, file := range files { hash, err := shasum(path.Join(expected, file)) require.NoError(t, err, "calculating hash for %s", file) expTree[file] = hash } actualTree := map[string]string{} files, err = lstree(actual) require.NoError(t, err) for _, file := range files { hash, err := shasum(path.Join(actual, file)) require.NoError(t, err, "calculating hash for %s", file) actualTree[file] = hash } for k, v := range expTree { v2, ok := actualTree[k] if !ok { continue } require.Equal(t, string(v), string(v2), "file '%s' and '%s' differ", path.Join(expected, k), path.Join(actual, k), ) delete(actualTree, k) delete(expTree, k) } files = mapKeys(actualTree) require.Empty(t, files, "unexpected files left behind") files = mapKeys(expTree) require.Empty(t, files, "expected to be written") }