github.com/abayer/test-infra@v0.0.5/prow/plugins/golint/golint_test.go (about) 1 /* 2 Copyright 2017 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 golint 18 19 import ( 20 "fmt" 21 "reflect" 22 "strings" 23 "testing" 24 25 "github.com/sirupsen/logrus" 26 27 "k8s.io/test-infra/prow/git/localgit" 28 "k8s.io/test-infra/prow/github" 29 ) 30 31 var initialFiles = map[string][]byte{ 32 "bar.go": []byte(`// Package bar does an interesting thing. 33 package bar 34 35 // Foo does a thing. 36 func Foo(wow int) int { 37 return 42 + wow 38 } 39 `), 40 } 41 42 var pullFiles = map[string][]byte{ 43 "qux.go": []byte(`package bar 44 45 func Qux() error { 46 return nil 47 } 48 `), 49 "zz_generated.wowza.go": []byte(`package bar 50 51 func Qux() error { 52 return nil 53 } 54 `), 55 } 56 57 type ghc struct { 58 genfile []byte 59 pr github.PullRequest 60 changes []github.PullRequestChange 61 oldComments []github.ReviewComment 62 comment github.DraftReview 63 } 64 65 func (g *ghc) GetPullRequestChanges(org, repo string, number int) ([]github.PullRequestChange, error) { 66 return g.changes, nil 67 } 68 69 func (g *ghc) CreateReview(org, repo string, number int, r github.DraftReview) error { 70 g.comment = r 71 return nil 72 } 73 74 func (g *ghc) ListPullRequestComments(org, repo string, number int) ([]github.ReviewComment, error) { 75 return g.oldComments, nil 76 } 77 78 func (g *ghc) GetFile(org, repo, filepath, commit string) ([]byte, error) { 79 return g.genfile, nil 80 } 81 82 func (g *ghc) GetPullRequest(org, repo string, number int) (*github.PullRequest, error) { 83 return &g.pr, nil 84 } 85 86 var e = &github.GenericCommentEvent{ 87 Action: github.GenericCommentActionCreated, 88 IssueState: "open", 89 Body: "/lint", 90 User: github.User{Login: "cjwagner"}, 91 Number: 42, 92 IsPR: true, 93 Repo: github.Repo{ 94 Owner: github.User{Login: "foo"}, 95 Name: "bar", 96 FullName: "foo/bar", 97 }, 98 } 99 100 func TestLint(t *testing.T) { 101 lg, c, err := localgit.New() 102 if err != nil { 103 t.Fatalf("Making localgit: %v", err) 104 } 105 defer func() { 106 if err := lg.Clean(); err != nil { 107 t.Errorf("Cleaning up localgit: %v", err) 108 } 109 if err := c.Clean(); err != nil { 110 t.Errorf("Cleaning up client: %v", err) 111 } 112 }() 113 if err := lg.MakeFakeRepo("foo", "bar"); err != nil { 114 t.Fatalf("Making fake repo: %v", err) 115 } 116 if err := lg.AddCommit("foo", "bar", initialFiles); err != nil { 117 t.Fatalf("Adding initial commit: %v", err) 118 } 119 if err := lg.CheckoutNewBranch("foo", "bar", "pull/42/head"); err != nil { 120 t.Fatalf("Checking out pull branch: %v", err) 121 } 122 if err := lg.AddCommit("foo", "bar", pullFiles); err != nil { 123 t.Fatalf("Adding PR commit: %v", err) 124 } 125 126 gh := &ghc{ 127 genfile: []byte("file-prefix zz_generated"), 128 changes: []github.PullRequestChange{ 129 { 130 Filename: "qux.go", 131 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 132 }, 133 { 134 Filename: "zz_generated.wowza.go", 135 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux2() error {\n+ return nil\n+}", 136 }, 137 }, 138 } 139 if err := handle(gh, c, logrus.NewEntry(logrus.New()), e); err != nil { 140 t.Fatalf("Got error from handle: %v", err) 141 } 142 if len(gh.comment.Comments) != 2 { 143 t.Fatalf("Expected two comments, got %d: %v.", len(gh.comment.Comments), gh.comment.Comments) 144 } 145 for _, c := range gh.comment.Comments { 146 pos := c.Position 147 gh.oldComments = append(gh.oldComments, github.ReviewComment{ 148 Path: c.Path, 149 Position: &pos, 150 Body: c.Body, 151 }) 152 } 153 if err := handle(gh, c, logrus.NewEntry(logrus.New()), e); err != nil { 154 t.Fatalf("Got error from handle on second try: %v", err) 155 } 156 if len(gh.comment.Comments) != 0 { 157 t.Fatalf("Expected no comments, got %d: %v", len(gh.comment.Comments), gh.comment.Comments) 158 } 159 160 // Test that we limit comments. 161 badFileLines := []string{"package baz", ""} 162 for i := 0; i < maxComments+5; i++ { 163 badFileLines = append(badFileLines, fmt.Sprintf("type PublicType%d int", i)) 164 } 165 gh.changes = append(gh.changes, github.PullRequestChange{ 166 Filename: "baz.go", 167 Patch: fmt.Sprintf("@@ -0,0 +1,%d @@\n+%s", len(badFileLines), strings.Join(badFileLines, "\n+")), 168 }) 169 if err := lg.AddCommit("foo", "bar", map[string][]byte{"baz.go": []byte(strings.Join(badFileLines, "\n"))}); err != nil { 170 t.Fatalf("Adding PR commit: %v", err) 171 } 172 gh.oldComments = nil 173 if err := handle(gh, c, logrus.NewEntry(logrus.New()), e); err != nil { 174 t.Fatalf("Got error from handle on third try: %v", err) 175 } 176 if len(gh.comment.Comments) != maxComments { 177 t.Fatalf("Expected %d comments, got %d: %v", maxComments, len(gh.comment.Comments), gh.comment.Comments) 178 } 179 } 180 181 func TestAddedLines(t *testing.T) { 182 var testcases = []struct { 183 patch string 184 lines map[int]int 185 err bool 186 }{ 187 { 188 patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 189 lines: map[int]int{1: 1, 2: 2, 3: 3, 4: 4, 5: 5}, 190 }, 191 { 192 patch: "@@ -29,12 +29,14 @@ import (\n \t\"github.com/sirupsen/logrus\"\n \t\"github.com/ghodss/yaml\"\n \n+\t\"k8s.io/test-infra/prow/config\"\n \t\"k8s.io/test-infra/prow/jenkins\"\n \t\"k8s.io/test-infra/prow/kube\"\n \t\"k8s.io/test-infra/prow/plank\"\n )\n \n var (\n+\tconfigPath = flag.String(\"config-path\", \"/etc/config/config\", \"Path to config.yaml.\")\n \tbuildCluster = flag.String(\"build-cluster\", \"\", \"Path to file containing a YAML-marshalled kube.Cluster object. If empty, uses the local cluster.\")\n \n \tjenkinsURL = flag.String(\"jenkins-url\", \"\", \"Jenkins URL\")\n@@ -47,18 +49,22 @@ var objReg = regexp.MustCompile(`^[\\w-]+$`)\n \n func main() {\n \tflag.Parse()\n-\n \tlogrus.SetFormatter(&logrus.JSONFormatter{})\n \n-\tkc, err := kube.NewClientInCluster(kube.ProwNamespace)\n+\tconfigAgent := &config.Agent{}\n+\tif err := configAgent.Start(*configPath); err != nil {\n+\t\tlogrus.WithError(err).Fatal(\"Error starting config agent.\")\n+\t}\n+\n+\tkc, err := kube.NewClientInCluster(configAgent.Config().ProwJobNamespace)\n \tif err != nil {\n \t\tlogrus.WithError(err).Fatal(\"Error getting client.\")\n \t}\n \tvar pkc *kube.Client\n \tif *buildCluster == \"\" {\n-\t\tpkc = kc.Namespace(kube.TestPodNamespace)\n+\t\tpkc = kc.Namespace(configAgent.Config().PodNamespace)\n \t} else {\n-\t\tpkc, err = kube.NewClientFromFile(*buildCluster, kube.TestPodNamespace)\n+\t\tpkc, err = kube.NewClientFromFile(*buildCluster, configAgent.Config().PodNamespace)\n \t\tif err != nil {\n \t\t\tlogrus.WithError(err).Fatal(\"Error getting kube client to build cluster.\")\n \t\t}", 193 lines: map[int]int{4: 32, 11: 39, 23: 54, 24: 55, 25: 56, 26: 57, 27: 58, 28: 59, 35: 65, 38: 67}, 194 }, 195 { 196 patch: "@@ -1 +0,0 @@\n-such", 197 }, 198 { 199 patch: "@@ -1,3 +0,0 @@\n-such\n-a\n-doge", 200 }, 201 { 202 patch: "@@ -0,0 +1 @@\n+wow", 203 lines: map[int]int{1: 1}, 204 }, 205 { 206 patch: "@@ -1 +1 @@\n-doge\n+wow", 207 lines: map[int]int{2: 1}, 208 }, 209 { 210 patch: "something strange", 211 err: true, 212 }, 213 { 214 patch: "@@ -a,3 +0,0 @@\n-wow", 215 err: true, 216 }, 217 { 218 patch: "@@ -1 +1 @@", 219 err: true, 220 }, 221 { 222 patch: "", 223 }, 224 } 225 for _, tc := range testcases { 226 als, err := AddedLines(tc.patch) 227 if err == nil == tc.err { 228 t.Errorf("For patch %s\nExpected error %v, got error %v", tc.patch, tc.err, err) 229 continue 230 } 231 if len(als) != len(tc.lines) { 232 t.Errorf("For patch %s\nAdded lines has wrong length. Got %v, expected %v", tc.patch, als, tc.lines) 233 } 234 for pl, l := range tc.lines { 235 if als[l] != pl { 236 t.Errorf("For patch %s\nExpected added line %d to be %d, but got %d", tc.patch, l, pl, als[l]) 237 } 238 } 239 } 240 } 241 242 func TestModifiedGoFiles(t *testing.T) { 243 lg, c, err := localgit.New() 244 if err != nil { 245 t.Fatalf("Making localgit: %v", err) 246 } 247 defer func() { 248 if err := lg.Clean(); err != nil { 249 t.Errorf("Cleaning up localgit: %v", err) 250 } 251 if err := c.Clean(); err != nil { 252 t.Errorf("Cleaning up client: %v", err) 253 } 254 }() 255 if err := lg.MakeFakeRepo("foo", "bar"); err != nil { 256 t.Fatalf("Making fake repo: %v", err) 257 } 258 if err := lg.AddCommit("foo", "bar", initialFiles); err != nil { 259 t.Fatalf("Adding initial commit: %v", err) 260 } 261 if err := lg.CheckoutNewBranch("foo", "bar", "pull/42/head"); err != nil { 262 t.Fatalf("Checking out pull branch: %v", err) 263 } 264 if err := lg.AddCommit("foo", "bar", pullFiles); err != nil { 265 t.Fatalf("Adding PR commit: %v", err) 266 } 267 268 var testcases = []struct { 269 name string 270 gh *ghc 271 expectedModifiedFiles map[string]string 272 }{ 273 { 274 name: "modified files include vendor file", 275 gh: &ghc{ 276 changes: []github.PullRequestChange{ 277 { 278 Filename: "qux.go", 279 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 280 }, 281 { 282 Filename: "vendor/foo/bar.go", 283 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux2() error {\n+ return nil\n+}", 284 }, 285 }, 286 }, 287 expectedModifiedFiles: map[string]string{ 288 "qux.go": "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 289 }, 290 }, 291 { 292 name: "modified files include non go file", 293 gh: &ghc{ 294 changes: []github.PullRequestChange{ 295 { 296 Filename: "qux.go", 297 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 298 }, 299 { 300 Filename: "foo.md", 301 Patch: "@@ -1,3 +1,4 @@\n+TODO", 302 }, 303 }, 304 }, 305 expectedModifiedFiles: map[string]string{ 306 "qux.go": "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 307 }, 308 }, 309 { 310 name: "modified files include generated file", 311 gh: &ghc{ 312 genfile: []byte("file-prefix zz_generated"), 313 changes: []github.PullRequestChange{ 314 { 315 Filename: "qux.go", 316 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 317 }, 318 { 319 Filename: "zz_generated.wowza.go", 320 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux2() error {\n+ return nil\n+}", 321 }, 322 }, 323 }, 324 expectedModifiedFiles: map[string]string{ 325 "qux.go": "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 326 }, 327 }, 328 { 329 name: "modified files include removed file", 330 gh: &ghc{ 331 changes: []github.PullRequestChange{ 332 { 333 Filename: "qux.go", 334 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 335 }, 336 { 337 Filename: "bar.go", 338 Status: github.PullRequestFileRemoved, 339 Patch: "@@ -1,5 +0,0 @@\n-package bar\n-\n-func Qux() error {\n- return nil\n-}", 340 }, 341 }, 342 }, 343 expectedModifiedFiles: map[string]string{ 344 "qux.go": "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 345 }, 346 }, 347 { 348 name: "modified files include renamed file", 349 gh: &ghc{ 350 changes: []github.PullRequestChange{ 351 { 352 Filename: "qux.go", 353 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 354 }, 355 { 356 Filename: "bar.go", 357 Status: github.PullRequestFileRenamed, 358 }, 359 }, 360 }, 361 expectedModifiedFiles: map[string]string{ 362 "qux.go": "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 363 }, 364 }, 365 { 366 name: "added and modified files", 367 gh: &ghc{ 368 changes: []github.PullRequestChange{ 369 { 370 Filename: "qux.go", 371 Status: github.PullRequestFileAdded, 372 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 373 }, 374 { 375 Filename: "bar.go", 376 Patch: "@@ -0,0 +1,5 @@\n+package baz\n+\n+func Bar() error {\n+ return nil\n+}", 377 }, 378 }, 379 }, 380 expectedModifiedFiles: map[string]string{ 381 "qux.go": "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 382 "bar.go": "@@ -0,0 +1,5 @@\n+package baz\n+\n+func Bar() error {\n+ return nil\n+}", 383 }, 384 }, 385 { 386 name: "removed and renamed files", 387 gh: &ghc{ 388 changes: []github.PullRequestChange{ 389 { 390 Filename: "qux.go", 391 Status: github.PullRequestFileRemoved, 392 Patch: "@@ -1,5 +0,0 @@\n-package bar\n-\n-func Qux() error {\n- return nil\n-}", 393 }, 394 { 395 Filename: "bar.go", 396 Status: github.PullRequestFileRenamed, 397 }, 398 }, 399 }, 400 expectedModifiedFiles: map[string]string{}, 401 }, 402 } 403 for _, tc := range testcases { 404 actualModifiedFiles, _ := modifiedGoFiles(tc.gh, "foo", "bar", 9527, "0ebb33b") 405 if !reflect.DeepEqual(tc.expectedModifiedFiles, actualModifiedFiles) { 406 t.Errorf("Expected: %#v, Got %#v in case %s.", tc.expectedModifiedFiles, actualModifiedFiles, tc.name) 407 } 408 } 409 }