github.com/dennwc/btrfs@v0.0.0-20221026161108-3097362dc072/btrfs_test.go (about)

     1  package btrfs
     2  
     3  import (
     4  	"github.com/dennwc/btrfs/test"
     5  	"io"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  	"reflect"
    10  	"sort"
    11  	"testing"
    12  )
    13  
    14  const sizeDef = 256 * 1024 * 1024
    15  
    16  func TestOpen(t *testing.T) {
    17  	dir, closer := btrfstest.New(t, sizeDef)
    18  	defer closer()
    19  	fs, err := Open(dir, true)
    20  	if err != nil {
    21  		t.Fatal(err)
    22  	}
    23  	if err = fs.Close(); err != nil {
    24  		t.Fatal(err)
    25  	}
    26  }
    27  
    28  func TestIsSubvolume(t *testing.T) {
    29  	dir, closer := btrfstest.New(t, sizeDef)
    30  	defer closer()
    31  
    32  	isSubvol := func(path string, expect bool) {
    33  		ok, err := IsSubVolume(path)
    34  		if err != nil {
    35  			t.Errorf("failed to check subvolume %v: %v", path, err)
    36  			return
    37  		} else if ok != expect {
    38  			t.Errorf("unexpected result for %v", path)
    39  		}
    40  	}
    41  	mkdir := func(path string) {
    42  		path = filepath.Join(dir, path)
    43  		if err := os.MkdirAll(path, 0755); err != nil {
    44  			t.Fatalf("cannot create dir %v: %v", path, err)
    45  		}
    46  		isSubvol(path, false)
    47  	}
    48  
    49  	mksub := func(path string) {
    50  		path = filepath.Join(dir, path)
    51  		if err := CreateSubVolume(path); err != nil {
    52  			t.Fatalf("cannot create subvolume %v: %v", path, err)
    53  		}
    54  		isSubvol(path, true)
    55  	}
    56  
    57  	mksub("v1")
    58  
    59  	mkdir("v1/d2")
    60  	mksub("v1/v2")
    61  
    62  	mkdir("v1/d2/d3")
    63  	mksub("v1/d2/v3")
    64  
    65  	mkdir("v1/v2/d3")
    66  	mksub("v1/v2/v3")
    67  
    68  	mkdir("d1")
    69  
    70  	mkdir("d1/d2")
    71  	mksub("d1/v2")
    72  
    73  	mkdir("d1/d2/d3")
    74  	mksub("d1/d2/v3")
    75  
    76  	mkdir("d1/v2/d3")
    77  	mksub("d1/v2/v3")
    78  }
    79  
    80  func TestSubvolumes(t *testing.T) {
    81  	dir, closer := btrfstest.New(t, sizeDef)
    82  	defer closer()
    83  	fs, err := Open(dir, false)
    84  	if err != nil {
    85  		t.Fatal(err)
    86  	}
    87  	defer fs.Close()
    88  
    89  	mksub := func(in string, path string) {
    90  		if in != "" {
    91  			path = filepath.Join(dir, in, path)
    92  		} else {
    93  			path = filepath.Join(dir, path)
    94  		}
    95  		if err := CreateSubVolume(path); err != nil {
    96  			t.Fatalf("cannot create subvolume %v: %v", path, err)
    97  		}
    98  	}
    99  	delsub := func(path string) {
   100  		path = filepath.Join(dir, path)
   101  		if err := DeleteSubVolume(path); err != nil {
   102  			t.Fatalf("cannot delete subvolume %v: %v", path, err)
   103  		}
   104  	}
   105  	expect := func(exp []string) {
   106  		subs, err := fs.ListSubvolumes(nil)
   107  		if err != nil {
   108  			t.Fatal(err)
   109  		}
   110  		var got []string
   111  		for _, s := range subs {
   112  			if s.UUID.IsZero() {
   113  				t.Fatalf("zero uuid in %+v", s)
   114  			}
   115  			if s.Path != "" {
   116  				got = append(got, s.Path)
   117  			}
   118  		}
   119  		sort.Strings(got)
   120  		sort.Strings(exp)
   121  		if !reflect.DeepEqual(got, exp) {
   122  			t.Fatalf("list failed:\ngot: %v\nvs\nexp: %v", got, exp)
   123  		}
   124  	}
   125  
   126  	names := []string{"foo", "bar", "baz"}
   127  	for _, name := range names {
   128  		mksub("", name)
   129  	}
   130  	for _, name := range names {
   131  		mksub(names[0], name)
   132  	}
   133  	expect([]string{
   134  		"foo", "bar", "baz",
   135  		"foo/foo", "foo/bar", "foo/baz",
   136  	})
   137  	delsub("foo/bar")
   138  	expect([]string{
   139  		"foo", "bar", "baz",
   140  		"foo/foo", "foo/baz",
   141  	})
   142  
   143  	path := filepath.Join(names[0], names[2])
   144  	mksub(path, "new")
   145  	path = filepath.Join(path, "new")
   146  
   147  	id, err := getPathRootID(filepath.Join(dir, path))
   148  	if err != nil {
   149  		t.Fatal(err)
   150  	}
   151  	info, err := subvolSearchByRootID(fs.f, id, "")
   152  	if err != nil {
   153  		t.Fatal(err)
   154  	} else if info.Path != path {
   155  		t.Fatalf("wrong path returned: %v vs %v", info.Path, path)
   156  	}
   157  }
   158  
   159  func TestCompression(t *testing.T) {
   160  	dir, closer := btrfstest.New(t, sizeDef)
   161  	defer closer()
   162  	fs, err := Open(dir, true)
   163  	if err != nil {
   164  		t.Fatal(err)
   165  	}
   166  	defer fs.Close()
   167  	if err := fs.CreateSubVolume("sub"); err != nil {
   168  		t.Fatal(err)
   169  	}
   170  	path := filepath.Join(dir, "sub")
   171  
   172  	if err := SetCompression(path, LZO); err != nil {
   173  		t.Fatal(err)
   174  	}
   175  	if c, err := GetCompression(path); err != nil {
   176  		t.Fatal(err)
   177  	} else if c != LZO {
   178  		t.Fatalf("unexpected compression returned: %q", string(c))
   179  	}
   180  }
   181  
   182  func TestCloneFile(t *testing.T) {
   183  	dir, closer := btrfstest.New(t, sizeDef)
   184  	defer closer()
   185  
   186  	f1, err := os.Create(filepath.Join(dir, "1.dat"))
   187  	if err != nil {
   188  		t.Fatal(err)
   189  	}
   190  	defer f1.Close()
   191  
   192  	const data = "btrfs_test"
   193  	_, err = f1.WriteString(data)
   194  	if err != nil {
   195  		t.Fatal(err)
   196  	}
   197  
   198  	f2, err := os.Create(filepath.Join(dir, "2.dat"))
   199  	if err != nil {
   200  		t.Fatal(err)
   201  	}
   202  	defer f2.Close()
   203  
   204  	err = CloneFile(f2, f1)
   205  	if err != nil {
   206  		t.Fatal(err)
   207  	}
   208  
   209  	buf := make([]byte, len(data))
   210  	n, err := f2.Read(buf)
   211  	if err != nil && err != io.EOF {
   212  		t.Fatal(err)
   213  	}
   214  	buf = buf[:n]
   215  	if string(buf) != data {
   216  		t.Fatalf("wrong data returned: %q", string(buf))
   217  	}
   218  }
   219  
   220  func TestResize(t *testing.T) {
   221  	dir, err := ioutil.TempDir("", "btrfs_data_")
   222  	if err != nil {
   223  		t.Fatal(err)
   224  	}
   225  	defer os.RemoveAll(dir)
   226  	fname := filepath.Join(dir, "data")
   227  	if err = btrfstest.Mkfs(fname, sizeDef); err != nil {
   228  		t.Fatal(err)
   229  	}
   230  	mnt := filepath.Join(dir, "mnt")
   231  	if err = os.MkdirAll(mnt, 0755); err != nil {
   232  		t.Fatal(err)
   233  	}
   234  	if err = btrfstest.Mount(mnt, fname); err != nil {
   235  		t.Fatal(err)
   236  	}
   237  	defer btrfstest.Unmount(mnt)
   238  
   239  	fs, err := Open(mnt, false)
   240  	if err != nil {
   241  		t.Fatal(err)
   242  	}
   243  	st, err := fs.Usage()
   244  	fs.Close()
   245  	if err != nil {
   246  		t.Fatal(err)
   247  	}
   248  
   249  	if err = btrfstest.Unmount(mnt); err != nil {
   250  		t.Fatal(err)
   251  	}
   252  	var newSize int64 = sizeDef
   253  	newSize = int64(float64(newSize) * 1.1)
   254  	if err = os.Truncate(fname, newSize); err != nil {
   255  		t.Fatal(err)
   256  	}
   257  	if err = btrfstest.Mount(mnt, fname); err != nil {
   258  		t.Fatal(err)
   259  	}
   260  
   261  	fs, err = Open(mnt, false)
   262  	if err != nil {
   263  		t.Fatal(err)
   264  	}
   265  	defer fs.Close()
   266  
   267  	if err = fs.ResizeToMax(); err != nil {
   268  		t.Fatal(err)
   269  	}
   270  
   271  	st2, err := fs.Usage()
   272  	if err != nil {
   273  		t.Fatal(err)
   274  	} else if st.Total >= st2.Total {
   275  		t.Fatal("to resized:", st.Total, st2.Total)
   276  	}
   277  }