sigs.k8s.io/prow@v0.0.0-20240503223140-c5e374dc7eb1/pkg/genfiles/genfiles_test.go (about) 1 /* 2 Copyright 2016 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 genfiles 18 19 import ( 20 "bytes" 21 "testing" 22 ) 23 24 func TestGroupLoad(t *testing.T) { 25 cases := []struct { 26 name string 27 src string 28 repoPaths []string 29 err error 30 31 want Group 32 }{ 33 { 34 name: "k8s-config", 35 src: `# Files that should be ignored by tools which do not want to consider generated 36 # code. 37 # 38 # eg: https://github.com/kubernetes-sigs/prow/blob/main/pkg/plugins/size/size.go 39 # 40 # This file is a series of lines, each of the form: 41 # <type> <name> 42 # 43 # Type can be: 44 # path - an exact path to a single file 45 # file-name - an exact leaf filename, regardless of path 46 # path-prefix - a prefix match on the file path 47 # file-prefix - a prefix match of the leaf filename (no path) 48 # paths-from-repo - read a file from the repo and load file paths 49 # 50 51 file-prefix zz_generated. 52 53 file-name BUILD 54 file-name types.generated.go 55 file-name generated.pb.go 56 file-name generated.proto 57 file-name types_swagger_doc_generated.go 58 59 path-prefix Godeps/ 60 path-prefix vendor/ 61 path-prefix api/swagger-spec/ 62 path-prefix pkg/generated/ 63 64 paths-from-repo docs/.generated_docs`, 65 repoPaths: []string{"docs/.generated_docs"}, 66 want: Group{ 67 FileNames: map[string]bool{ 68 "BUILD": true, 69 "types.generated.go": true, 70 "generated.pb.go": true, 71 "generated.proto": true, 72 "types_swagger_doc_generated.go": true, 73 }, 74 PathPrefixes: map[string]bool{ 75 "Godeps/": true, 76 "vendor/": true, 77 "api/swagger-spec/": true, 78 "pkg/generated/": true, 79 }, 80 FilePrefixes: map[string]bool{ 81 "zz_generated.": true, 82 }, 83 }, 84 }, 85 { 86 name: "malformed config", 87 src: `# This is an invalid .generated_files 88 89 what is this line anyway?`, 90 err: &ParseError{line: "what is this line anyway?"}, 91 want: Group{}, 92 }, 93 { 94 name: "partially valid config", 95 src: `# This file contains some valid lines, and then some bad lines. 96 97 # Good lines 98 99 file-prefix myprefix 100 file-name mypath 101 102 paths-from-repo myrepo 103 104 # Bad lines 105 106 badline 107 108 invalid command`, 109 repoPaths: []string{"myrepo"}, 110 err: &ParseError{line: "badline"}, 111 want: Group{ 112 FileNames: map[string]bool{ 113 "mypath": true, 114 }, 115 FilePrefixes: map[string]bool{ 116 "myprefix": true, 117 }, 118 }, 119 }, 120 } 121 122 for _, c := range cases { 123 t.Run(c.name, func(t *testing.T) { 124 g := &Group{ 125 Paths: make(map[string]bool), 126 FileNames: make(map[string]bool), 127 PathPrefixes: make(map[string]bool), 128 FilePrefixes: make(map[string]bool), 129 } 130 131 rps, err := g.load(bytes.NewBufferString(c.src)) 132 133 // Check repoPaths 134 if got, want := len(rps), len(c.repoPaths); got != want { 135 t.Logf("g.load, repoPaths: got %v, want %v", rps, c.repoPaths) 136 t.Fatalf("len(repoPaths) mismatch: got %d, want %d", got, want) 137 } 138 139 for i, p := range rps { 140 if got, want := p, c.repoPaths[i]; got != want { 141 t.Fatalf("repoPaths mismatch at index %d: got %s, want %s", i, got, want) 142 } 143 } 144 145 // Check err 146 if err != nil && c.err == nil { 147 t.Fatalf("load error: %v", err) 148 } 149 150 if err == nil && c.err != nil { 151 t.Fatalf("load wanted error %v, got nil", err) 152 } 153 154 if got, want := err, c.err; got != nil && got.Error() != want.Error() { 155 t.Fatalf("load errors mismatch: got %v, want %v", got, want) 156 } 157 158 // Check g.Paths 159 if got, want := len(g.Paths), len(c.want.Paths); got != want { 160 t.Logf("g.Paths: got %v, want %v", g.Paths, c.want.Paths) 161 t.Fatalf("len(g.Paths) mismatch: got %d, want %d", got, want) 162 } 163 164 for k, v := range g.Paths { 165 if got, want := v, c.want.Paths[k]; got != want { 166 t.Fatalf("g.Paths mismatch at key %q: got %t, want %t", k, got, want) 167 } 168 } 169 170 // Check g.FileNames 171 if got, want := len(g.FileNames), len(c.want.FileNames); got != want { 172 t.Logf("g.FileNames: got %v, want %v", g.FileNames, c.want.FileNames) 173 t.Fatalf("len(g.FileNames) mismatch: got %d, want %d", got, want) 174 } 175 176 for k, v := range g.FileNames { 177 if got, want := v, c.want.FileNames[k]; got != want { 178 t.Fatalf("g.FileNames mismatch at key %q: got %t, want %t", k, got, want) 179 } 180 } 181 182 // Check g.PathPrefixes 183 if got, want := len(g.PathPrefixes), len(c.want.PathPrefixes); got != want { 184 t.Logf("g.PathPrefixes: got %v, want %v", g.PathPrefixes, c.want.PathPrefixes) 185 t.Fatalf("len(g.PathPrefixes) mismatch: got %d, want %d", got, want) 186 } 187 188 for k, v := range g.PathPrefixes { 189 if got, want := v, c.want.PathPrefixes[k]; got != want { 190 t.Fatalf("g.PathPrefixes mismatch at key %q: got %t, want %t", k, got, want) 191 } 192 } 193 194 // Check g.FilePrefixes 195 if got, want := len(g.FilePrefixes), len(c.want.FilePrefixes); got != want { 196 t.Logf("g.FilePrefixes: got %v, want %v", g.FilePrefixes, c.want.FilePrefixes) 197 t.Fatalf("len(g.FilePrefixes) mismatch: got %d, want %d", got, want) 198 } 199 200 for k, v := range g.FilePrefixes { 201 if got, want := v, c.want.FilePrefixes[k]; got != want { 202 t.Fatalf("g.FilePrefixes mismatch at key %q: got %t, want %t", k, got, want) 203 } 204 } 205 }) 206 } 207 } 208 209 func TestGroupLoadPaths(t *testing.T) { 210 cases := []struct { 211 name string 212 src string 213 err error 214 215 // Assume that the Group started empty. 216 want Group 217 }{ 218 { 219 name: "k8s/docs", 220 src: `# first 3 lines of kubernetes/docs/.generated_docs 221 docs/.generated_docs 222 docs/admin/cloud-controller-manager.md 223 docs/admin/federation-apiserver.md 224 # ...`, 225 err: nil, 226 227 want: Group{ 228 Paths: map[string]bool{ 229 "docs/.generated_docs": true, 230 "docs/admin/cloud-controller-manager.md": true, 231 "docs/admin/federation-apiserver.md": true, 232 }, 233 }, 234 }, 235 } 236 237 for _, c := range cases { 238 t.Run(c.name, func(t *testing.T) { 239 g := &Group{ 240 Paths: make(map[string]bool), 241 FileNames: make(map[string]bool), 242 PathPrefixes: make(map[string]bool), 243 FilePrefixes: make(map[string]bool), 244 } 245 246 if got, want := g.loadPaths(bytes.NewBufferString(c.src)), c.err; got != nil && want != nil && got.Error() != want.Error() { 247 t.Fatalf("g.loadPaths: got %s, want %s", got, want) 248 } 249 250 // Check g.Paths 251 if got, want := len(g.Paths), len(c.want.Paths); got != want { 252 t.Logf("g.Paths: got %v, want %v", g.Paths, c.want.Paths) 253 t.Fatalf("len(g.Paths) mismatch: got %d, want %d", got, want) 254 } 255 256 for k, v := range g.Paths { 257 if got, want := v, c.want.Paths[k]; got != want { 258 t.Fatalf("g.Paths mismatch at key %q: got %t, want %t", k, got, want) 259 } 260 } 261 }) 262 } 263 } 264 265 func TestGroupMatch(t *testing.T) { 266 group := &Group{ 267 Paths: map[string]bool{ 268 "foo": true, 269 "bar/": true, 270 "foo/bar": true, 271 }, 272 PathPrefixes: map[string]bool{ 273 "kubernetes/generated": true, 274 }, 275 FileNames: map[string]bool{ 276 "generated.txt": true, 277 }, 278 FilePrefixes: map[string]bool{ 279 "mygen": true, 280 }, 281 } 282 283 cases := []struct { 284 path string 285 match bool 286 }{ 287 // Intend to test group.Paths 288 {}, 289 {path: "foo", match: true}, 290 {path: "foo/bar", match: true}, 291 {path: "foo/baz", match: false}, 292 293 // Intend to test group.PathPrefixes 294 {path: "kubernetes/generated/one.txt", match: true}, 295 {path: "kubernetes/generated/two.txt", match: true}, 296 {path: "kubernetes/not_generated.txt", match: false}, 297 298 // Intend to test group.FileNames 299 {path: "kubernetes/generated.txt", match: true}, 300 {path: "generated.txt", match: true}, 301 {path: "/any/old/path/generated.txt", match: true}, 302 {path: "/everywhere/generated.txt", match: true}, 303 {path: "/and/nowhere/generated.txt", match: true}, 304 {path: "/and/nowhere/NOT_generated.txt", match: false}, 305 306 // Intend to test group.FilePrefixes 307 {path: "mygen.proto", match: true}, 308 {path: "/any/path/mygen.go", match: true}, 309 {path: "/any/mygenWithAName.go", match: true}, 310 {path: "notmygen.go", match: false}, 311 } 312 313 for _, c := range cases { 314 t.Run(c.path, func(t *testing.T) { 315 if got, want := group.Match(c.path), c.match; got != want { 316 t.Fatalf("group.Match: got %t, want %t", got, want) 317 } 318 }) 319 } 320 }