kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/go/platform/kzip/info/info_test.go (about)

     1  /*
     2   * Copyright 2019 The Kythe Authors. All rights reserved.
     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 info
    18  
    19  import (
    20  	"bytes"
    21  	"testing"
    22  
    23  	"kythe.io/kythe/go/platform/kzip"
    24  	"kythe.io/kythe/go/util/compare"
    25  
    26  	apb "kythe.io/kythe/proto/analysis_go_proto"
    27  	spb "kythe.io/kythe/proto/storage_go_proto"
    28  )
    29  
    30  func TestMergeKzipInfo(t *testing.T) {
    31  	infos := []*apb.KzipInfo{
    32  		{
    33  			Corpora: map[string]*apb.KzipInfo_CorpusInfo{
    34  				"corpus1": {
    35  					LanguageRequiredInputs: map[string]*apb.KzipInfo_CorpusInfo_Inputs{
    36  						"python": {
    37  							Count: 2,
    38  						},
    39  					},
    40  					LanguageSources: map[string]*apb.KzipInfo_CorpusInfo_Inputs{
    41  						"python": {
    42  							Count: 1,
    43  						},
    44  					},
    45  					LanguageCuInfo: map[string]*apb.KzipInfo_CorpusInfo_CUInfo{
    46  						"python": {
    47  							Count: 1,
    48  						},
    49  						"java": {
    50  							Count: 20,
    51  							JavaVersionCount: map[int32]int32{
    52  								7: 10,
    53  							},
    54  						},
    55  					},
    56  				},
    57  			},
    58  			CriticalKzipErrors: []string{"foo.py doesn't have a required_input"},
    59  			Size:               10,
    60  		},
    61  		{
    62  			Corpora: map[string]*apb.KzipInfo_CorpusInfo{
    63  				"corpus1": {
    64  					LanguageRequiredInputs: map[string]*apb.KzipInfo_CorpusInfo_Inputs{
    65  						"python": {
    66  							Count: 1,
    67  						},
    68  					},
    69  					LanguageCuInfo: map[string]*apb.KzipInfo_CorpusInfo_CUInfo{
    70  						"python": {
    71  							Count: 1,
    72  						},
    73  						"java": {
    74  							Count: 2,
    75  							JavaVersionCount: map[int32]int32{
    76  								6: 1,
    77  								7: 7,
    78  							},
    79  						},
    80  					},
    81  				},
    82  				"corpus2": {
    83  					LanguageSources: map[string]*apb.KzipInfo_CorpusInfo_Inputs{
    84  						"python": {
    85  							Count: 5,
    86  						},
    87  						"java": {
    88  							Count: 3,
    89  						},
    90  					},
    91  					LanguageCuInfo: map[string]*apb.KzipInfo_CorpusInfo_CUInfo{
    92  						"java": {
    93  							Count: 3,
    94  							JavaVersionCount: map[int32]int32{
    95  								4: 1,
    96  							},
    97  						},
    98  					},
    99  				},
   100  				"unnamed_required_input_corpus": {
   101  					LanguageRequiredInputs: map[string]*apb.KzipInfo_CorpusInfo_Inputs{
   102  						"python": {
   103  							Count: 9,
   104  						},
   105  						"java": {
   106  							Count: 20,
   107  						},
   108  						"go": {
   109  							Count: 2,
   110  						},
   111  					},
   112  				},
   113  			},
   114  			CriticalKzipErrors: []string{"foo2.py doesn't have a required_input"},
   115  			Size:               30,
   116  		},
   117  	}
   118  
   119  	want := &apb.KzipInfo{
   120  		Corpora: map[string]*apb.KzipInfo_CorpusInfo{
   121  			"corpus1": {
   122  				LanguageRequiredInputs: map[string]*apb.KzipInfo_CorpusInfo_Inputs{
   123  					"python": {
   124  						Count: 3,
   125  					},
   126  				},
   127  				LanguageSources: map[string]*apb.KzipInfo_CorpusInfo_Inputs{
   128  					"python": {
   129  						Count: 1,
   130  					},
   131  				},
   132  				LanguageCuInfo: map[string]*apb.KzipInfo_CorpusInfo_CUInfo{
   133  					"python": {
   134  						Count: 2,
   135  					},
   136  					"java": {
   137  						Count: 22,
   138  						JavaVersionCount: map[int32]int32{
   139  							6: 1,
   140  							7: 17,
   141  						},
   142  					},
   143  				},
   144  			},
   145  			"corpus2": {
   146  				LanguageSources: map[string]*apb.KzipInfo_CorpusInfo_Inputs{
   147  					"python": {
   148  						Count: 5,
   149  					},
   150  					"java": {
   151  						Count: 3,
   152  					},
   153  				},
   154  				LanguageCuInfo: map[string]*apb.KzipInfo_CorpusInfo_CUInfo{
   155  					"java": {
   156  						Count: 3,
   157  						JavaVersionCount: map[int32]int32{
   158  							4: 1,
   159  						},
   160  					},
   161  				},
   162  			},
   163  			"unnamed_required_input_corpus": {
   164  				LanguageRequiredInputs: map[string]*apb.KzipInfo_CorpusInfo_Inputs{
   165  					"python": {
   166  						Count: 9,
   167  					},
   168  					"java": {
   169  						Count: 20,
   170  					},
   171  					"go": {
   172  						Count: 2,
   173  					},
   174  				},
   175  			},
   176  		},
   177  		CriticalKzipErrors: []string{"foo.py doesn't have a required_input", "foo2.py doesn't have a required_input"},
   178  		Size:               40,
   179  	}
   180  	wantTotal := &apb.KzipInfo_CorpusInfo{
   181  		LanguageRequiredInputs: map[string]*apb.KzipInfo_CorpusInfo_Inputs{
   182  			"python": {
   183  				Count: 12,
   184  			},
   185  			"java": {
   186  				Count: 20,
   187  			},
   188  			"go": {
   189  				Count: 2,
   190  			},
   191  		},
   192  		LanguageSources: map[string]*apb.KzipInfo_CorpusInfo_Inputs{
   193  			"python": {
   194  				Count: 6,
   195  			},
   196  			"java": {
   197  				Count: 3,
   198  			},
   199  		},
   200  		LanguageCuInfo: map[string]*apb.KzipInfo_CorpusInfo_CUInfo{
   201  			"python": {
   202  				Count: 2,
   203  			},
   204  			"java": {
   205  				Count: 25,
   206  				JavaVersionCount: map[int32]int32{
   207  					4: 1,
   208  					6: 1,
   209  					7: 17,
   210  				},
   211  			},
   212  		},
   213  	}
   214  
   215  	got := MergeKzipInfo(infos)
   216  	gotTotal := KzipInfoTotalCount(infos)
   217  	if diff := compare.ProtoDiff(got, want); diff != "" {
   218  		t.Errorf("Merged kzips don't match: (-: found, +: expected)\n%s", diff)
   219  	}
   220  	if diff := compare.ProtoDiff(gotTotal, wantTotal); diff != "" {
   221  		t.Errorf("got %v, want %v", gotTotal, wantTotal)
   222  		t.Errorf("Merged kzips don't match: (-: found, +: expected)\n%s", diff)
   223  	}
   224  }
   225  
   226  func makeKzip(t *testing.T, u *apb.CompilationUnit) *bytes.Reader {
   227  	b := bytes.NewBuffer(nil)
   228  	w, err := kzip.NewWriter(b)
   229  	if err != nil {
   230  		t.Fatalf("opening writer: %v", err)
   231  	}
   232  	if _, err = w.AddUnit(u, nil); err != nil {
   233  		t.Fatalf("AddUnit: unexpected error: %v", err)
   234  	}
   235  	if err := w.Close(); err != nil {
   236  		t.Fatalf("Writer.Close: unexpected error: %v", err)
   237  	}
   238  	return bytes.NewReader(b.Bytes())
   239  }
   240  
   241  var infoTests = []struct {
   242  	name string
   243  	in   *apb.CompilationUnit
   244  	out  *apb.KzipInfo
   245  }{
   246  	{
   247  		"required counts",
   248  		&apb.CompilationUnit{
   249  			VName: &spb.VName{Language: "python"},
   250  			RequiredInput: []*apb.CompilationUnit_FileInput{
   251  				{
   252  					VName: &spb.VName{Corpus: "mycorpus", Language: "python", Path: "file1.py"},
   253  					Info:  &apb.FileInfo{Path: "file1.py"},
   254  				},
   255  			},
   256  		},
   257  		&apb.KzipInfo{
   258  			Corpora: map[string]*apb.KzipInfo_CorpusInfo{
   259  				"mycorpus": {
   260  					LanguageRequiredInputs: map[string]*apb.KzipInfo_CorpusInfo_Inputs{
   261  						"python": {
   262  							Count: 1,
   263  						},
   264  					},
   265  				},
   266  				"": {
   267  					LanguageCuInfo: map[string]*apb.KzipInfo_CorpusInfo_CUInfo{
   268  						"python": {
   269  							Count: 1,
   270  						},
   271  					},
   272  				},
   273  			},
   274  		},
   275  	},
   276  
   277  	{
   278  		"No corpus for required input",
   279  		&apb.CompilationUnit{
   280  			VName: &spb.VName{Language: "python"},
   281  			RequiredInput: []*apb.CompilationUnit_FileInput{
   282  				{
   283  					VName: &spb.VName{Language: "python", Path: "file1.py"},
   284  					Info:  &apb.FileInfo{Path: "file1.py"},
   285  				},
   286  			},
   287  		},
   288  		&apb.KzipInfo{
   289  			Corpora: map[string]*apb.KzipInfo_CorpusInfo{
   290  				"": {
   291  					LanguageCuInfo: map[string]*apb.KzipInfo_CorpusInfo_CUInfo{
   292  						"python": {
   293  							Count: 1,
   294  						},
   295  					},
   296  				},
   297  			},
   298  			CriticalKzipErrors: []string{`unable to determine corpus for required_input "file1.py" in CU(language:"python")`},
   299  		},
   300  	},
   301  
   302  	// kzip info checks that each source file has a corresponding required_input
   303  	// entry. This test case checks that the required_input path is normalized
   304  	// before doing the check.
   305  	{
   306  		"normalize paths",
   307  		&apb.CompilationUnit{
   308  			VName: &spb.VName{Language: "c++", Corpus: "kythe"},
   309  			RequiredInput: []*apb.CompilationUnit_FileInput{
   310  				{
   311  					VName: &spb.VName{
   312  						Language: "c++",
   313  						Corpus:   "kythe",
   314  						Path:     "kythe/cxx/verifier/parser.yy.cc",
   315  						Root:     "bazel-out/bin",
   316  					},
   317  					Info: &apb.FileInfo{
   318  						Path: "bazel-out/k8-fastbuild/bin/kythe/cxx/verifier/../../../../../../bazel-out/k8-fastbuild/bin/kythe/cxx/verifier/parser.yy.cc",
   319  					},
   320  				},
   321  			},
   322  			SourceFile: []string{"bazel-out/k8-fastbuild/bin/kythe/cxx/verifier/parser.yy.cc"},
   323  		},
   324  		&apb.KzipInfo{
   325  			Corpora: map[string]*apb.KzipInfo_CorpusInfo{
   326  				"kythe": {
   327  					LanguageRequiredInputs: map[string]*apb.KzipInfo_CorpusInfo_Inputs{
   328  						"c++": {
   329  							Count: 1,
   330  						},
   331  					},
   332  					LanguageSources: map[string]*apb.KzipInfo_CorpusInfo_Inputs{
   333  						"c++": {
   334  							Count: 1,
   335  						},
   336  					},
   337  					LanguageCuInfo: map[string]*apb.KzipInfo_CorpusInfo_CUInfo{
   338  						"c++": {
   339  							Count: 1,
   340  						},
   341  					},
   342  				},
   343  			},
   344  		},
   345  	},
   346  }
   347  
   348  func TestInfo(t *testing.T) {
   349  	for _, testcase := range infoTests {
   350  		kz := makeKzip(t, testcase.in)
   351  		got, err := KzipInfo(kz, 0)
   352  		if err != nil {
   353  			t.Error(err)
   354  			continue
   355  		}
   356  
   357  		if diff := compare.ProtoDiff(testcase.out, got); diff != "" {
   358  			t.Errorf("KzipInfo() output differs from expected for %s (-: found, +: expected)\n%s", testcase.name, diff)
   359  		}
   360  	}
   361  }