github.com/google/osv-scalibr@v0.4.1/extractor/filesystem/language/rust/cargolock/cargolock_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 cargolock_test 16 17 import ( 18 "testing" 19 20 "github.com/google/go-cmp/cmp" 21 "github.com/google/go-cmp/cmp/cmpopts" 22 23 "github.com/google/osv-scalibr/extractor" 24 "github.com/google/osv-scalibr/extractor/filesystem/language/rust/cargolock" 25 "github.com/google/osv-scalibr/extractor/filesystem/simplefileapi" 26 "github.com/google/osv-scalibr/inventory" 27 "github.com/google/osv-scalibr/purl" 28 "github.com/google/osv-scalibr/testing/extracttest" 29 ) 30 31 func TestExtractor_FileRequired(t *testing.T) { 32 tests := []struct { 33 name string 34 inputPath string 35 want bool 36 }{ 37 { 38 name: "Empty path", 39 inputPath: "", 40 want: false, 41 }, 42 { 43 name: "", 44 inputPath: "Cargo.lock", 45 want: true, 46 }, 47 { 48 name: "", 49 inputPath: "path/to/my/Cargo.lock", 50 want: true, 51 }, 52 { 53 name: "", 54 inputPath: "path/to/my/Cargo.lock/file", 55 want: false, 56 }, 57 { 58 name: "", 59 inputPath: "path/to/my/Cargo.lock.file", 60 want: false, 61 }, 62 { 63 name: "", 64 inputPath: "path.to.my.Cargo.lock", 65 want: false, 66 }, 67 } 68 69 for _, tt := range tests { 70 t.Run(tt.name, func(t *testing.T) { 71 e := cargolock.Extractor{} 72 got := e.FileRequired(simplefileapi.New(tt.inputPath, nil)) 73 if got != tt.want { 74 t.Errorf("FileRequired(%s, FileInfo) got = %v, want %v", tt.inputPath, got, tt.want) 75 } 76 }) 77 } 78 } 79 80 func TestExtractor_Extract(t *testing.T) { 81 tests := []extracttest.TestTableEntry{ 82 { 83 Name: "Invalid toml", 84 InputConfig: extracttest.ScanInputMockConfig{ 85 Path: "testdata/not-toml.txt", 86 }, 87 WantPackages: nil, 88 WantErr: extracttest.ContainsErrStr{Str: "could not extract"}, 89 }, 90 { 91 Name: "no packages", 92 InputConfig: extracttest.ScanInputMockConfig{ 93 Path: "testdata/empty.lock", 94 }, 95 WantPackages: []*extractor.Package{}, 96 }, 97 { 98 Name: "one package", 99 InputConfig: extracttest.ScanInputMockConfig{ 100 Path: "testdata/one-package.lock", 101 }, 102 WantPackages: []*extractor.Package{ 103 { 104 Name: "addr2line", 105 Version: "0.15.2", 106 PURLType: purl.TypeCargo, 107 Locations: []string{"testdata/one-package.lock"}, 108 }, 109 }, 110 }, 111 { 112 Name: "two packages", 113 InputConfig: extracttest.ScanInputMockConfig{ 114 Path: "testdata/two-packages.lock", 115 }, 116 WantPackages: []*extractor.Package{ 117 { 118 Name: "addr2line", 119 Version: "0.15.2", 120 PURLType: purl.TypeCargo, 121 Locations: []string{"testdata/two-packages.lock"}, 122 }, 123 { 124 Name: "syn", 125 Version: "1.0.73", 126 PURLType: purl.TypeCargo, 127 Locations: []string{"testdata/two-packages.lock"}, 128 }, 129 }, 130 }, 131 { 132 Name: "two packages with local", 133 InputConfig: extracttest.ScanInputMockConfig{ 134 Path: "testdata/two-packages-with-local.lock", 135 }, 136 WantPackages: []*extractor.Package{ 137 { 138 Name: "addr2line", 139 Version: "0.15.2", 140 PURLType: purl.TypeCargo, 141 Locations: []string{"testdata/two-packages-with-local.lock"}, 142 }, 143 { 144 Name: "local-rust-pkg", 145 Version: "0.1.0", 146 PURLType: purl.TypeCargo, 147 Locations: []string{"testdata/two-packages-with-local.lock"}, 148 }, 149 }, 150 }, 151 { 152 Name: "package with build string", 153 InputConfig: extracttest.ScanInputMockConfig{ 154 Path: "testdata/package-with-build-string.lock", 155 }, 156 WantPackages: []*extractor.Package{ 157 { 158 Name: "wasi", 159 Version: "0.10.2+wasi-snapshot-preview1", 160 PURLType: purl.TypeCargo, 161 Locations: []string{"testdata/package-with-build-string.lock"}, 162 }, 163 }, 164 }, 165 } 166 for _, tt := range tests { 167 t.Run(tt.Name, func(t *testing.T) { 168 extr := cargolock.Extractor{} 169 170 scanInput := extracttest.GenerateScanInputMock(t, tt.InputConfig) 171 defer extracttest.CloseTestScanInput(t, scanInput) 172 173 got, err := extr.Extract(t.Context(), &scanInput) 174 175 if diff := cmp.Diff(tt.WantErr, err, cmpopts.EquateErrors()); diff != "" { 176 t.Errorf("%s.Extract(%q) error diff (-want +got):\n%s", extr.Name(), tt.InputConfig.Path, diff) 177 return 178 } 179 180 wantInv := inventory.Inventory{Packages: tt.WantPackages} 181 if diff := cmp.Diff(wantInv, got, cmpopts.SortSlices(extracttest.PackageCmpLess)); diff != "" { 182 t.Errorf("%s.Extract(%q) diff (-want +got):\n%s", extr.Name(), tt.InputConfig.Path, diff) 183 } 184 }) 185 } 186 }