1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
package btrfstest
import (
"bytes"
"errors"
"io/ioutil"
"log"
"os"
"os/exec"
"strings"
"testing"
"time"
)
func run(name string, args ...string) error {
buf := bytes.NewBuffer(nil)
cmd := exec.Command(name, args...)
cmd.Stdout = buf
cmd.Stderr = buf
err := cmd.Run()
if err == nil {
return nil
} else if buf.Len() == 0 {
return err
}
return errors.New("error: " + strings.TrimSpace(string(buf.Bytes())))
}
func Mkfs(file string, size int64) error {
f, err := os.Create(file)
if err != nil {
return err
}
if err = f.Truncate(size); err != nil {
f.Close()
return err
}
if err = f.Close(); err != nil {
return err
}
if err = run("mkfs.btrfs", file); err != nil {
os.Remove(file)
return err
}
return err
}
func Mount(mount string, file string) error {
if err := run("mount", file, mount); err != nil {
return err
}
return nil
}
func Unmount(mount string) error {
for i := 0; i < 5; i++ {
if err := run("umount", mount); err == nil {
break
} else {
if strings.Contains(err.Error(), "busy") {
time.Sleep(time.Second)
} else {
break
}
}
}
return nil
}
func New(t testing.TB, size int64) (string, func()) {
f, err := ioutil.TempFile("", "btrfs_vol")
if err != nil {
t.Fatal(err)
}
name := f.Name()
f.Close()
rm := func() {
os.Remove(name)
}
if err = Mkfs(name, size); err != nil {
rm()
}
mount, err := ioutil.TempDir("", "btrfs_mount")
if err != nil {
rm()
t.Fatal(err)
}
if err = Mount(mount, name); err != nil {
rm()
os.RemoveAll(mount)
if txt := err.Error(); strings.Contains(txt, "permission denied") ||
strings.Contains(txt, "only root") {
t.Skip(err)
} else {
t.Fatal(err)
}
}
done := false
return mount, func() {
if done {
return
}
if err := Unmount(mount); err != nil {
log.Println("umount failed:", err)
}
if err := os.Remove(mount); err != nil {
log.Println("cleanup failed:", err)
}
rm()
done = true
}
}
|