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