github.com/lineaje-labs/syft@v0.98.1-0.20231227153149-9e393f60ff1b/syft/pkg/cataloger/alpine/package_test.go (about) 1 package alpine 2 3 import ( 4 "strings" 5 "testing" 6 7 "github.com/go-test/deep" 8 "github.com/sergi/go-diff/diffmatchpatch" 9 10 "github.com/anchore/packageurl-go" 11 "github.com/anchore/syft/syft/linux" 12 "github.com/anchore/syft/syft/pkg" 13 ) 14 15 func Test_PackageURL(t *testing.T) { 16 tests := []struct { 17 name string 18 metadata parsedData 19 distro linux.Release 20 expected string 21 }{ 22 { 23 name: "non-alpine distro", 24 metadata: parsedData{ 25 License: "", 26 ApkDBEntry: pkg.ApkDBEntry{ 27 Package: "p", 28 Version: "v", 29 Architecture: "a", 30 }, 31 }, 32 distro: linux.Release{ 33 ID: "something else", 34 VersionID: "3.4.6", 35 }, 36 expected: "pkg:apk/something%20else/p@v?arch=a&distro=something%20else-3.4.6", 37 }, 38 { 39 name: "gocase", 40 metadata: parsedData{ 41 License: "", 42 ApkDBEntry: pkg.ApkDBEntry{ 43 Package: "p", 44 Version: "v", 45 Architecture: "a", 46 }, 47 }, 48 distro: linux.Release{ 49 ID: "alpine", 50 VersionID: "3.4.6", 51 }, 52 expected: "pkg:apk/alpine/p@v?arch=a&distro=alpine-3.4.6", 53 }, 54 { 55 name: "missing architecture", 56 metadata: parsedData{ 57 License: "", 58 ApkDBEntry: pkg.ApkDBEntry{ 59 Package: "p", 60 Version: "v", 61 }, 62 }, 63 distro: linux.Release{ 64 ID: "alpine", 65 VersionID: "3.4.6", 66 }, 67 expected: "pkg:apk/alpine/p@v?distro=alpine-3.4.6", 68 }, 69 // verify #351 70 { 71 metadata: parsedData{ 72 License: "", 73 ApkDBEntry: pkg.ApkDBEntry{ 74 Package: "g++", 75 Version: "v84", 76 Architecture: "am86", 77 }, 78 }, 79 distro: linux.Release{ 80 ID: "alpine", 81 VersionID: "3.4.6", 82 }, 83 expected: "pkg:apk/alpine/g++@v84?arch=am86&distro=alpine-3.4.6", 84 }, 85 { 86 metadata: parsedData{ 87 License: "", 88 ApkDBEntry: pkg.ApkDBEntry{ 89 Package: "g plus plus", 90 Version: "v84", 91 Architecture: "am86", 92 }, 93 }, 94 distro: linux.Release{ 95 ID: "alpine", 96 VersionID: "3.15.0", 97 }, 98 expected: "pkg:apk/alpine/g%20plus%20plus@v84?arch=am86&distro=alpine-3.15.0", 99 }, 100 { 101 name: "add source information as qualifier", 102 metadata: parsedData{ 103 License: "", 104 ApkDBEntry: pkg.ApkDBEntry{ 105 Package: "p", 106 Version: "v", 107 Architecture: "a", 108 OriginPackage: "origin", 109 }, 110 }, 111 distro: linux.Release{ 112 ID: "alpine", 113 VersionID: "3.4.6", 114 }, 115 expected: "pkg:apk/alpine/p@v?arch=a&upstream=origin&distro=alpine-3.4.6", 116 }, 117 { 118 name: "wolfi distro", 119 metadata: parsedData{ 120 License: "", 121 ApkDBEntry: pkg.ApkDBEntry{ 122 Package: "p", 123 Version: "v", 124 Architecture: "a", 125 }, 126 }, 127 distro: linux.Release{ 128 ID: "wolfi", 129 VersionID: "20221230", 130 }, 131 expected: "pkg:apk/wolfi/p@v?arch=a&distro=wolfi-20221230", 132 }, 133 } 134 135 for _, test := range tests { 136 t.Run(test.name, func(t *testing.T) { 137 actual := packageURL(test.metadata.ApkDBEntry, &test.distro) 138 if actual != test.expected { 139 dmp := diffmatchpatch.New() 140 diffs := dmp.DiffMain(test.expected, actual, true) 141 t.Errorf("diff: %s", dmp.DiffPrettyText(diffs)) 142 } 143 144 if test.expected == "" { 145 return 146 } 147 148 // verify packageurl can parse 149 purl, err := packageurl.FromString(actual) 150 if err != nil { 151 t.Errorf("cannot re-parse purl: %s", actual) 152 } 153 if purl.Name != test.metadata.Package { 154 dmp := diffmatchpatch.New() 155 diffs := dmp.DiffMain(test.metadata.Package, purl.Name, true) 156 t.Errorf("invalid purl name: %s", dmp.DiffPrettyText(diffs)) 157 } 158 if purl.Version != test.metadata.Version { 159 dmp := diffmatchpatch.New() 160 diffs := dmp.DiffMain(test.metadata.Version, purl.Version, true) 161 t.Errorf("invalid purl version: %s", dmp.DiffPrettyText(diffs)) 162 } 163 if purl.Qualifiers.Map()["arch"] != test.metadata.Architecture { 164 dmp := diffmatchpatch.New() 165 diffs := dmp.DiffMain(test.metadata.Architecture, purl.Qualifiers.Map()["arch"], true) 166 t.Errorf("invalid purl architecture: %s", dmp.DiffPrettyText(diffs)) 167 } 168 }) 169 } 170 } 171 172 func TestApkMetadata_FileOwner(t *testing.T) { 173 tests := []struct { 174 metadata pkg.ApkDBEntry 175 expected []string 176 }{ 177 { 178 metadata: pkg.ApkDBEntry{ 179 Files: []pkg.ApkFileRecord{ 180 {Path: "/somewhere"}, 181 {Path: "/else"}, 182 }, 183 }, 184 expected: []string{ 185 "/else", 186 "/somewhere", 187 }, 188 }, 189 { 190 metadata: pkg.ApkDBEntry{ 191 Files: []pkg.ApkFileRecord{ 192 {Path: "/somewhere"}, 193 {Path: ""}, 194 }, 195 }, 196 expected: []string{ 197 "/somewhere", 198 }, 199 }, 200 } 201 202 for _, test := range tests { 203 t.Run(strings.Join(test.expected, ","), func(t *testing.T) { 204 actual := test.metadata.OwnedFiles() 205 for _, d := range deep.Equal(test.expected, actual) { 206 t.Errorf("diff: %+v", d) 207 } 208 }) 209 } 210 }