github.com/google/osv-scalibr@v0.4.1/extractor/filesystem/os/macports/macports_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 macports_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"
    24  	"github.com/google/osv-scalibr/extractor/filesystem/os/macports"
    25  	macportsmeta "github.com/google/osv-scalibr/extractor/filesystem/os/macports/metadata"
    26  	"github.com/google/osv-scalibr/extractor/filesystem/simplefileapi"
    27  	"github.com/google/osv-scalibr/inventory"
    28  	"github.com/google/osv-scalibr/purl"
    29  )
    30  
    31  func TestFileRequired(t *testing.T) {
    32  	tests := []struct {
    33  		name         string
    34  		path         string
    35  		wantRequired bool
    36  	}{
    37  		{
    38  			name:         "valid portfile",
    39  			path:         "/opt/local/var/macports/registry/portfiles/libtool-2.5.4_0/ad1db8600defd0eb7646fd461154434ec33014e5b04be396c9a40b0ce9171299-2968/Portfile",
    40  			wantRequired: true,
    41  		},
    42  		{
    43  			name:         "invalid portfile folder on version",
    44  			path:         "/opt/local/var/macports/registry/portfiles/autoconf-0/1f197df6a061a6661dd5b6292a0e88d6b31d81b6927563a17530cbab5706723c-2566/Portfile",
    45  			wantRequired: false,
    46  		},
    47  		{
    48  			name:         "invalid portfile folder on revision",
    49  			path:         "/opt/local/var/macports/registry/portfiles/freetype-2.13.3/801278d1d6f986fb9d249bf7320528c70d057280593ff462a9f425a58d9f269c-4310/Portfile",
    50  			wantRequired: false,
    51  		},
    52  		{
    53  			name:         "invalid portfile folder on sha256 hash",
    54  			path:         "/opt/local/var/macports/registry/portfiles/brotli-1.1.0_0/23-2335/Portfile",
    55  			wantRequired: false,
    56  		},
    57  		{
    58  			name:         "invalid portfile folder on index",
    59  			path:         "/opt/local/var/macports/registry/portfiles/gmp-6.3.0_0/8ae36d8bcd724fe086917092efbde6a5d50b0401381fa67a45978c92fb042b96/Portfile",
    60  			wantRequired: false,
    61  		},
    62  		{
    63  			name:         "invalid portfile name",
    64  			path:         "/opt/local/var/macports/registry/portfiles/pango-1.55.0_0/b333af837d8e7245cf81b35c1b9ef384cc327b85a48f5ce7eaa72110103eff8a-5916/PortfileXXX",
    65  			wantRequired: false,
    66  		},
    67  		{
    68  			name:         "invalid folder path",
    69  			path:         "/opt/local/var/macports/registry/portfile/x/y",
    70  			wantRequired: false,
    71  		},
    72  		{
    73  			name:         "invalid folder path",
    74  			path:         "/opt/local/var/macports/registry/portfiles_dummy/pango-1.55.0_0/2323-5916/Portfile",
    75  			wantRequired: false,
    76  		},
    77  	}
    78  
    79  	for _, tt := range tests {
    80  		t.Run(tt.name, func(t *testing.T) {
    81  			var e filesystem.Extractor = macports.Extractor{}
    82  			if got := e.FileRequired(simplefileapi.New(tt.path, nil)); got != tt.wantRequired {
    83  				t.Fatalf("FileRequired(%s): got %v, want %v", tt.path, got, tt.wantRequired)
    84  			}
    85  		})
    86  	}
    87  }
    88  
    89  func pkgLess(i1, i2 *extractor.Package) bool {
    90  	return i1.Name < i2.Name
    91  }
    92  
    93  func TestExtract(t *testing.T) {
    94  	tests := []struct {
    95  		name         string
    96  		path         string
    97  		wantPackages []*extractor.Package
    98  		wantErr      error
    99  	}{
   100  		{
   101  			name: "valid_portfile_path",
   102  			path: "/opt/local/var/macports/registry/portfiles/libtool-2.5.4_0/ad1db8600defd0eb7646fd461154434ec33014e5b04be396c9a40b0ce9171299-2968/Portfile",
   103  			wantPackages: []*extractor.Package{
   104  				{
   105  					Name:     "libtool",
   106  					Version:  "2.5.4",
   107  					PURLType: purl.TypeMacports,
   108  					Metadata: &macportsmeta.Metadata{
   109  						PackageName:     "libtool",
   110  						PackageVersion:  "2.5.4",
   111  						PackageRevision: "0",
   112  					},
   113  					Locations: []string{"/opt/local/var/macports/registry/portfiles/libtool-2.5.4_0/ad1db8600defd0eb7646fd461154434ec33014e5b04be396c9a40b0ce9171299-2968/Portfile"},
   114  				},
   115  			},
   116  		},
   117  		{
   118  			name: "valid_portfile_path_with_a_dash_in_it",
   119  			path: "/opt/local/var/macports/registry/portfiles/gobject-introspection-1.78.1_5/c55084712bbb40ccf96cbfb8f1c1c77c670a37e189f4accb8ada691aea18d1ef-1331/Portfile",
   120  			wantPackages: []*extractor.Package{
   121  				{
   122  					Name:     "gobject-introspection",
   123  					Version:  "1.78.1",
   124  					PURLType: purl.TypeMacports,
   125  					Metadata: &macportsmeta.Metadata{
   126  						PackageName:     "gobject-introspection",
   127  						PackageVersion:  "1.78.1",
   128  						PackageRevision: "5",
   129  					},
   130  					Locations: []string{"/opt/local/var/macports/registry/portfiles/gobject-introspection-1.78.1_5/c55084712bbb40ccf96cbfb8f1c1c77c670a37e189f4accb8ada691aea18d1ef-1331/Portfile"},
   131  				},
   132  			},
   133  		},
   134  		{
   135  			name: "valid_portfile_path_with_two_dashes_in_it",
   136  			path: "/opt/local/var/macports/registry/portfiles/xorg-xcb-proto-1.17.0_0/9846ecdbb454aa6ef08a26553a3667b63a6f46abfdb73ffaec2700e6473074df-2685/Portfile",
   137  			wantPackages: []*extractor.Package{
   138  				{
   139  					Name:     "xorg-xcb-proto",
   140  					Version:  "1.17.0",
   141  					PURLType: purl.TypeMacports,
   142  					Metadata: &macportsmeta.Metadata{
   143  						PackageName:     "xorg-xcb-proto",
   144  						PackageVersion:  "1.17.0",
   145  						PackageRevision: "0",
   146  					},
   147  					Locations: []string{"/opt/local/var/macports/registry/portfiles/xorg-xcb-proto-1.17.0_0/9846ecdbb454aa6ef08a26553a3667b63a6f46abfdb73ffaec2700e6473074df-2685/Portfile"},
   148  				},
   149  			},
   150  		},
   151  		{
   152  			name: "valid_portfile_path_with_number_in_the_package_name",
   153  			path: "/opt/local/var/macports/registry/portfiles/gd2-2.3.3_7/6c29fb21ddd646407e905e6b8b9a2c70cf00b3dea10609043f6b188fa7e30a1b-3596/Portfile",
   154  			wantPackages: []*extractor.Package{
   155  				{
   156  					Name:     "gd2",
   157  					Version:  "2.3.3",
   158  					PURLType: purl.TypeMacports,
   159  					Metadata: &macportsmeta.Metadata{
   160  						PackageName:     "gd2",
   161  						PackageVersion:  "2.3.3",
   162  						PackageRevision: "7",
   163  					},
   164  					Locations: []string{"/opt/local/var/macports/registry/portfiles/gd2-2.3.3_7/6c29fb21ddd646407e905e6b8b9a2c70cf00b3dea10609043f6b188fa7e30a1b-3596/Portfile"},
   165  				},
   166  			},
   167  		},
   168  		{
   169  			name: "valid_portfile_path_with_text_in_the_version_part",
   170  			path: "/opt/local/var/macports/registry/portfiles/urw-fonts-1.0.7pre44_0/07082b6c0b422e34867886e9af30145d0ffaf7e8586705677a9906c1fd8a314f-1753/Portfile",
   171  			wantPackages: []*extractor.Package{
   172  				{
   173  					Name:     "urw-fonts",
   174  					Version:  "1.0.7pre44",
   175  					PURLType: purl.TypeMacports,
   176  					Metadata: &macportsmeta.Metadata{
   177  						PackageName:     "urw-fonts",
   178  						PackageVersion:  "1.0.7pre44",
   179  						PackageRevision: "0",
   180  					},
   181  					Locations: []string{"/opt/local/var/macports/registry/portfiles/urw-fonts-1.0.7pre44_0/07082b6c0b422e34867886e9af30145d0ffaf7e8586705677a9906c1fd8a314f-1753/Portfile"},
   182  				},
   183  			},
   184  		},
   185  		{
   186  			name:         "invalid path",
   187  			path:         "/tmp/var/scalibr",
   188  			wantPackages: nil,
   189  		},
   190  	}
   191  
   192  	for _, tt := range tests {
   193  		t.Run(tt.name, func(t *testing.T) {
   194  			var e filesystem.Extractor = macports.Extractor{}
   195  			input := &filesystem.ScanInput{Path: tt.path, Reader: nil}
   196  			got, err := e.Extract(t.Context(), input)
   197  			if diff := cmp.Diff(tt.wantErr, err, cmpopts.EquateErrors()); diff != "" {
   198  				t.Errorf("Extract(%s) unexpected error (-want +got):\n%s", tt.path, diff)
   199  			}
   200  
   201  			want := inventory.Inventory{Packages: tt.wantPackages}
   202  
   203  			if diff := cmp.Diff(want, got, cmpopts.SortSlices(pkgLess)); diff != "" {
   204  				t.Errorf("Extract(%s) (-want +got):\n%s", tt.path, diff)
   205  			}
   206  		})
   207  	}
   208  }