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  }