github.com/fawick/restic@v0.1.1-0.20171126184616-c02923fbfc79/internal/cache/file_test.go (about)

     1  package cache
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"io/ioutil"
     8  	"math/rand"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/restic/restic/internal/restic"
    13  	"github.com/restic/restic/internal/test"
    14  )
    15  
    16  func generateRandomFiles(t testing.TB, tpe restic.FileType, c *Cache) restic.IDSet {
    17  	ids := restic.NewIDSet()
    18  	for i := 0; i < rand.Intn(15)+10; i++ {
    19  		buf := test.Random(rand.Int(), 1<<19)
    20  		id := restic.Hash(buf)
    21  		h := restic.Handle{Type: tpe, Name: id.String()}
    22  
    23  		if c.Has(h) {
    24  			t.Errorf("index %v present before save", id)
    25  		}
    26  
    27  		err := c.Save(h, bytes.NewReader(buf))
    28  		if err != nil {
    29  			t.Fatal(err)
    30  		}
    31  		ids.Insert(id)
    32  	}
    33  	return ids
    34  }
    35  
    36  // randomID returns a random ID from s.
    37  func randomID(s restic.IDSet) restic.ID {
    38  	for id := range s {
    39  		return id
    40  	}
    41  	panic("set is empty")
    42  }
    43  
    44  func load(t testing.TB, c *Cache, h restic.Handle) []byte {
    45  	rd, err := c.Load(h, 0, 0)
    46  	if err != nil {
    47  		t.Fatal(err)
    48  	}
    49  
    50  	if rd == nil {
    51  		t.Fatalf("Load() returned nil reader")
    52  	}
    53  
    54  	buf, err := ioutil.ReadAll(rd)
    55  	if err != nil {
    56  		t.Fatal(err)
    57  	}
    58  
    59  	if err = rd.Close(); err != nil {
    60  		t.Fatal(err)
    61  	}
    62  
    63  	return buf
    64  }
    65  
    66  func listFiles(t testing.TB, c *Cache, tpe restic.FileType) restic.IDSet {
    67  	list, err := c.list(tpe)
    68  	if err != nil {
    69  		t.Errorf("listing failed: %v", err)
    70  	}
    71  
    72  	return list
    73  }
    74  
    75  func clearFiles(t testing.TB, c *Cache, tpe restic.FileType, valid restic.IDSet) {
    76  	if err := c.Clear(tpe, valid); err != nil {
    77  		t.Error(err)
    78  	}
    79  }
    80  
    81  func TestFiles(t *testing.T) {
    82  	seed := time.Now().Unix()
    83  	t.Logf("seed is %v", seed)
    84  	rand.Seed(seed)
    85  
    86  	c, cleanup := TestNewCache(t)
    87  	defer cleanup()
    88  
    89  	var tests = []restic.FileType{
    90  		restic.SnapshotFile,
    91  		restic.DataFile,
    92  		restic.IndexFile,
    93  	}
    94  
    95  	for _, tpe := range tests {
    96  		t.Run(fmt.Sprintf("%v", tpe), func(t *testing.T) {
    97  			ids := generateRandomFiles(t, tpe, c)
    98  			id := randomID(ids)
    99  
   100  			h := restic.Handle{Type: tpe, Name: id.String()}
   101  			id2 := restic.Hash(load(t, c, h))
   102  
   103  			if !id.Equal(id2) {
   104  				t.Errorf("wrong data returned, want %v, got %v", id.Str(), id2.Str())
   105  			}
   106  
   107  			if !c.Has(h) {
   108  				t.Errorf("cache thinks index %v isn't present", id.Str())
   109  			}
   110  
   111  			list := listFiles(t, c, tpe)
   112  			if !ids.Equals(list) {
   113  				t.Errorf("wrong list of index IDs returned, want:\n  %v\ngot:\n  %v", ids, list)
   114  			}
   115  
   116  			clearFiles(t, c, tpe, restic.NewIDSet(id))
   117  			list2 := listFiles(t, c, tpe)
   118  			ids.Delete(id)
   119  			want := restic.NewIDSet(id)
   120  			if !list2.Equals(want) {
   121  				t.Errorf("ClearIndexes removed indexes, want:\n  %v\ngot:\n  %v", list2, want)
   122  			}
   123  
   124  			clearFiles(t, c, tpe, restic.NewIDSet())
   125  			want = restic.NewIDSet()
   126  			list3 := listFiles(t, c, tpe)
   127  			if !list3.Equals(want) {
   128  				t.Errorf("ClearIndexes returned a wrong list, want:\n  %v\ngot:\n  %v", want, list3)
   129  			}
   130  		})
   131  	}
   132  }
   133  
   134  func TestFileSaveWriter(t *testing.T) {
   135  	seed := time.Now().Unix()
   136  	t.Logf("seed is %v", seed)
   137  	rand.Seed(seed)
   138  
   139  	c, cleanup := TestNewCache(t)
   140  	defer cleanup()
   141  
   142  	// save about 5 MiB of data in the cache
   143  	data := test.Random(rand.Int(), 5234142)
   144  	id := restic.ID{}
   145  	copy(id[:], data)
   146  	h := restic.Handle{
   147  		Type: restic.DataFile,
   148  		Name: id.String(),
   149  	}
   150  
   151  	wr, err := c.SaveWriter(h)
   152  	if err != nil {
   153  		t.Fatal(err)
   154  	}
   155  
   156  	n, err := io.Copy(wr, bytes.NewReader(data))
   157  	if err != nil {
   158  		t.Fatal(err)
   159  	}
   160  
   161  	if n != int64(len(data)) {
   162  		t.Fatalf("wrong number of bytes written, want %v, got %v", len(data), n)
   163  	}
   164  
   165  	if err = wr.Close(); err != nil {
   166  		t.Fatal(err)
   167  	}
   168  
   169  	rd, err := c.Load(h, 0, 0)
   170  	if err != nil {
   171  		t.Fatal(err)
   172  	}
   173  
   174  	buf, err := ioutil.ReadAll(rd)
   175  	if err != nil {
   176  		t.Fatal(err)
   177  	}
   178  
   179  	if len(buf) != len(data) {
   180  		t.Fatalf("wrong number of bytes read, want %v, got %v", len(data), len(buf))
   181  	}
   182  
   183  	if !bytes.Equal(buf, data) {
   184  		t.Fatalf("wrong data returned, want:\n  %02x\ngot:\n  %02x", data[:16], buf[:16])
   185  	}
   186  
   187  	if err = rd.Close(); err != nil {
   188  		t.Fatal(err)
   189  	}
   190  }
   191  
   192  func TestFileLoad(t *testing.T) {
   193  	seed := time.Now().Unix()
   194  	t.Logf("seed is %v", seed)
   195  	rand.Seed(seed)
   196  
   197  	c, cleanup := TestNewCache(t)
   198  	defer cleanup()
   199  
   200  	// save about 5 MiB of data in the cache
   201  	data := test.Random(rand.Int(), 5234142)
   202  	id := restic.ID{}
   203  	copy(id[:], data)
   204  	h := restic.Handle{
   205  		Type: restic.DataFile,
   206  		Name: id.String(),
   207  	}
   208  	if err := c.Save(h, bytes.NewReader(data)); err != nil {
   209  		t.Fatalf("Save() returned error: %v", err)
   210  	}
   211  
   212  	var tests = []struct {
   213  		offset int64
   214  		length int
   215  	}{
   216  		{0, 0},
   217  		{5, 0},
   218  		{32*1024 + 5, 0},
   219  		{0, 123},
   220  		{0, 64*1024 + 234},
   221  		{100, 5234142},
   222  	}
   223  
   224  	for _, test := range tests {
   225  		t.Run(fmt.Sprintf("%v/%v", test.length, test.offset), func(t *testing.T) {
   226  			rd, err := c.Load(h, test.length, test.offset)
   227  			if err != nil {
   228  				t.Fatal(err)
   229  			}
   230  
   231  			buf, err := ioutil.ReadAll(rd)
   232  			if err != nil {
   233  				t.Fatal(err)
   234  			}
   235  
   236  			if err = rd.Close(); err != nil {
   237  				t.Fatal(err)
   238  			}
   239  
   240  			o := int(test.offset)
   241  			l := test.length
   242  			if test.length == 0 {
   243  				l = len(data) - o
   244  			}
   245  
   246  			if l > len(data)-o {
   247  				l = len(data) - o
   248  			}
   249  
   250  			if len(buf) != l {
   251  				t.Fatalf("wrong number of bytes returned: want %d, got %d", l, len(buf))
   252  			}
   253  
   254  			if !bytes.Equal(buf, data[o:o+l]) {
   255  				t.Fatalf("wrong data returned, want:\n  %02x\ngot:\n  %02x", data[o:o+16], buf[:16])
   256  			}
   257  		})
   258  	}
   259  }