github.com/ratrocket/u-root@v0.0.0-20180201221235-1cf9f48ee2cf/cmds/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 -r",
   110  				files: []file{{"hi", true}},
   111  				r:     true,
   112  				err:   nilerr,
   113  				stdin: no,
   114  			},
   115  			{
   116  				name: "directory and file with -r",
   117  				files: []file{
   118  					{"hi", true},
   119  					{"go.txt", true},
   120  				},
   121  				r:     true,
   122  				err:   nilerr,
   123  				stdin: no,
   124  			},
   125  			{
   126  				name: "-f",
   127  				files: []file{
   128  					{"hi/one.doc", true}, // does not exist
   129  					{"hi/two.txt", true},
   130  					{"go.doc", true}, // does  not exist
   131  				},
   132  				f:     true,
   133  				err:   nilerr,
   134  				stdin: no,
   135  			},
   136  			{
   137  				name: "-i -f",
   138  				files: []file{
   139  					{"hi/one.txt", true}, // does not exist
   140  					{"hi/two.txt", true},
   141  					{"go.txt", true}, // does  not exist
   142  				},
   143  				f:     true,
   144  				i:     true,
   145  				err:   nilerr,
   146  				stdin: no,
   147  			},
   148  		}
   149  	)
   150  
   151  	for _, tc := range testCases {
   152  
   153  		t.Run(tc.name, func(t *testing.T) {
   154  			d, err := ioutil.TempDir(os.TempDir(), "u-root.cmds.rm")
   155  			if err != nil {
   156  				t.Fatal(err)
   157  			}
   158  			defer os.RemoveAll(d)
   159  
   160  			for _, f := range tmpFiles {
   161  				var (
   162  					err      error
   163  					filepath = path.Join(d, f.name)
   164  				)
   165  				if f.isdir {
   166  					err = os.Mkdir(filepath, f.mode)
   167  				} else {
   168  					err = ioutil.WriteFile(filepath, fbody, f.mode)
   169  				}
   170  				if err != nil {
   171  					t.Fatal(err)
   172  				}
   173  			}
   174  			testRemove(t, d, tc)
   175  		})
   176  	}
   177  }
   178  
   179  func testRemove(t *testing.T, dir string, tc rmTestCase) {
   180  	var files = make([]string, len(tc.files))
   181  	for i, f := range tc.files {
   182  		files[i] = path.Join(dir, f.name)
   183  	}
   184  
   185  	flags.v = true
   186  	flags.r = tc.r
   187  	flags.f = tc.f
   188  	flags.i = tc.i
   189  
   190  	if err := rm(tc.stdin, files); !tc.err(err) {
   191  		t.Error(err)
   192  	}
   193  
   194  	if flags.i && tc.stdin.Count() == 0 {
   195  		t.Error("Expected reading from stdin")
   196  	} else if !flags.i && tc.stdin.Count() > 0 {
   197  		t.Errorf("Did not expect reading %d times from stdin", tc.stdin.Count())
   198  	}
   199  	if tc.stdin.Overflowed() {
   200  		t.Error("Read from stdin too many times")
   201  	}
   202  
   203  	for i, f := range tc.files {
   204  		_, err := os.Stat(path.Join(dir, f.name))
   205  		if tc.files[i].delete != os.IsNotExist(err) {
   206  			t.Errorf("File %q deleted: %t, expected: %t",
   207  				f.name, os.IsNotExist(err), tc.files[i].delete)
   208  		}
   209  	}
   210  }
   211  
   212  func pathError(errno syscall.Errno) func(error) bool {
   213  	return func(err error) bool {
   214  		pe, ok := err.(*os.PathError)
   215  		if !ok {
   216  			return false
   217  		}
   218  		return pe.Err == errno
   219  	}
   220  }