| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2017 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. |
| 4 |
| 5 package main |
| 6 |
| 7 import ( |
| 8 "errors" |
| 9 "os" |
| 10 "reflect" |
| 11 "testing" |
| 12 ) |
| 13 |
| 14 // basicFileInfo implements some of os.FileInfo, and panics if unexpected parts |
| 15 // of that interface are called. |
| 16 type basicFileInfo struct { |
| 17 size int64 |
| 18 mode os.FileMode |
| 19 isDir bool |
| 20 |
| 21 os.FileInfo |
| 22 } |
| 23 |
| 24 func (bfi basicFileInfo) Size() int64 { return bfi.size } |
| 25 func (bfi basicFileInfo) Mode() os.FileMode { return bfi.mode } |
| 26 func (bfi basicFileInfo) IsDir() bool { return bfi.isDir } |
| 27 |
| 28 type file struct { |
| 29 path string |
| 30 bfi basicFileInfo |
| 31 } |
| 32 |
| 33 func symlink(path string, size int64) file { |
| 34 return file{ |
| 35 path: path, |
| 36 bfi: basicFileInfo{ |
| 37 size: size, |
| 38 mode: os.ModeSymlink, |
| 39 isDir: false, |
| 40 }, |
| 41 } |
| 42 } |
| 43 |
| 44 func regularFile(path string, size int64) file { |
| 45 return file{ |
| 46 path: path, |
| 47 bfi: basicFileInfo{ |
| 48 size: size, |
| 49 mode: 0, |
| 50 isDir: false, |
| 51 }, |
| 52 } |
| 53 } |
| 54 |
| 55 func directory(path string) file { |
| 56 return file{ |
| 57 path: path, |
| 58 bfi: basicFileInfo{ |
| 59 size: 0, |
| 60 mode: os.ModeDir, |
| 61 isDir: true, |
| 62 }, |
| 63 } |
| 64 } |
| 65 |
| 66 var errBang = errors.New("bang") |
| 67 |
| 68 func TestWalkFn(t *testing.T) { |
| 69 type testCase struct { |
| 70 name string |
| 71 files []file |
| 72 walkFnErr error |
| 73 want partitionedDeps |
| 74 } |
| 75 |
| 76 testCases := []testCase{ |
| 77 { |
| 78 name: "partitions files", |
| 79 files: []file{ |
| 80 symlink("/rootDir/patha", 1e3), |
| 81 regularFile("/rootDir/pathb", 10e3), |
| 82 regularFile("/rootDir/pathc", 100e3), |
| 83 }, |
| 84 want: partitionedDeps{ |
| 85 links: itemGroup{ |
| 86 items: []*Item{ |
| 87 { |
| 88 Path: "/rootDir/patha
", |
| 89 RelPath: "patha", |
| 90 Mode: os.ModeSymlink, |
| 91 Size: 1e3, |
| 92 }, |
| 93 }, |
| 94 totalSize: 1e3, |
| 95 }, |
| 96 filesToArchive: itemGroup{ |
| 97 items: []*Item{ |
| 98 { |
| 99 Path: "/rootDir/pathb
", |
| 100 RelPath: "pathb", |
| 101 Mode: 0, |
| 102 Size: 10e3, |
| 103 }, |
| 104 }, |
| 105 totalSize: 10e3, |
| 106 }, |
| 107 indivFiles: itemGroup{ |
| 108 items: []*Item{ |
| 109 { |
| 110 Path: "/rootDir/pathc
", |
| 111 RelPath: "pathc", |
| 112 Mode: 0, |
| 113 Size: 100e3, |
| 114 }, |
| 115 }, |
| 116 totalSize: 100e3, |
| 117 }, |
| 118 }, |
| 119 }, |
| 120 { |
| 121 name: "handles zero-size files", |
| 122 files: []file{ |
| 123 symlink("/rootDir/patha", 0), |
| 124 regularFile("/rootDir/pathb", 0), |
| 125 }, |
| 126 want: partitionedDeps{ |
| 127 links: itemGroup{ |
| 128 items: []*Item{ |
| 129 { |
| 130 Path: "/rootDir/patha
", |
| 131 RelPath: "patha", |
| 132 Mode: os.ModeSymlink, |
| 133 Size: 0, |
| 134 }, |
| 135 }, |
| 136 totalSize: 0, |
| 137 }, |
| 138 filesToArchive: itemGroup{ |
| 139 items: []*Item{ |
| 140 { |
| 141 Path: "/rootDir/pathb
", |
| 142 RelPath: "pathb", |
| 143 Mode: 0, |
| 144 Size: 0, |
| 145 }, |
| 146 }, |
| 147 totalSize: 0, |
| 148 }, |
| 149 }, |
| 150 }, |
| 151 { |
| 152 name: "aggregates link sizes", |
| 153 files: []file{ |
| 154 symlink("/rootDir/patha", 1), |
| 155 symlink("/rootDir/pathb", 1<<1), |
| 156 }, |
| 157 want: partitionedDeps{ |
| 158 links: itemGroup{ |
| 159 items: []*Item{ |
| 160 { |
| 161 Path: "/rootDir/patha
", |
| 162 RelPath: "patha", |
| 163 Mode: os.ModeSymlink, |
| 164 Size: 1, |
| 165 }, |
| 166 { |
| 167 Path: "/rootDir/pathb
", |
| 168 RelPath: "pathb", |
| 169 Mode: os.ModeSymlink, |
| 170 Size: 1 << 1, |
| 171 }, |
| 172 }, |
| 173 totalSize: 3, |
| 174 }, |
| 175 }, |
| 176 }, |
| 177 { |
| 178 name: "aggregates large file sizes", |
| 179 files: []file{ |
| 180 regularFile("/rootDir/patha", 1024<<10), |
| 181 regularFile("/rootDir/pathb", 1024<<11), |
| 182 }, |
| 183 want: partitionedDeps{ |
| 184 indivFiles: itemGroup{ |
| 185 items: []*Item{ |
| 186 { |
| 187 Path: "/rootDir/patha
", |
| 188 RelPath: "patha", |
| 189 Mode: 0, |
| 190 Size: 1024 << 10, |
| 191 }, |
| 192 { |
| 193 Path: "/rootDir/pathb
", |
| 194 RelPath: "pathb", |
| 195 Mode: 0, |
| 196 Size: 1024 << 11, |
| 197 }, |
| 198 }, |
| 199 totalSize: (1024 << 10) + (1024 << 11), |
| 200 }, |
| 201 }, |
| 202 }, |
| 203 { |
| 204 name: "aggregates small file sizes", |
| 205 files: []file{ |
| 206 regularFile("/rootDir/patha", 1024), |
| 207 regularFile("/rootDir/pathb", 1024<<1), |
| 208 }, |
| 209 want: partitionedDeps{ |
| 210 filesToArchive: itemGroup{ |
| 211 items: []*Item{ |
| 212 { |
| 213 Path: "/rootDir/patha
", |
| 214 RelPath: "patha", |
| 215 Mode: 0, |
| 216 Size: 1024, |
| 217 }, |
| 218 { |
| 219 Path: "/rootDir/pathb
", |
| 220 RelPath: "pathb", |
| 221 Mode: 0, |
| 222 Size: 1024 << 1, |
| 223 }, |
| 224 }, |
| 225 totalSize: 1024 + 2048, |
| 226 }, |
| 227 }, |
| 228 }, |
| 229 } |
| 230 |
| 231 TestCases: |
| 232 for _, tc := range testCases { |
| 233 pw := partitioningWalker{rootDir: "/rootDir"} |
| 234 for _, f := range tc.files { |
| 235 if err := pw.walkFn(f.path, f.bfi, tc.walkFnErr); err !=
nil { |
| 236 t.Errorf("partitioning deps(%s): walkFn got err
%v; want nil", tc.name, err) |
| 237 continue TestCases |
| 238 } |
| 239 } |
| 240 if got, want := pw.parts, tc.want; !reflect.DeepEqual(got, want)
{ |
| 241 t.Errorf("partitioning deps(%s): got %#v; want %#v", tc.
name, got, want) |
| 242 } |
| 243 } |
| 244 |
| 245 } |
| 246 |
| 247 func TestWalkFn_BadRelpath(t *testing.T) { |
| 248 pw := partitioningWalker{rootDir: "/rootDir"} |
| 249 f := regularFile("./patha", 1) |
| 250 if err := pw.walkFn(f.path, f.bfi, nil); err == nil { |
| 251 t.Errorf("testing bad relpath: walkFn returned nil err; want non
-nil err") |
| 252 } |
| 253 } |
| 254 |
| 255 func TestWalkFn_ReturnsErrorsUnchanged(t *testing.T) { |
| 256 pw := partitioningWalker{rootDir: "/rootDir"} |
| 257 f := regularFile("/rootDir/patha", 1) |
| 258 if err := pw.walkFn(f.path, f.bfi, errBang); err != errBang { |
| 259 t.Errorf("walkFn err: got: %v; want %v", err, errBang) |
| 260 } |
| 261 } |
| 262 |
| 263 func TestWalkFn_DoesNothingForDirectories(t *testing.T) { |
| 264 pw := partitioningWalker{rootDir: "/rootDir"} |
| 265 f := directory("/rootDir/patha") |
| 266 if err := pw.walkFn(f.path, f.bfi, nil); err != nil { |
| 267 t.Errorf("walkFn err: got: %v; want nil", err) |
| 268 } |
| 269 } |
| OLD | NEW |