github.com/hugelgupf/u-root@v0.0.0-20191023214958-4807c632154c/cmds/core/rm/rm_test.go (about)

     1  // Copyright 2012 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //  created by Manoel Vilela (manoel_vilela@engineer.com)
     6  
     7  package main
     8  
     9  import (
    10  	"io/ioutil"
    11  	"os"
    12  	"path"
    13  	"syscall"
    14  	"testing"
    15  
    16  	"github.com/u-root/u-root/pkg/testutil"
    17  )
    18  
    19  type file struct {
    20  	name   string
    21  	delete bool
    22  }
    23  
    24  type rmTestCase struct {
    25  	name  string
    26  	files []file
    27  	i     bool
    28  	r     bool
    29  	f     bool
    30  	err   func(error) bool
    31  	stdin *testutil.FakeStdin
    32  }
    33  
    34  func TestRemove(t *testing.T) {
    35  	var (
    36  		no       = testutil.NewFakeStdin("no")
    37  		fbody    = []byte("Go is cool!")
    38  		tmpFiles = []struct {
    39  			name  string
    40  			mode  os.FileMode
    41  			isdir bool
    42  		}{
    43  
    44  			{
    45  				name:  "hi",
    46  				mode:  0755,
    47  				isdir: true,
    48  			},
    49  			{
    50  				name: "hi/one.txt",
    51  				mode: 0666,
    52  			},
    53  			{
    54  				name: "hi/two.txt",
    55  				mode: 0777,
    56  			},
    57  			{
    58  				name: "go.txt",
    59  				mode: 0555,
    60  			},
    61  		}
    62  		nilerr    = func(err error) bool { return err == nil }
    63  		testCases = []rmTestCase{
    64  			{
    65  				name: "no flags",
    66  				files: []file{
    67  					{"hi/one.txt", true},
    68  					{"hi/two.txt", true},
    69  					{"go.txt", true},
    70  				},
    71  				err:   nilerr,
    72  				stdin: no,
    73  			},
    74  			{
    75  				name: "-i",
    76  				files: []file{
    77  					{"hi/one.txt", true},
    78  					{"hi/two.txt", false},
    79  					{"go.txt", true},
    80  				},
    81  				i:     true,
    82  				err:   nilerr,
    83  				stdin: testutil.NewFakeStdin("y", "no", "yes"),
    84  			},
    85  			{
    86  				name: "nonexistent with no flags",
    87  				files: []file{
    88  					{"hi/one.txt", true},
    89  					{"hi/two.doc", true}, // does not exist
    90  					{"go.txt", false},
    91  				},
    92  				err:   os.IsNotExist,
    93  				stdin: no,
    94  			},
    95  			{
    96  				name:  "directory with no flags",
    97  				files: []file{{"hi", false}},
    98  				err:   pathError(syscall.ENOTEMPTY),
    99  				stdin: no,
   100  			},
   101  			{
   102  				name:  "directory with -f",
   103  				files: []file{{"hi", false}},
   104  				f:     true,
   105  				err:   pathError(syscall.ENOTEMPTY),
   106  				stdin: no,
   107  			},
   108  			{
   109  				name:  "directory with -rf",
   110  				files: []file{{"hi", true}},
   111  				r:     true,
   112  				f:     true,
   113  				err:   nilerr,
   114  				stdin: no,
   115  			},
   116  			{
   117  				name:  "directory with -r",
   118  				files: []file{{"hi", true}},
   119  				r:     true,
   120  				err:   nilerr,
   121  				stdin: no,
   122  			},
   123  			{
   124  				name: "directory and file with -r",
   125  				files: []file{
   126  					{"hi", true},
   127  					{"go.txt", true},
   128  				},
   129  				r:     true,
   130  				err:   nilerr,
   131  				stdin: no,
   132  			},
   133  			{
   134  				name: "-f",
   135  				files: []file{
   136  					{"hi/one.doc", true}, // does not exist
   137  					{"hi/two.txt", true},
   138  					{"go.doc", true}, // does  not exist
   139  				},
   140  				f:     true,
   141  				err:   nilerr,
   142  				stdin: no,
   143  			},
   144  			{
   145  				name: "-i -f",
   146  				files: []file{
   147  					{"hi/one.txt", true}, // does not exist
   148  					{"hi/two.txt", true},
   149  					{"go.txt", true}, // does  not exist
   150  				},
   151  				f:     true,
   152  				i:     true,
   153  				err:   nilerr,
   154  				stdin: no,
   155  			},
   156  		}
   157  	)
   158  
   159  	for _, tc := range testCases {
   160  
   161  		t.Run(tc.name, func(t *testing.T) {
   162  			d, err := ioutil.TempDir(os.TempDir(), "u-root.cmds.rm")
   163  			if err != nil {
   164  				t.Fatal(err)
   165  			}
   166  			defer os.RemoveAll(d)
   167  
   168  			for _, f := range tmpFiles {
   169  				var (
   170  					err      error
   171  					filepath = path.Join(d, f.name)
   172  				)
   173  				if f.isdir {
   174  					err = os.Mkdir(filepath, f.mode)
   175  				} else {
   176  					err = ioutil.WriteFile(filepath, fbody, f.mode)
   177  				}
   178  				if err != nil {
   179  					t.Fatal(err)
   180  				}
   181  			}
   182  			testRemove(t, d, tc)
   183  		})
   184  	}
   185  }
   186  
   187  func testRemove(t *testing.T, dir string, tc rmTestCase) {
   188  	var files = make([]string, len(tc.files))
   189  	for i, f := range tc.files {
   190  		files[i] = path.Join(dir, f.name)
   191  	}
   192  
   193  	flags.v = true
   194  	flags.r = tc.r
   195  	flags.f = tc.f
   196  	flags.i = tc.i
   197  
   198  	if err := rm(tc.stdin, files); !tc.err(err) {
   199  		t.Error(err)
   200  	}
   201  
   202  	if flags.i && tc.stdin.Count() == 0 {
   203  		t.Error("Expected reading from stdin")
   204  	} else if !flags.i && tc.stdin.Count() > 0 {
   205  		t.Errorf("Did not expect reading %d times from stdin", tc.stdin.Count())
   206  	}
   207  	if tc.stdin.Overflowed() {
   208  		t.Error("Read from stdin too many times")
   209  	}
   210  
   211  	for i, f := range tc.files {
   212  		_, err := os.Stat(path.Join(dir, f.name))
   213  		if tc.files[i].delete != os.IsNotExist(err) {
   214  			t.Errorf("File %q deleted: %t, expected: %t",
   215  				f.name, os.IsNotExist(err), tc.files[i].delete)
   216  		}
   217  	}
   218  }
   219  
   220  func pathError(errno syscall.Errno) func(error) bool {
   221  	return func(err error) bool {
   222  		pe, ok := err.(*os.PathError)
   223  		if !ok {
   224  			return false
   225  		}
   226  		return pe.Err == errno
   227  	}
   228  }