github.com/rkt/rkt@v1.30.1-0.20200224141603-171c416fac02/pkg/fileutil/fileutil_test.go (about) 1 // Copyright 2015 The rkt Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package fileutil 16 17 import ( 18 "io/ioutil" 19 "os" 20 "path/filepath" 21 "testing" 22 23 "github.com/rkt/rkt/pkg/user" 24 ) 25 26 const tstprefix = "fileutil-test" 27 28 func touch(t *testing.T, name string) { 29 f, err := os.Create(name) 30 if err != nil { 31 t.Fatal(err) 32 } 33 if err := f.Close(); err != nil { 34 t.Fatal(err) 35 } 36 } 37 38 type tree struct { 39 path string 40 dir bool 41 } 42 43 func createTree(t *testing.T, dir string, tr []tree) { 44 for _, f := range tr { 45 if f.dir { 46 if err := os.MkdirAll(filepath.Join(dir, f.path), 0755); err != nil { 47 t.Fatal(err) 48 } 49 } else { 50 touch(t, filepath.Join(dir, f.path)) 51 } 52 } 53 } 54 55 func checkTree(t *testing.T, dir string, tr []tree) { 56 for _, f := range tr { 57 if _, err := os.Stat(filepath.Join(dir, f.path)); err != nil { 58 t.Fatal(err) 59 } 60 } 61 } 62 63 func TestCopyTree(t *testing.T) { 64 td, err := ioutil.TempDir("", tstprefix) 65 if err != nil { 66 t.Fatal(err) 67 } 68 defer os.RemoveAll(td) 69 70 src := filepath.Join(td, "src") 71 dst := filepath.Join(td, "dst") 72 if err := os.MkdirAll(filepath.Join(td, "src"), 0755); err != nil { 73 panic(err) 74 } 75 76 tr := []tree{ 77 { 78 path: "dir1", 79 dir: true, 80 }, 81 { 82 path: "dir2", 83 dir: true, 84 }, 85 { 86 path: "dir1/foo", 87 dir: false, 88 }, 89 { 90 path: "dir1/bar", 91 dir: false, 92 }, 93 } 94 95 createTree(t, src, tr) 96 97 // absolute paths 98 if err := CopyTree(src, dst, user.NewBlankUidRange()); err != nil { 99 t.Fatal(err) 100 } 101 checkTree(t, dst, tr) 102 103 // relative paths 104 if err := os.Chdir(td); err != nil { 105 t.Fatal(err) 106 } 107 108 dst = "dst-rel1" 109 if err := CopyTree("././src/", dst, user.NewBlankUidRange()); err != nil { 110 t.Fatal(err) 111 } 112 checkTree(t, dst, tr) 113 114 dst = "./dst-rel2" 115 if err := CopyTree("./src", dst, user.NewBlankUidRange()); err != nil { 116 t.Fatal(err) 117 } 118 checkTree(t, dst, tr) 119 } 120 121 func TestFileIsExecutable(t *testing.T) { 122 tempDir, err := ioutil.TempDir("", tstprefix) 123 if err != nil { 124 t.Fatal(err) 125 } 126 defer os.RemoveAll(tempDir) 127 128 testCases := []struct { 129 Permission os.FileMode 130 IsExecutable bool 131 }{ 132 {0200, false}, 133 {0400, false}, 134 {0600, false}, 135 {0100, true}, 136 {0300, true}, 137 {0500, true}, 138 {0700, true}, 139 140 {0002, false}, 141 {0004, false}, 142 {0006, false}, 143 {0001, true}, 144 {0003, true}, 145 {0005, true}, 146 {0007, true}, 147 148 {0020, false}, 149 {0040, false}, 150 {0060, false}, 151 {0010, true}, 152 {0030, true}, 153 {0050, true}, 154 {0070, true}, 155 156 {0000, false}, 157 {0222, false}, 158 {0444, false}, 159 {0666, false}, 160 161 {0146, true}, 162 {0661, true}, 163 } 164 165 for _, tc := range testCases { 166 f, err := ioutil.TempFile(tempDir, "") 167 if err != nil { 168 panic(err) 169 } 170 171 if err := f.Chmod(tc.Permission); err != nil { 172 panic(err) 173 } 174 175 if err := f.Close(); err != nil { 176 panic(err) 177 } 178 179 path := f.Name() 180 181 if tc.IsExecutable != IsExecutable(path) { 182 t.Errorf("fileutil.IsExecutable(%q) with permissions %q, expected %v", path, tc.Permission, tc.IsExecutable) 183 } 184 } 185 } 186 187 func TestDeviceInfo(t *testing.T) { 188 // First, test the main call 189 { 190 kind, major, minor, err := GetDeviceInfo("/dev/null") 191 if kind != 'c' || major != 1 || minor != 3 || err != nil { 192 t.Errorf("GetDeviceInfo(/dev/null) wrong result") 193 } 194 } 195 196 { 197 _, _, _, err := GetDeviceInfo("/usr") 198 if err == nil { 199 t.Errorf("GetDeviceInfo(/usr) should return err") 200 } 201 } 202 203 // Then test the logic more specifically 204 for i, tt := range []struct { 205 mode os.FileMode 206 rdev uint64 207 kind rune 208 major uint64 209 minor uint64 210 }{ 211 // /dev/null 212 { 213 69206454, 214 259, 215 'c', 216 1, 217 3, 218 }, 219 // /dev/sda1 220 { 221 67109296, 222 2049, 223 'b', 224 8, 225 1, 226 }, 227 // /dev/pts/3 228 { 229 69206416, 230 34819, 231 'c', 232 136, 233 3, 234 }, 235 // /dev/dm-0 236 { 237 67109296, 238 64768, 239 'b', 240 253, 241 0, 242 }, 243 } { 244 kind, major, minor, err := getDeviceInfo(tt.mode, tt.rdev) 245 if err != nil { 246 t.Errorf("getDeviceInfo %d not as expected, got err %s", i, err) 247 } 248 // don't care about result when err 249 if err != nil { 250 continue 251 } 252 253 if tt.kind != kind { 254 t.Errorf("getDeviceInfo %d kind expected %v got %v", i, tt.kind, kind) 255 } 256 if tt.major != major { 257 t.Errorf("getDeviceInfo %d major expected %v got %v", i, tt.major, major) 258 } 259 if tt.minor != minor { 260 t.Errorf("getDeviceInfo %d minor expected %v got %v", i, tt.minor, minor) 261 } 262 } 263 }