github.com/advanderveer/restic@v0.8.1-0.20171209104529-42a8c19aaea6/cmd/restic/exclude_test.go (about)

     1  package main
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path/filepath"
     7  	"testing"
     8  
     9  	"github.com/restic/restic/internal/test"
    10  )
    11  
    12  func TestRejectByPattern(t *testing.T) {
    13  	var tests = []struct {
    14  		filename string
    15  		reject   bool
    16  	}{
    17  		{filename: "/home/user/foo.go", reject: true},
    18  		{filename: "/home/user/foo.c", reject: false},
    19  		{filename: "/home/user/foobar", reject: false},
    20  		{filename: "/home/user/foobar/x", reject: true},
    21  		{filename: "/home/user/README", reject: false},
    22  		{filename: "/home/user/README.md", reject: true},
    23  	}
    24  
    25  	patterns := []string{"*.go", "README.md", "/home/user/foobar/*"}
    26  
    27  	for _, tc := range tests {
    28  		t.Run("", func(t *testing.T) {
    29  			reject := rejectByPattern(patterns)
    30  			res := reject(tc.filename, nil)
    31  			if res != tc.reject {
    32  				t.Fatalf("wrong result for filename %v: want %v, got %v",
    33  					tc.filename, tc.reject, res)
    34  			}
    35  		})
    36  	}
    37  }
    38  
    39  func TestIsExcludedByFile(t *testing.T) {
    40  	const (
    41  		tagFilename = "CACHEDIR.TAG"
    42  		header      = "Signature: 8a477f597d28d172789f06886806bc55"
    43  	)
    44  	tests := []struct {
    45  		name    string
    46  		tagFile string
    47  		content string
    48  		want    bool
    49  	}{
    50  		{"NoTagfile", "", "", false},
    51  		{"EmptyTagfile", tagFilename, "", true},
    52  		{"UnnamedTagFile", "", header, false},
    53  		{"WrongTagFile", "notatagfile", header, false},
    54  		{"IncorrectSig", tagFilename, header[1:], false},
    55  		{"ValidSig", tagFilename, header, true},
    56  		{"ValidPlusStuff", tagFilename, header + "foo", true},
    57  		{"ValidPlusNewlineAndStuff", tagFilename, header + "\nbar", true},
    58  	}
    59  	for _, tc := range tests {
    60  		t.Run(tc.name, func(t *testing.T) {
    61  			tempDir, cleanup := test.TempDir(t)
    62  			defer cleanup()
    63  
    64  			foo := filepath.Join(tempDir, "foo")
    65  			err := ioutil.WriteFile(foo, []byte("foo"), 0666)
    66  			if err != nil {
    67  				t.Fatalf("could not write file: %v", err)
    68  			}
    69  			if tc.tagFile != "" {
    70  				tagFile := filepath.Join(tempDir, tc.tagFile)
    71  				err = ioutil.WriteFile(tagFile, []byte(tc.content), 0666)
    72  				if err != nil {
    73  					t.Fatalf("could not write tagfile: %v", err)
    74  				}
    75  			}
    76  			h := header
    77  			if tc.content == "" {
    78  				h = ""
    79  			}
    80  			if got := isExcludedByFile(foo, tagFilename, h, nil); tc.want != got {
    81  				t.Fatalf("expected %v, got %v", tc.want, got)
    82  			}
    83  		})
    84  	}
    85  }
    86  
    87  // TestMultipleIsExcludedByFile is for testing that multiple instances of
    88  // the --exclude-if-present parameter (or the shortcut --exclude-caches do not
    89  // cancel each other out. It was initially written to demonstrate a bug in
    90  // rejectIfPresent.
    91  func TestMultipleIsExcludedByFile(t *testing.T) {
    92  	tempDir, cleanup := test.TempDir(t)
    93  	defer cleanup()
    94  
    95  	// Create some files in a temporary directory.
    96  	// Files in UPPERCASE will be used as exclusion triggers later on.
    97  	// We will test the inclusion later, so we add the expected value as
    98  	// a bool.
    99  	files := []struct {
   100  		path string
   101  		incl bool
   102  	}{
   103  		{"42", true},
   104  
   105  		// everything in foodir except the NOFOO tagfile
   106  		// should not be included.
   107  		{"foodir/NOFOO", true},
   108  		{"foodir/foo", false},
   109  		{"foodir/foosub/underfoo", false},
   110  
   111  		// everything in bardir except the NOBAR tagfile
   112  		// should not be included.
   113  		{"bardir/NOBAR", true},
   114  		{"bardir/bar", false},
   115  		{"bardir/barsub/underbar", false},
   116  
   117  		// everything in bazdir should be included.
   118  		{"bazdir/baz", true},
   119  		{"bazdir/bazsub/underbaz", true},
   120  	}
   121  	var errs []error
   122  	for _, f := range files {
   123  		// create directories first, then the file
   124  		p := filepath.Join(tempDir, filepath.FromSlash(f.path))
   125  		errs = append(errs, os.MkdirAll(filepath.Dir(p), 0700))
   126  		errs = append(errs, ioutil.WriteFile(p, []byte(f.path), 0600))
   127  	}
   128  	test.OKs(t, errs) // see if anything went wrong during the creation
   129  
   130  	// create two rejection functions, one that tests for the NOFOO file
   131  	// and one for the NOBAR file
   132  	fooExclude, _ := rejectIfPresent("NOFOO")
   133  	barExclude, _ := rejectIfPresent("NOBAR")
   134  
   135  	// To mock the archiver scanning walk, we create filepath.WalkFn
   136  	// that tests against the two rejection functions and stores
   137  	// the result in a map against we can test later.
   138  	m := make(map[string]bool)
   139  	walk := func(p string, fi os.FileInfo, err error) error {
   140  		if err != nil {
   141  			return err
   142  		}
   143  		excludedByFoo := fooExclude(p, fi)
   144  		excludedByBar := barExclude(p, fi)
   145  		excluded := excludedByFoo || excludedByBar
   146  		// the log message helps debugging in case the test fails
   147  		t.Logf("%q: %v || %v = %v", p, excludedByFoo, excludedByBar, excluded)
   148  		m[p] = !excluded
   149  		if excluded {
   150  			return filepath.SkipDir
   151  		}
   152  		return nil
   153  	}
   154  	// walk through the temporary file and check the error
   155  	test.OK(t, filepath.Walk(tempDir, walk))
   156  
   157  	// compare whether the walk gave the expected values for the test cases
   158  	for _, f := range files {
   159  		p := filepath.Join(tempDir, filepath.FromSlash(f.path))
   160  		if m[p] != f.incl {
   161  			t.Errorf("inclusion status of %s is wrong: want %v, got %v", f.path, f.incl, m[p])
   162  		}
   163  	}
   164  }