github.com/abayer/test-infra@v0.0.5/mungegithub/features/repo-updates_test.go (about) 1 /* 2 Copyright 2015 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package features 18 19 import ( 20 "fmt" 21 "path/filepath" 22 "reflect" 23 "runtime" 24 "testing" 25 26 "github.com/golang/glog" 27 "github.com/google/go-github/github" 28 "k8s.io/apimachinery/pkg/util/sets" 29 ) 30 31 var ( 32 _ = fmt.Printf 33 _ = glog.Errorf 34 ) 35 36 const ( 37 baseDir = "" 38 leafDir = "a/b/c" 39 nonExistentDir = "DELETED_DIR" 40 ) 41 42 func getTestRepo() *RepoInfo { 43 testRepo := RepoInfo{enableMdYaml: false, useReviewers: false} 44 approvers := map[string]sets.String{} 45 baseApprovers := sets.NewString("Alice", "Bob") 46 leafApprovers := sets.NewString("Carl", "Dave") 47 approvers[baseDir] = baseApprovers 48 approvers[leafDir] = leafApprovers 49 testRepo.approvers = approvers 50 testRepo.labels = map[string]sets.String{ 51 baseDir: sets.NewString("sig/godzilla"), 52 leafDir: sets.NewString("wg/save-tokyo"), 53 } 54 55 return &testRepo 56 } 57 58 func TestGetApprovers(t *testing.T) { 59 testFile0 := filepath.Join(baseDir, "testFile.md") 60 testFile1 := filepath.Join(leafDir, "testFile.md") 61 testFile2 := filepath.Join(nonExistentDir, "testFile.md") 62 TestRepo := getTestRepo() 63 tests := []struct { 64 testName string 65 testFile *github.CommitFile 66 expectedOwnersPath string 67 expectedLeafOwners sets.String 68 expectedAllOwners sets.String 69 }{ 70 { 71 testName: "Modified Base Dir Only", 72 testFile: &github.CommitFile{Filename: &testFile0}, 73 expectedOwnersPath: baseDir, 74 expectedLeafOwners: TestRepo.approvers[baseDir], 75 expectedAllOwners: TestRepo.approvers[baseDir], 76 }, 77 { 78 testName: "Modified Leaf Dir Only", 79 testFile: &github.CommitFile{Filename: &testFile1}, 80 expectedOwnersPath: leafDir, 81 expectedLeafOwners: TestRepo.approvers[leafDir], 82 expectedAllOwners: TestRepo.approvers[leafDir].Union(TestRepo.approvers[baseDir]), 83 }, 84 { 85 testName: "Modified Nonexistent Dir (Default to Base)", 86 testFile: &github.CommitFile{Filename: &testFile2}, 87 expectedOwnersPath: baseDir, 88 expectedLeafOwners: TestRepo.approvers[baseDir], 89 expectedAllOwners: TestRepo.approvers[baseDir], 90 }, 91 } 92 for testNum, test := range tests { 93 foundLeafApprovers := TestRepo.LeafApprovers(*test.testFile.Filename) 94 foundApprovers := TestRepo.Approvers(*test.testFile.Filename) 95 foundOwnersPath := TestRepo.FindApproverOwnersForPath(*test.testFile.Filename) 96 if !foundLeafApprovers.Equal(test.expectedLeafOwners) { 97 t.Errorf("The Leaf Approvers Found Do Not Match Expected For Test %d: %s", testNum, test.testName) 98 t.Errorf("\tExpected Owners: %v\tFound Owners: %v ", test.expectedLeafOwners, foundLeafApprovers) 99 } 100 if !foundApprovers.Equal(test.expectedAllOwners) { 101 t.Errorf("The Approvers Found Do Not Match Expected For Test %d: %s", testNum, test.testName) 102 t.Errorf("\tExpected Owners: %v\tFound Owners: %v ", test.expectedAllOwners, foundApprovers) 103 } 104 if foundOwnersPath != test.expectedOwnersPath { 105 t.Errorf("The Owners Path Found Does Not Match Expected For Test %d: %s", testNum, test.testName) 106 t.Errorf("\tExpected Owners: %v\tFound Owners: %v ", test.expectedOwnersPath, foundOwnersPath) 107 } 108 } 109 } 110 111 func TestLabels(t *testing.T) { 112 tests := []struct { 113 testName string 114 inputPath string 115 expectedLabels sets.String 116 }{ 117 { 118 testName: "base 1", 119 inputPath: "foo.txt", 120 expectedLabels: sets.NewString("sig/godzilla"), 121 }, { 122 testName: "base 2", 123 inputPath: "./foo.txt", 124 expectedLabels: sets.NewString("sig/godzilla"), 125 }, { 126 testName: "base 3", 127 inputPath: "", 128 expectedLabels: sets.NewString("sig/godzilla"), 129 }, { 130 testName: "base 4", 131 inputPath: ".", 132 expectedLabels: sets.NewString("sig/godzilla"), 133 }, { 134 testName: "leaf 1", 135 inputPath: "a/b/c/foo.txt", 136 expectedLabels: sets.NewString("sig/godzilla", "wg/save-tokyo"), 137 }, { 138 testName: "leaf 2", 139 inputPath: "a/b/foo.txt", 140 expectedLabels: sets.NewString("sig/godzilla"), 141 }, 142 } 143 144 TestRepo := getTestRepo() 145 for _, tt := range tests { 146 got := TestRepo.FindLabelsForPath(tt.inputPath) 147 if !got.Equal(tt.expectedLabels) { 148 t.Errorf("%v: expected %v, got %v", tt.testName, tt.expectedLabels, got) 149 } 150 } 151 } 152 153 func TestCanonical(t *testing.T) { 154 155 tests := []struct { 156 testName string 157 inputPath string 158 expectedPath string 159 }{ 160 { 161 testName: "Empty String", 162 inputPath: "", 163 expectedPath: "", 164 }, 165 { 166 testName: "Dot (.) as Path", 167 inputPath: ".", 168 expectedPath: "", 169 }, 170 { 171 testName: "Github Style Input (No Root)", 172 inputPath: "a/b/c/d.txt", 173 expectedPath: "a/b/c/d.txt", 174 }, 175 { 176 testName: "Preceding Slash and Trailing Slash", 177 inputPath: "/a/b/", 178 expectedPath: "/a/b", 179 }, 180 { 181 testName: "Trailing Slash", 182 inputPath: "foo/bar/baz/", 183 expectedPath: "foo/bar/baz", 184 }, 185 } 186 for _, test := range tests { 187 if test.expectedPath != canonicalize(test.inputPath) { 188 t.Errorf("Expected the canonical path for %v to be %v. Found %v instead", test.inputPath, test.expectedPath, canonicalize(test.inputPath)) 189 } 190 } 191 } 192 193 var ( 194 lowerCaseAliases = []byte(` 195 aliases: 196 team/t1: 197 - u1 198 - u2 199 team/t2: 200 - u1 201 - u3`) 202 mixedCaseAliases = []byte(` 203 aliases: 204 TEAM/T1: 205 - U1 206 - U2`) 207 ) 208 209 type aliasTest struct { 210 data []byte 211 } 212 213 func (a *aliasTest) read() ([]byte, error) { 214 return a.data, nil 215 } 216 217 func TestCalculateAliasDelta(t *testing.T) { 218 runtime.GOMAXPROCS(runtime.NumCPU()) 219 220 tests := []struct { 221 name string 222 aliasData []byte 223 approvers sets.String 224 reviewers sets.String 225 expectedA sets.String 226 expectedR sets.String 227 }{ 228 { 229 name: "No expansions.", 230 aliasData: lowerCaseAliases, 231 approvers: sets.NewString("abc", "def"), 232 expectedA: sets.NewString("abc", "def"), 233 reviewers: sets.NewString("abcr", "defr"), 234 expectedR: sets.NewString("abcr", "defr"), 235 }, 236 { 237 name: "One alias to be expanded", 238 aliasData: lowerCaseAliases, 239 approvers: sets.NewString("abc", "team/t1"), 240 expectedA: sets.NewString("abc", "u1", "u2"), 241 reviewers: sets.NewString("abcr", "team/t2"), 242 expectedR: sets.NewString("abcr", "u1", "u3"), 243 }, 244 { 245 name: "Duplicates inside and outside alias.", 246 aliasData: lowerCaseAliases, 247 approvers: sets.NewString("u1", "team/t1"), 248 expectedA: sets.NewString("u1", "u2"), 249 reviewers: sets.NewString("u3", "team/t2"), 250 expectedR: sets.NewString("u3", "u1"), 251 }, 252 { 253 name: "Duplicates in multiple aliases.", 254 aliasData: lowerCaseAliases, 255 approvers: sets.NewString("u1", "team/t1", "team/t2"), 256 expectedA: sets.NewString("u1", "u2", "u3"), 257 reviewers: sets.NewString("u1", "team/t1", "team/t2"), 258 expectedR: sets.NewString("u1", "u2", "u3"), 259 }, 260 { 261 name: "Mixed casing in aliases.", 262 aliasData: mixedCaseAliases, 263 approvers: sets.NewString("team/t1"), 264 expectedA: sets.NewString("u1", "u2"), 265 reviewers: sets.NewString("team/t1"), 266 expectedR: sets.NewString("u1", "u2"), 267 }, 268 } 269 270 for _, test := range tests { 271 info := RepoInfo{ 272 aliasFile: "dummy.file", 273 aliasData: &aliasData{}, 274 aliasReader: &aliasTest{ 275 data: test.aliasData, 276 }, 277 approvers: map[string]sets.String{ 278 "fake": test.approvers, 279 }, 280 reviewers: map[string]sets.String{ 281 "fake": test.reviewers, 282 }, 283 } 284 285 if err := info.updateRepoAliases(); err != nil { 286 t.Fatalf("%v", err) 287 } 288 289 info.expandAllAliases() 290 if expected, got := test.expectedA, info.approvers["fake"]; !reflect.DeepEqual(expected, got) { 291 t.Errorf("%s: expected approvers: %#v, got: %#v", test.name, expected, got) 292 } 293 if expected, got := test.expectedR, info.reviewers["fake"]; !reflect.DeepEqual(expected, got) { 294 t.Errorf("%s: expected reviewers: %#v, got: %#v", test.name, expected, got) 295 } 296 } 297 } 298 299 func TestResolveAlias(t *testing.T) { 300 tests := []struct { 301 name string 302 knownAliases map[string][]string 303 user string 304 expected []string 305 }{ 306 { 307 name: "no known aliases", 308 knownAliases: map[string][]string{}, 309 user: "bob", 310 expected: []string{}, 311 }, 312 { 313 name: "no applicable aliases", 314 knownAliases: map[string][]string{"jim": {"james"}}, 315 user: "bob", 316 expected: []string{}, 317 }, 318 { 319 name: "applicable aliases", 320 knownAliases: map[string][]string{"bob": {"robert"}}, 321 user: "bob", 322 expected: []string{"robert"}, 323 }, 324 } 325 326 for _, test := range tests { 327 info := RepoInfo{ 328 aliasData: &aliasData{ 329 AliasMap: test.knownAliases, 330 }, 331 } 332 333 if expected, got := test.expected, info.resolveAlias(test.user); !reflect.DeepEqual(expected, got) { 334 t.Errorf("%s: expected: %#v, got: %#v", test.name, expected, got) 335 } 336 } 337 }