github.com/google/osv-scalibr@v0.4.1/extractor/filesystem/runtime/asdf/asdf_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 asdf_test
    16  
    17  import (
    18  	"io/fs"
    19  	"path/filepath"
    20  	"testing"
    21  
    22  	"github.com/google/go-cmp/cmp"
    23  	"github.com/google/go-cmp/cmp/cmpopts"
    24  	"github.com/google/osv-scalibr/extractor"
    25  	"github.com/google/osv-scalibr/extractor/filesystem"
    26  	"github.com/google/osv-scalibr/extractor/filesystem/runtime/asdf"
    27  	asdfmeta "github.com/google/osv-scalibr/extractor/filesystem/runtime/asdf/metadata"
    28  	"github.com/google/osv-scalibr/extractor/filesystem/simplefileapi"
    29  	"github.com/google/osv-scalibr/inventory"
    30  	"github.com/google/osv-scalibr/purl"
    31  	"github.com/google/osv-scalibr/testing/extracttest"
    32  	"github.com/google/osv-scalibr/testing/fakefs"
    33  )
    34  
    35  func TestFileRequired(t *testing.T) {
    36  	tests := []struct {
    37  		name         string
    38  		path         string
    39  		wantRequired bool
    40  	}{
    41  		{
    42  			name:         "invalid path",
    43  			path:         "/tmp/var/scalibr",
    44  			wantRequired: false,
    45  		},
    46  	}
    47  
    48  	for _, tt := range tests {
    49  		t.Run(tt.name, func(t *testing.T) {
    50  			var e filesystem.Extractor = asdf.Extractor{}
    51  			if got := e.FileRequired(simplefileapi.New(tt.path, fakefs.FakeFileInfo{
    52  				FileName: filepath.Base(tt.path),
    53  				FileMode: fs.ModePerm,
    54  				FileSize: 30 * 1024,
    55  			})); got != tt.wantRequired {
    56  				t.Fatalf("FileRequired(%s): got %v, want %v", tt.path, got, tt.wantRequired)
    57  			}
    58  		})
    59  	}
    60  }
    61  
    62  func TestExtract(t *testing.T) {
    63  	tests := []struct {
    64  		name            string
    65  		wantPackages    []*extractor.Package
    66  		inputConfigFile extracttest.ScanInputMockConfig
    67  	}{
    68  		{
    69  			name: "valid_.tool-versions_",
    70  			inputConfigFile: extracttest.ScanInputMockConfig{
    71  				Path: "testdata/simpleValid/.tool-versions",
    72  			},
    73  			wantPackages: []*extractor.Package{
    74  				{
    75  					Name:     "nodejs",
    76  					Version:  "24.04",
    77  					PURLType: purl.TypeAsdf,
    78  					Metadata: &asdfmeta.Metadata{
    79  						ToolName:    "nodejs",
    80  						ToolVersion: "24.04",
    81  					},
    82  					Locations: []string{"testdata/simpleValid/.tool-versions"},
    83  				},
    84  			},
    85  		}, {
    86  			name: "valid_.tool-versions_multiple_versions",
    87  			inputConfigFile: extracttest.ScanInputMockConfig{
    88  				Path: "testdata/validMultiVersions/.tool-versions",
    89  			},
    90  			wantPackages: []*extractor.Package{
    91  				{
    92  					Name:     "nodejs",
    93  					Version:  "24.04",
    94  					PURLType: purl.TypeAsdf,
    95  					Metadata: &asdfmeta.Metadata{
    96  						ToolName:    "nodejs",
    97  						ToolVersion: "24.04",
    98  					},
    99  					Locations: []string{"testdata/validMultiVersions/.tool-versions"},
   100  				}, {
   101  					Name:     "nodejs",
   102  					Version:  "21",
   103  					PURLType: purl.TypeAsdf,
   104  					Metadata: &asdfmeta.Metadata{
   105  						ToolName:    "nodejs",
   106  						ToolVersion: "21",
   107  					},
   108  					Locations: []string{"testdata/validMultiVersions/.tool-versions"},
   109  				}, {
   110  					Name:     "nodejs",
   111  					Version:  "19.0",
   112  					PURLType: purl.TypeAsdf,
   113  					Metadata: &asdfmeta.Metadata{
   114  						ToolName:    "nodejs",
   115  						ToolVersion: "19.0",
   116  					},
   117  					Locations: []string{"testdata/validMultiVersions/.tool-versions"},
   118  				},
   119  			},
   120  		}, {
   121  			name: "valid_.tool-versions_multiple_versions_with_skip_values",
   122  			inputConfigFile: extracttest.ScanInputMockConfig{
   123  				Path: "testdata/validMultiVersionWithSkip/.tool-versions",
   124  			},
   125  			wantPackages: []*extractor.Package{
   126  				{
   127  					Name:     "nodejs",
   128  					Version:  "24.04",
   129  					PURLType: purl.TypeAsdf,
   130  					Metadata: &asdfmeta.Metadata{
   131  						ToolName:    "nodejs",
   132  						ToolVersion: "24.04",
   133  					},
   134  					Locations: []string{"testdata/validMultiVersionWithSkip/.tool-versions"},
   135  				}, {
   136  					Name:     "nodejs",
   137  					Version:  "21",
   138  					PURLType: purl.TypeAsdf,
   139  					Metadata: &asdfmeta.Metadata{
   140  						ToolName:    "nodejs",
   141  						ToolVersion: "21",
   142  					},
   143  					Locations: []string{"testdata/validMultiVersionWithSkip/.tool-versions"},
   144  				}, {
   145  					Name:     "nodejs",
   146  					Version:  "19.0",
   147  					PURLType: purl.TypeAsdf,
   148  					Metadata: &asdfmeta.Metadata{
   149  						ToolName:    "nodejs",
   150  						ToolVersion: "19.0",
   151  					},
   152  					Locations: []string{"testdata/validMultiVersionWithSkip/.tool-versions"},
   153  				},
   154  			},
   155  		}, {
   156  			name: "valid_.tool-versions_multiple_lines",
   157  			inputConfigFile: extracttest.ScanInputMockConfig{
   158  				Path: "testdata/validMultiLine/.tool-versions",
   159  			},
   160  			wantPackages: []*extractor.Package{
   161  				{
   162  					Name:     "nodejs",
   163  					Version:  "24.04",
   164  					PURLType: purl.TypeAsdf,
   165  					Metadata: &asdfmeta.Metadata{
   166  						ToolName:    "nodejs",
   167  						ToolVersion: "24.04",
   168  					},
   169  					Locations: []string{"testdata/validMultiLine/.tool-versions"},
   170  				}, {
   171  					Name:     "nodejs",
   172  					Version:  "20.0",
   173  					PURLType: purl.TypeAsdf,
   174  					Metadata: &asdfmeta.Metadata{
   175  						ToolName:    "nodejs",
   176  						ToolVersion: "20.0",
   177  					},
   178  					Locations: []string{"testdata/validMultiLine/.tool-versions"},
   179  				},
   180  			},
   181  		}, {
   182  			name: "valid_.tool-versions_more_whitespaces",
   183  			inputConfigFile: extracttest.ScanInputMockConfig{
   184  				Path: "testdata/validWhiteSpaces/.tool-versions",
   185  			},
   186  			wantPackages: []*extractor.Package{
   187  				{
   188  					Name:     "nodejs",
   189  					Version:  "24.04",
   190  					PURLType: purl.TypeAsdf,
   191  					Metadata: &asdfmeta.Metadata{
   192  						ToolName:    "nodejs",
   193  						ToolVersion: "24.04",
   194  					},
   195  					Locations: []string{"testdata/validWhiteSpaces/.tool-versions"},
   196  				},
   197  			},
   198  		},
   199  		{
   200  			name: "invalid_.tool-versions_",
   201  			inputConfigFile: extracttest.ScanInputMockConfig{
   202  				Path: "testdata/invalid/.tool-versions",
   203  			},
   204  			wantPackages: nil,
   205  		},
   206  	}
   207  
   208  	for _, tt := range tests {
   209  		t.Run(tt.name, func(t *testing.T) {
   210  			extr := asdf.Extractor{}
   211  
   212  			scanInput := extracttest.GenerateScanInputMock(t, tt.inputConfigFile)
   213  			defer extracttest.CloseTestScanInput(t, scanInput)
   214  
   215  			got, _ := extr.Extract(t.Context(), &scanInput)
   216  
   217  			wantInv := inventory.Inventory{Packages: tt.wantPackages}
   218  			if diff := cmp.Diff(wantInv, got, cmpopts.SortSlices(extracttest.PackageCmpLess)); diff != "" {
   219  				t.Errorf("%s.Extract(%q) diff (-want +got):\n%s", extr.Name(), tt.inputConfigFile.Path, diff)
   220  			}
   221  		})
   222  	}
   223  }