github.com/google/osv-scalibr@v0.4.1/extractor/filesystem/language/erlang/mixlock/mixlock_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 mixlock_test 16 17 import ( 18 "testing" 19 20 "github.com/google/go-cmp/cmp" 21 "github.com/google/go-cmp/cmp/cmpopts" 22 "github.com/google/osv-scalibr/extractor" 23 "github.com/google/osv-scalibr/extractor/filesystem/language/erlang/mixlock" 24 "github.com/google/osv-scalibr/extractor/filesystem/simplefileapi" 25 "github.com/google/osv-scalibr/inventory" 26 "github.com/google/osv-scalibr/purl" 27 "github.com/google/osv-scalibr/testing/extracttest" 28 ) 29 30 func TestExtractor_FileRequired(t *testing.T) { 31 tests := []struct { 32 name string 33 inputPath string 34 want bool 35 }{ 36 { 37 inputPath: "", 38 want: false, 39 }, 40 { 41 inputPath: "mix.lock", 42 want: true, 43 }, 44 { 45 inputPath: "path/to/my/mix.lock", 46 want: true, 47 }, 48 { 49 inputPath: "path/to/my/mix.lock/file", 50 want: false, 51 }, 52 { 53 inputPath: "path/to/my/mix.lock.file", 54 want: false, 55 }, 56 { 57 inputPath: "path.to.my.mix.lock", 58 want: false, 59 }, 60 } 61 for _, tt := range tests { 62 t.Run(tt.inputPath, func(t *testing.T) { 63 e := mixlock.Extractor{} 64 got := e.FileRequired(simplefileapi.New(tt.inputPath, nil)) 65 if got != tt.want { 66 t.Errorf("FileRequired(%s, FileInfo) got = %v, want %v", tt.inputPath, got, tt.want) 67 } 68 }) 69 } 70 } 71 72 func TestExtractor_Extract(t *testing.T) { 73 tests := []extracttest.TestTableEntry{ 74 { 75 Name: "no packages", 76 InputConfig: extracttest.ScanInputMockConfig{ 77 Path: "testdata/empty.lock", 78 }, 79 WantPackages: []*extractor.Package{}, 80 }, 81 { 82 Name: "one package", 83 InputConfig: extracttest.ScanInputMockConfig{ 84 Path: "testdata/one-package.lock", 85 }, 86 WantPackages: []*extractor.Package{ 87 { 88 Name: "plug", 89 Version: "1.11.1", 90 PURLType: purl.TypeHex, 91 Locations: []string{"testdata/one-package.lock"}, 92 SourceCode: &extractor.SourceCodeIdentifier{ 93 Commit: "f2992bac66fdae679453c9e86134a4201f6f43a687d8ff1cd1b2862d53c80259", 94 }, 95 }, 96 }, 97 }, 98 { 99 Name: "two packages", 100 InputConfig: extracttest.ScanInputMockConfig{ 101 Path: "testdata/two-packages.lock", 102 }, 103 WantPackages: []*extractor.Package{ 104 { 105 Name: "plug", 106 Version: "1.11.1", 107 PURLType: purl.TypeHex, 108 Locations: []string{"testdata/two-packages.lock"}, 109 SourceCode: &extractor.SourceCodeIdentifier{ 110 Commit: "f2992bac66fdae679453c9e86134a4201f6f43a687d8ff1cd1b2862d53c80259", 111 }, 112 }, 113 { 114 Name: "plug_crypto", 115 Version: "1.2.2", 116 PURLType: purl.TypeHex, 117 Locations: []string{"testdata/two-packages.lock"}, 118 SourceCode: &extractor.SourceCodeIdentifier{ 119 Commit: "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", 120 }, 121 }, 122 }, 123 }, 124 { 125 Name: "many", 126 InputConfig: extracttest.ScanInputMockConfig{ 127 Path: "testdata/many.lock", 128 }, 129 WantPackages: []*extractor.Package{ 130 { 131 Name: "backoff", 132 Version: "1.1.6", 133 PURLType: purl.TypeHex, 134 Locations: []string{"testdata/many.lock"}, 135 SourceCode: &extractor.SourceCodeIdentifier{ 136 Commit: "83b72ed2108ba1ee8f7d1c22e0b4a00cfe3593a67dbc792799e8cce9f42f796b", 137 }, 138 }, 139 { 140 Name: "decimal", 141 Version: "2.0.0", 142 PURLType: purl.TypeHex, 143 Locations: []string{"testdata/many.lock"}, 144 SourceCode: &extractor.SourceCodeIdentifier{ 145 Commit: "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", 146 }, 147 }, 148 { 149 Name: "dialyxir", 150 Version: "1.1.0", 151 PURLType: purl.TypeHex, 152 Locations: []string{"testdata/many.lock"}, 153 SourceCode: &extractor.SourceCodeIdentifier{ 154 Commit: "c5aab0d6e71e5522e77beff7ba9e08f8e02bad90dfbeffae60eaf0cb47e29488", 155 }, 156 }, 157 { 158 Name: "earmark", 159 Version: "1.4.3", 160 PURLType: purl.TypeHex, 161 Locations: []string{"testdata/many.lock"}, 162 SourceCode: &extractor.SourceCodeIdentifier{ 163 Commit: "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", 164 }, 165 }, 166 { 167 Name: "earmark_parser", 168 Version: "1.4.10", 169 PURLType: purl.TypeHex, 170 Locations: []string{"testdata/many.lock"}, 171 SourceCode: &extractor.SourceCodeIdentifier{ 172 Commit: "6603d7a603b9c18d3d20db69921527f82ef09990885ed7525003c7fe7dc86c56", 173 }, 174 }, 175 { 176 Name: "ecto", 177 Version: "3.5.5", 178 PURLType: purl.TypeHex, 179 Locations: []string{"testdata/many.lock"}, 180 SourceCode: &extractor.SourceCodeIdentifier{ 181 Commit: "48219a991bb86daba6e38a1e64f8cea540cded58950ff38fbc8163e062281a07", 182 }, 183 }, 184 { 185 Name: "erlex", 186 Version: "0.2.6", 187 PURLType: purl.TypeHex, 188 Locations: []string{"testdata/many.lock"}, 189 SourceCode: &extractor.SourceCodeIdentifier{ 190 Commit: "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", 191 }, 192 }, 193 { 194 Name: "ex_doc", 195 Version: "0.23.0", 196 PURLType: purl.TypeHex, 197 Locations: []string{"testdata/many.lock"}, 198 SourceCode: &extractor.SourceCodeIdentifier{ 199 Commit: "a069bc9b0bf8efe323ecde8c0d62afc13d308b1fa3d228b65bca5cf8703a529d", 200 }, 201 }, 202 { 203 Name: "makeup", 204 Version: "1.0.5", 205 PURLType: purl.TypeHex, 206 Locations: []string{"testdata/many.lock"}, 207 SourceCode: &extractor.SourceCodeIdentifier{ 208 Commit: "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", 209 }, 210 }, 211 { 212 Name: "makeup_elixir", 213 Version: "0.15.0", 214 PURLType: purl.TypeHex, 215 Locations: []string{"testdata/many.lock"}, 216 SourceCode: &extractor.SourceCodeIdentifier{ 217 Commit: "98312c9f0d3730fde4049985a1105da5155bfe5c11e47bdc7406d88e01e4219b", 218 }, 219 }, 220 { 221 Name: "meck", 222 Version: "0.9.2", 223 PURLType: purl.TypeHex, 224 Locations: []string{"testdata/many.lock"}, 225 SourceCode: &extractor.SourceCodeIdentifier{ 226 Commit: "85ccbab053f1db86c7ca240e9fc718170ee5bda03810a6292b5306bf31bae5f5", 227 }, 228 }, 229 { 230 Name: "mime", 231 Version: "1.5.0", 232 PURLType: purl.TypeHex, 233 Locations: []string{"testdata/many.lock"}, 234 SourceCode: &extractor.SourceCodeIdentifier{ 235 Commit: "203ef35ef3389aae6d361918bf3f952fa17a09e8e43b5aa592b93eba05d0fb8d", 236 }, 237 }, 238 { 239 Name: "nimble_parsec", 240 Version: "1.1.0", 241 PURLType: purl.TypeHex, 242 Locations: []string{"testdata/many.lock"}, 243 SourceCode: &extractor.SourceCodeIdentifier{ 244 Commit: "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", 245 }, 246 }, 247 { 248 Name: "phoenix", 249 Version: "1.4.17", 250 PURLType: purl.TypeHex, 251 Locations: []string{"testdata/many.lock"}, 252 SourceCode: &extractor.SourceCodeIdentifier{ 253 Commit: "1b1bd4cff7cfc87c94deaa7d60dd8c22e04368ab95499483c50640ef3bd838d8", 254 }, 255 }, 256 { 257 Name: "phoenix_html", 258 Version: "2.14.3", 259 PURLType: purl.TypeHex, 260 Locations: []string{"testdata/many.lock"}, 261 SourceCode: &extractor.SourceCodeIdentifier{ 262 Commit: "51f720d0d543e4e157ff06b65de38e13303d5778a7919bcc696599e5934271b8", 263 }, 264 }, 265 { 266 Name: "phoenix_pubsub", 267 Version: "1.1.2", 268 PURLType: purl.TypeHex, 269 Locations: []string{"testdata/many.lock"}, 270 SourceCode: &extractor.SourceCodeIdentifier{ 271 Commit: "496c303bdf1b2e98a9d26e89af5bba3ab487ba3a3735f74bf1f4064d2a845a3e", 272 }, 273 }, 274 { 275 Name: "plug", 276 Version: "1.11.1", 277 PURLType: purl.TypeHex, 278 Locations: []string{"testdata/many.lock"}, 279 SourceCode: &extractor.SourceCodeIdentifier{ 280 Commit: "f2992bac66fdae679453c9e86134a4201f6f43a687d8ff1cd1b2862d53c80259", 281 }, 282 }, 283 { 284 Name: "plug_crypto", 285 Version: "1.2.2", 286 PURLType: purl.TypeHex, 287 Locations: []string{"testdata/many.lock"}, 288 SourceCode: &extractor.SourceCodeIdentifier{ 289 Commit: "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", 290 }, 291 }, 292 { 293 Name: "poolboy", 294 Version: "1.5.2", 295 PURLType: purl.TypeHex, 296 Locations: []string{"testdata/many.lock"}, 297 SourceCode: &extractor.SourceCodeIdentifier{ 298 Commit: "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", 299 }, 300 }, 301 { 302 Name: "pow", 303 Version: "1.0.15", 304 PURLType: purl.TypeHex, 305 Locations: []string{"testdata/many.lock"}, 306 SourceCode: &extractor.SourceCodeIdentifier{ 307 Commit: "9267b5c75df2d59968585c042e2a0ec6217b1959d3afd629817461f0a20e903c", 308 }, 309 }, 310 { 311 Name: "telemetry", 312 Version: "0.4.2", 313 PURLType: purl.TypeHex, 314 Locations: []string{"testdata/many.lock"}, 315 SourceCode: &extractor.SourceCodeIdentifier{ 316 Commit: "2808c992455e08d6177322f14d3bdb6b625fbcfd233a73505870d8738a2f4599", 317 }, 318 }, 319 }, 320 }, 321 { 322 Name: "git packages", 323 InputConfig: extracttest.ScanInputMockConfig{ 324 Path: "testdata/git.lock", 325 }, 326 WantPackages: []*extractor.Package{ 327 { 328 Name: "foe", 329 Version: "", 330 PURLType: purl.TypeHex, 331 Locations: []string{"testdata/git.lock"}, 332 SourceCode: &extractor.SourceCodeIdentifier{ 333 Commit: "a9574ab75d6ed01e1288c453ae1d943d7a964595", 334 }, 335 }, 336 { 337 Name: "foo", 338 Version: "", 339 PURLType: purl.TypeHex, 340 Locations: []string{"testdata/git.lock"}, 341 SourceCode: &extractor.SourceCodeIdentifier{ 342 Commit: "fc94cce7830fa4dc455024bc2a83720afe244531", 343 }, 344 }, 345 { 346 Name: "bar", 347 Version: "", 348 PURLType: purl.TypeHex, 349 Locations: []string{"testdata/git.lock"}, 350 SourceCode: &extractor.SourceCodeIdentifier{ 351 Commit: "bef3ee1d3618017061498b96c75043e8449ef9b5", 352 }, 353 }, 354 }, 355 }, 356 } 357 358 for _, tt := range tests { 359 t.Run(tt.Name, func(t *testing.T) { 360 extr := mixlock.Extractor{} 361 362 scanInput := extracttest.GenerateScanInputMock(t, tt.InputConfig) 363 defer extracttest.CloseTestScanInput(t, scanInput) 364 365 got, err := extr.Extract(t.Context(), &scanInput) 366 367 if diff := cmp.Diff(tt.WantErr, err, cmpopts.EquateErrors()); diff != "" { 368 t.Errorf("%s.Extract(%q) error diff (-want +got):\n%s", extr.Name(), tt.InputConfig.Path, diff) 369 return 370 } 371 372 wantInv := inventory.Inventory{Packages: tt.WantPackages} 373 if diff := cmp.Diff(wantInv, got, cmpopts.SortSlices(extracttest.PackageCmpLess)); diff != "" { 374 t.Errorf("%s.Extract(%q) diff (-want +got):\n%s", extr.Name(), tt.InputConfig.Path, diff) 375 } 376 }) 377 } 378 }