github.com/google/osv-scalibr@v0.4.1/testing/fakeextractor/fake_extractor_test.go (about) 1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package fakeextractor_test 16 17 import ( 18 "context" 19 "io/fs" 20 "path/filepath" 21 "testing" 22 23 "github.com/google/go-cmp/cmp" 24 "github.com/google/go-cmp/cmp/cmpopts" 25 "github.com/google/osv-scalibr/extractor" 26 "github.com/google/osv-scalibr/extractor/filesystem" 27 "github.com/google/osv-scalibr/extractor/filesystem/simplefileapi" 28 "github.com/google/osv-scalibr/inventory" 29 "github.com/google/osv-scalibr/testing/fakeextractor" 30 "github.com/google/osv-scalibr/testing/fakefs" 31 ) 32 33 func TestName(t *testing.T) { 34 tests := []struct { 35 name string 36 extractor filesystem.Extractor 37 want string 38 }{ 39 { 40 name: "no name", 41 extractor: fakeextractor.New("", 1, nil, nil), 42 want: "", 43 }, 44 { 45 name: "name", 46 extractor: fakeextractor.New("some extractor", 1, nil, nil), 47 want: "some extractor", 48 }, 49 } 50 51 for _, test := range tests { 52 t.Run(test.name, func(t *testing.T) { 53 got := test.extractor.Name() 54 if got != test.want { 55 t.Fatalf("extractor.Name() = %q, want %q", got, test.want) 56 } 57 }) 58 } 59 } 60 61 func TestVersion(t *testing.T) { 62 tests := []struct { 63 name string 64 extractor filesystem.Extractor 65 want int 66 }{ 67 { 68 name: "zero version", 69 extractor: fakeextractor.New("", 0, nil, nil), 70 want: 0, 71 }, 72 { 73 name: "positive version", 74 extractor: fakeextractor.New("some extractor", 7, nil, nil), 75 want: 7, 76 }, 77 } 78 79 for _, test := range tests { 80 t.Run(test.name, func(t *testing.T) { 81 got := test.extractor.Version() 82 if got != test.want { 83 t.Fatalf("extractor.Version() = %d, want %d", got, test.want) 84 } 85 }) 86 } 87 } 88 89 func TestFileRequired(t *testing.T) { 90 type args struct { 91 path string 92 mode fs.FileMode 93 } 94 95 tests := []struct { 96 name string 97 extractor filesystem.Extractor 98 args args 99 want bool 100 }{ 101 { 102 name: "file required", 103 extractor: fakeextractor.New("", 1, []string{"some file", "another file"}, nil), 104 args: args{"some file", fs.ModePerm}, 105 want: true, 106 }, 107 { 108 name: "file not required because none are required by extractor", 109 extractor: fakeextractor.New("", 1, nil, nil), 110 args: args{"some file", fs.ModePerm}, 111 want: false, 112 }, 113 { 114 name: "file not the same as required files", 115 extractor: fakeextractor.New("", 1, []string{"some file", "another file"}, nil), 116 args: args{"yet another file", fs.ModePerm}, 117 want: false, 118 }, 119 } 120 121 for _, test := range tests { 122 t.Run(test.name, func(t *testing.T) { 123 got := test.extractor.FileRequired(simplefileapi.New(test.args.path, fakefs.FakeFileInfo{ 124 FileName: filepath.Base(test.args.path), 125 FileMode: test.args.mode, 126 })) 127 if diff := cmp.Diff(test.want, got); diff != "" { 128 t.Fatalf("extractor.FileRequired(%v, %v) returned unexpected result; diff (-want +got):\n%s", test.args.path, test.args.mode, diff) 129 } 130 }) 131 } 132 } 133 134 func TestExtract(t *testing.T) { 135 name1 := "package" 136 name2 := "another package" 137 multiplePackages := []*extractor.Package{{ 138 Name: name1, 139 Locations: []string{"some path"}, 140 }, { 141 Name: name2, 142 Locations: []string{"some path"}, 143 }} 144 145 type args struct { 146 //nolint:containedctx 147 ctx context.Context 148 input *filesystem.ScanInput 149 } 150 tests := []struct { 151 name string 152 extractor filesystem.Extractor 153 args args 154 want []*extractor.Package 155 wantErr error 156 }{ 157 { 158 name: "no_results", 159 extractor: fakeextractor.New("", 1, nil, map[string]fakeextractor.NamesErr{ 160 "some path": {nil, nil}, 161 }), 162 args: args{t.Context(), &filesystem.ScanInput{Path: "some path"}}, 163 want: []*extractor.Package{}, 164 }, 165 { 166 name: "multiple_results", 167 extractor: fakeextractor.New("extractor name", 1, nil, map[string]fakeextractor.NamesErr{ 168 "some path": {[]string{name1, name2}, nil}, 169 }), 170 args: args{t.Context(), &filesystem.ScanInput{Path: "some path"}}, 171 want: multiplePackages, 172 }, 173 { 174 name: "unrecognized_path_throws_an_error", 175 extractor: fakeextractor.New("", 1, nil, map[string]fakeextractor.NamesErr{ 176 "some path": {nil, nil}, 177 }), 178 args: args{t.Context(), &filesystem.ScanInput{Path: "another path"}}, 179 wantErr: cmpopts.AnyError, 180 }, 181 } 182 183 for _, test := range tests { 184 t.Run(test.name, func(t *testing.T) { 185 got, err := test.extractor.Extract(test.args.ctx, test.args.input) 186 if !cmp.Equal(err, test.wantErr, cmpopts.EquateErrors()) { 187 t.Fatalf("extractor.Extract(%v, %+v) got error: %v, want: %v\n", test.args.ctx, test.args.input, err, test.wantErr) 188 } 189 wantInv := inventory.Inventory{Packages: test.want} 190 if diff := cmp.Diff(wantInv, got); diff != "" { 191 t.Fatalf("extractor.Extract(%v, %+v) returned unexpected result; diff (-want +got):\n%s", test.args.ctx, test.args.input, diff) 192 } 193 }) 194 } 195 }