github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/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  }