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 }