github.com/google/osv-scalibr@v0.4.1/extractor/convert_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 extractor_test 16 17 import ( 18 "testing" 19 20 "github.com/google/go-cmp/cmp" 21 "github.com/google/osv-scalibr/extractor" 22 javascriptmeta "github.com/google/osv-scalibr/extractor/filesystem/language/javascript/packagejson/metadata" 23 dpkgmeta "github.com/google/osv-scalibr/extractor/filesystem/os/dpkg/metadata" 24 cdxmeta "github.com/google/osv-scalibr/extractor/filesystem/sbom/cdx/metadata" 25 spdxmeta "github.com/google/osv-scalibr/extractor/filesystem/sbom/spdx/metadata" 26 "github.com/google/osv-scalibr/inventory/osvecosystem" 27 "github.com/google/osv-scalibr/purl" 28 "github.com/ossf/osv-schema/bindings/go/osvconstants" 29 ) 30 31 func TestToPURL(t *testing.T) { 32 tests := []struct { 33 name string 34 pkg *extractor.Package 35 want *purl.PackageURL 36 }{ 37 { 38 name: "no_purl_type", 39 pkg: &extractor.Package{ 40 Name: "name", 41 Version: "version", 42 }, 43 want: nil, 44 }, 45 { 46 name: "simple_purl", 47 pkg: &extractor.Package{ 48 Name: "name", 49 Version: "version", 50 PURLType: purl.TypeGolang, 51 }, 52 want: &purl.PackageURL{ 53 Type: purl.TypeGolang, 54 Name: "name", 55 Version: "version", 56 }, 57 }, 58 { 59 name: "python_purl", 60 pkg: &extractor.Package{ 61 Name: "Name", 62 Version: "1.2.3", 63 PURLType: purl.TypePyPi, 64 Locations: []string{"location"}, 65 }, 66 want: &purl.PackageURL{ 67 Type: purl.TypePyPi, 68 Name: "name", 69 Version: "1.2.3", 70 }, 71 }, 72 { 73 name: "npm_purl", 74 pkg: &extractor.Package{ 75 Name: "Name", 76 Version: "1.2.3", 77 PURLType: purl.TypeNPM, 78 Locations: []string{"location"}, 79 Metadata: &javascriptmeta.JavascriptPackageJSONMetadata{ 80 Source: javascriptmeta.Unknown, 81 }, 82 }, 83 want: &purl.PackageURL{ 84 Type: purl.TypeNPM, 85 Name: "Name", 86 Version: "1.2.3", 87 }, 88 }, 89 { 90 name: "hex_purl", 91 pkg: &extractor.Package{ 92 Name: "Name", 93 Version: "1.2.3", 94 PURLType: purl.TypeHex, 95 Locations: []string{"location"}, 96 }, 97 want: &purl.PackageURL{ 98 Type: purl.TypeHex, 99 Name: "name", 100 Version: "1.2.3", 101 }, 102 }, 103 { 104 name: "spdx_purl", 105 pkg: &extractor.Package{ 106 Name: "name", 107 PURLType: purl.TypePyPi, 108 Metadata: &spdxmeta.Metadata{ 109 PURL: &purl.PackageURL{ 110 Type: purl.TypePyPi, 111 Name: "name", 112 Namespace: "namespace", 113 Version: "1.2.3", 114 }, 115 CPEs: []string{}, 116 }, 117 Locations: []string{"location"}, 118 }, 119 want: &purl.PackageURL{ 120 Type: purl.TypePyPi, 121 Name: "name", 122 Namespace: "namespace", 123 Version: "1.2.3", 124 }, 125 }, 126 { 127 name: "cdx_purl", 128 pkg: &extractor.Package{ 129 Name: "name", 130 PURLType: purl.TypeCargo, 131 Metadata: &cdxmeta.Metadata{ 132 PURL: &purl.PackageURL{ 133 Type: purl.TypeCargo, 134 Name: "name", 135 Namespace: "namespace", 136 Version: "1.2.3", 137 }, 138 CPEs: []string{}, 139 }, 140 Locations: []string{"location"}, 141 }, 142 want: &purl.PackageURL{ 143 Type: purl.TypeCargo, 144 Name: "name", 145 Namespace: "namespace", 146 Version: "1.2.3", 147 }, 148 }, 149 { 150 name: "dpkg_purl", 151 pkg: &extractor.Package{ 152 Name: "Name", 153 Version: "1.2.3", 154 PURLType: purl.TypeDebian, 155 Metadata: &dpkgmeta.Metadata{ 156 PackageName: "pkg-name", 157 OSVersionCodename: "jammy", 158 }, 159 Locations: []string{"location"}, 160 }, 161 want: &purl.PackageURL{ 162 Type: purl.TypeDebian, 163 Namespace: "linux", 164 Name: "pkg-name", 165 Version: "1.2.3", 166 Qualifiers: purl.QualifiersFromMap(map[string]string{ 167 purl.Distro: "jammy", 168 }), 169 }, 170 }, 171 { 172 name: "opkg_purl", 173 pkg: &extractor.Package{ 174 Name: "Name", 175 Version: "1.2.3", 176 PURLType: purl.TypeOpkg, 177 Metadata: &dpkgmeta.Metadata{ 178 PackageName: "pkg-name", 179 OSVersionCodename: "jammy", 180 }, 181 Locations: []string{"location"}, 182 }, 183 want: &purl.PackageURL{ 184 Type: purl.TypeOpkg, 185 Namespace: "linux", 186 Name: "pkg-name", 187 Version: "1.2.3", 188 Qualifiers: purl.QualifiersFromMap(map[string]string{ 189 purl.Distro: "jammy", 190 }), 191 }, 192 }, 193 } 194 195 for _, tt := range tests { 196 t.Run(tt.name, func(t *testing.T) { 197 got := tt.pkg.PURL() 198 if diff := cmp.Diff(tt.want, got); diff != "" { 199 t.Errorf("%v.PURL(): unexpected PURL (-want +got):\n%s", tt.pkg, diff) 200 } 201 }) 202 } 203 } 204 205 func TestToEcosystem(t *testing.T) { 206 tests := []struct { 207 name string 208 pkg *extractor.Package 209 want osvecosystem.Parsed 210 }{ 211 { 212 name: "no_purl_type", 213 pkg: &extractor.Package{ 214 Name: "name", 215 Version: "version", 216 }, 217 want: osvecosystem.Parsed{}, 218 }, 219 { 220 name: "simple_ecosystem", 221 pkg: &extractor.Package{ 222 Name: "name", 223 Version: "version", 224 PURLType: purl.TypeGolang, 225 }, 226 want: osvecosystem.FromEcosystem(osvconstants.EcosystemGo), 227 }, 228 { 229 name: "os_ecosystem", 230 pkg: &extractor.Package{ 231 Name: "Name", 232 Version: "1.2.3", 233 PURLType: purl.TypeDebian, 234 Metadata: &dpkgmeta.Metadata{ 235 PackageName: "pkg-name", 236 OSVersionCodename: "jammy", 237 OSVersionID: "11", 238 OSID: "debian", 239 }, 240 }, 241 want: osvecosystem.Parsed{ 242 Ecosystem: osvconstants.EcosystemDebian, 243 Suffix: "11", 244 }, 245 }, 246 } 247 248 for _, tt := range tests { 249 t.Run(tt.name, func(t *testing.T) { 250 got := tt.pkg.Ecosystem() 251 if got != tt.want { 252 t.Errorf("%v.Ecosystem(): got %q, want %q", tt.pkg, got, tt.want) 253 } 254 }) 255 } 256 }