github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/cmds/core/chmod/chmod_test.go (about) 1 // Copyright 2016-2017 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 package main 6 7 import ( 8 "bytes" 9 "io/ioutil" 10 "os" 11 "os/exec" 12 "path/filepath" 13 "testing" 14 15 "github.com/u-root/u-root/pkg/testutil" 16 ) 17 18 type fileModeTrans struct { 19 before os.FileMode 20 after os.FileMode 21 } 22 23 func run(c *exec.Cmd) (string, string, error) { 24 var o, e bytes.Buffer 25 c.Stdout, c.Stderr = &o, &e 26 err := c.Run() 27 return o.String(), e.String(), err 28 } 29 30 func TestChmodSimple(t *testing.T) { 31 // Temporary directories. 32 tempDir, err := ioutil.TempDir("", "TestChmodSimple") 33 if err != nil { 34 t.Fatalf("cannot create temporary directory: %v", err) 35 } 36 defer os.RemoveAll(tempDir) 37 38 f, err := ioutil.TempFile(tempDir, "BLAH1") 39 if err != nil { 40 t.Fatalf("cannot create temporary file: %v", err) 41 } 42 defer f.Close() 43 44 for k, v := range map[string]fileModeTrans{ 45 "0777": {before: 0000, after: 0777}, 46 "0644": {before: 0777, after: 0644}, 47 "u-rwx": {before: 0777, after: 0077}, 48 "g-rx": {before: 0777, after: 0727}, 49 "a-xr": {before: 0222, after: 0222}, 50 "a-xw": {before: 0666, after: 0444}, 51 "u-xw": {before: 0666, after: 0466}, 52 "a=": {before: 0777, after: 0000}, 53 "u=": {before: 0777, after: 0077}, 54 "u-": {before: 0777, after: 0777}, 55 "o+": {before: 0700, after: 0700}, 56 "g=rx": {before: 0777, after: 0757}, 57 "u=rx": {before: 0077, after: 0577}, 58 "o=rx": {before: 0077, after: 0075}, 59 "u=xw": {before: 0742, after: 0342}, 60 "a-rwx": {before: 0777, after: 0000}, 61 "a-rx": {before: 0777, after: 0222}, 62 "a-x": {before: 0777, after: 0666}, 63 "o+rwx": {before: 0000, after: 0007}, 64 "a+rwx": {before: 0000, after: 0777}, 65 "a+xrw": {before: 0000, after: 0777}, 66 "a+xxxxxxxx": {before: 0000, after: 0111}, 67 "o+xxxxx": {before: 0000, after: 0001}, 68 "a+rx": {before: 0000, after: 0555}, 69 "a+r": {before: 0111, after: 0555}, 70 "a=rwx": {before: 0000, after: 0777}, 71 "a=rx": {before: 0000, after: 0555}} { 72 // Set up the 'before' state 73 err := os.Chmod(f.Name(), v.before) 74 if err != nil { 75 t.Fatalf("chmod(%q) failed: %v", f.Name(), err) 76 } 77 78 // Set permissions using chmod. 79 c := testutil.Command(t, k, f.Name()) 80 err = c.Run() 81 if err != nil { 82 t.Fatalf("setting permissions failed: %v", err) 83 } 84 85 // Check that it worked. 86 checkPath(t, f.Name(), k, v) 87 } 88 } 89 90 func checkPath(t *testing.T, path string, instruction string, v fileModeTrans) { 91 info, err := os.Stat(path) 92 if err != nil { 93 t.Fatalf("stat(%q) failed: %v", path, err) 94 } 95 if got := info.Mode().Perm(); got != v.after { 96 t.Errorf("Wrong file permissions on %q: executed %s, before %0o, got %0o, want %0o", path, instruction, v.before, got, v.after) 97 } 98 } 99 100 func TestChmodRecursive(t *testing.T) { 101 // Temporary directories. 102 tempDir, err := ioutil.TempDir("", "TestChmodRecursive") 103 if err != nil { 104 t.Fatalf("cannot create temporary directory: %v", err) 105 } 106 defer os.RemoveAll(tempDir) 107 108 var targetDirectories []string 109 for _, dir := range []string{"L1_A", "L1_B", "L1_C", 110 filepath.Join("L1_A", "L2_A"), 111 filepath.Join("L1_A", "L2_B"), 112 filepath.Join("L1_A", "L2_C"), 113 filepath.Join("L1_B", "L2_A"), 114 filepath.Join("L1_B", "L2_B"), 115 filepath.Join("L1_B", "L2_C"), 116 filepath.Join("L1_C", "L2_A"), 117 filepath.Join("L1_C", "L2_B"), 118 filepath.Join("L1_C", "L2_C"), 119 } { 120 dir = filepath.Join(tempDir, dir) 121 err := os.Mkdir(dir, os.FileMode(0700)) 122 if err != nil { 123 t.Fatalf("cannot create test directory: %v", err) 124 } 125 targetDirectories = append(targetDirectories, dir) 126 } 127 128 for k, v := range map[string]fileModeTrans{ 129 "0707": {before: 0755, after: 0707}, 130 "0770": {before: 0755, after: 0770}, 131 "o-rwx": {before: 0777, after: 0770}, 132 "g-rx": {before: 0777, after: 0727}, 133 "a=rrrrrwx": {before: 0777, after: 0777}, 134 "a+w": {before: 0700, after: 0722}, 135 "g+xr": {before: 0700, after: 0750}, 136 "a=rx": {before: 0777, after: 0555}} { 137 138 // Set up the 'before' state 139 for _, dir := range targetDirectories { 140 err := os.Chmod(dir, v.before) 141 if err != nil { 142 t.Fatalf("chmod(%q) failed: %v", dir, err) 143 } 144 } 145 146 // Set permissions using chmod. 147 c := testutil.Command(t, "-R", k, tempDir) 148 err = c.Run() 149 if err != nil { 150 t.Fatalf("setting permissions failed: %v", err) 151 } 152 153 // Check that it worked. 154 for _, dir := range targetDirectories { 155 checkPath(t, dir, k, v) 156 } 157 } 158 } 159 160 func TestChmodReference(t *testing.T) { 161 // Temporary directories. 162 tempDir, err := ioutil.TempDir("", "TestChmodReference") 163 if err != nil { 164 t.Fatalf("cannot create temporary directory: %v", err) 165 } 166 defer os.RemoveAll(tempDir) 167 168 sourceFile, err := ioutil.TempFile(tempDir, "BLAH1") 169 if err != nil { 170 t.Fatalf("cannot create temporary file: %v", err) 171 } 172 defer sourceFile.Close() 173 174 targetFile, err := ioutil.TempFile(tempDir, "BLAH2") 175 if err != nil { 176 t.Fatalf("cannot create temporary file: %v", err) 177 } 178 defer targetFile.Close() 179 180 for _, perm := range []os.FileMode{0777, 0644} { 181 err = os.Chmod(sourceFile.Name(), perm) 182 if err != nil { 183 t.Fatalf("chmod(%q) failed: %v", sourceFile.Name(), err) 184 } 185 186 // Set target file permissions using chmod. 187 c := testutil.Command(t, 188 "--reference", 189 sourceFile.Name(), 190 targetFile.Name()) 191 err = c.Run() 192 if err != nil { 193 t.Fatalf("setting permissions failed: %v", err) 194 } 195 196 // Check that it worked. 197 info, err := os.Stat(targetFile.Name()) 198 if err != nil { 199 t.Fatalf("stat(%q) failed: %v", targetFile.Name(), err) 200 } 201 if got := info.Mode().Perm(); got != perm { 202 t.Fatalf("Wrong file permissions on file %q: got %0o, want %0o", 203 targetFile.Name(), got, perm) 204 } 205 } 206 } 207 208 func TestInvocationErrors(t *testing.T) { 209 tempDir, err := ioutil.TempDir("", "TestInvocationErrors") 210 if err != nil { 211 t.Fatalf("cannot create temporary directory: %v", err) 212 } 213 defer os.RemoveAll(tempDir) 214 215 f, err := ioutil.TempFile(tempDir, "BLAH1") 216 if err != nil { 217 t.Fatalf("cannot create temporary file: %v", err) 218 } 219 defer f.Close() 220 221 for _, v := range []struct { 222 args []string 223 want string 224 skipTo int 225 skipFrom int 226 }{ 227 228 { 229 args: []string{f.Name()}, 230 want: "Usage", 231 skipTo: 0, 232 skipFrom: len("Usage"), 233 }, 234 { 235 args: []string{""}, 236 want: "Usage", 237 skipTo: 0, 238 skipFrom: len("Usage"), 239 }, 240 { 241 args: []string{"01777", f.Name()}, 242 want: "Invalid octal value 1777. Value should be less than or equal to 0777.\n", 243 skipTo: 20, 244 skipFrom: -1, 245 }, 246 { 247 args: []string{"0abas", f.Name()}, 248 want: "Unable to decode mode \"0abas\". Please use an octal value or a valid mode string.\n", 249 skipTo: 20, 250 skipFrom: -1, 251 }, 252 { 253 args: []string{"0777", "blah1234"}, 254 want: "chmod blah1234: no such file or directory\n", 255 skipTo: 20, 256 skipFrom: -1, 257 }, 258 { 259 args: []string{"a=9rwx", f.Name()}, 260 want: "Unable to decode mode \"a=9rwx\". Please use an octal value or a valid mode string.\n", 261 skipTo: 20, 262 skipFrom: -1, 263 }, 264 { 265 args: []string{"+r", f.Name()}, 266 want: "Unable to decode mode \"+r\". Please use an octal value or a valid mode string.\n", 267 skipTo: 20, 268 skipFrom: -1, 269 }, 270 { 271 args: []string{"a%rwx", f.Name()}, 272 want: "Unable to decode mode \"a%rwx\". Please use an octal value or a valid mode string.\n", 273 skipTo: 20, 274 skipFrom: -1, 275 }, 276 { 277 args: []string{"b=rwx", f.Name()}, 278 want: "Unable to decode mode \"b=rwx\". Please use an octal value or a valid mode string.\n", 279 skipTo: 20, 280 skipFrom: -1, 281 }, 282 } { 283 cmd := testutil.Command(t, v.args...) 284 _, stderr, err := run(cmd) 285 if v.skipFrom == -1 { 286 v.skipFrom = len(stderr) 287 } 288 // Ignore the date and time because we're using Log.Fatalf 289 if got := stderr[v.skipTo:v.skipFrom]; got != v.want { 290 t.Errorf("Chmod for %q failed: got %q, want %q", v.args, got, v.want) 291 } 292 if err == nil { 293 t.Errorf("Chmod for %q failed: got nil want err", v.args) 294 } 295 } 296 } 297 298 func TestMain(m *testing.M) { 299 testutil.Run(m, main) 300 }