github.com/anchore/syft@v1.38.2/syft/pkg/cataloger/nix/cataloger_test.go (about) 1 package nix 2 3 import ( 4 "testing" 5 6 "github.com/google/go-cmp/cmp" 7 "github.com/scylladb/go-set/strset" 8 "github.com/stretchr/testify/assert" 9 "github.com/stretchr/testify/require" 10 _ "modernc.org/sqlite" 11 12 "github.com/anchore/syft/syft/artifact" 13 "github.com/anchore/syft/syft/file" 14 "github.com/anchore/syft/syft/pkg" 15 "github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest" 16 ) 17 18 func TestCataloger_Image(t *testing.T) { 19 tests := []struct { 20 fixture string 21 wantPkgs []string 22 wantRel []string 23 }{ 24 { 25 // $ nix-store -q --tree $(which jq) 26 // 27 // /nix/store/nzwfgsp28vgxv7n2gl5fxqkca9awh4dz-jq-1.6-bin3.4 28 // ├───/nix/store/02mqs1by2vab9yzw0qc4j7463w78p3ps-glibc-2.37-8 29 // │ ├───/nix/store/cw8fpl8r1x9rmaqj55fwbfnnrgw7b40k-libidn2-2.3.4 30 // │ │ ├───/nix/store/h1ysk4vvw48winwmh38rvnsj0dlsz7c1-libunistring-1.1 31 // │ │ │ └───/nix/store/h1ysk4vvw48winwmh38rvnsj0dlsz7c1-libunistring-1.1 [...] 32 // │ │ └───/nix/store/cw8fpl8r1x9rmaqj55fwbfnnrgw7b40k-libidn2-2.3.4 [...] 33 // │ ├───/nix/store/fmz62d844wf4blb11k21f4m0q6n6hdfp-xgcc-12.3.0-libgcc 34 // │ └───/nix/store/02mqs1by2vab9yzw0qc4j7463w78p3ps-glibc-2.37-8 [...] 35 // ├───/nix/store/mzj90j6m3c3a1vv8j9pl920f98i2yz9q-oniguruma-6.9.8-lib 36 // │ ├───/nix/store/02mqs1by2vab9yzw0qc4j7463w78p3ps-glibc-2.37-8 [...] 37 // │ └───/nix/store/mzj90j6m3c3a1vv8j9pl920f98i2yz9q-oniguruma-6.9.8-lib [...] 38 // └───/nix/store/1x3s2v9wc9m302cspfqcn2iwar0b5w99-jq-1.6-lib 39 // ├───/nix/store/02mqs1by2vab9yzw0qc4j7463w78p3ps-glibc-2.37-8 [...] 40 // ├───/nix/store/mzj90j6m3c3a1vv8j9pl920f98i2yz9q-oniguruma-6.9.8-lib [...] 41 // └───/nix/store/1x3s2v9wc9m302cspfqcn2iwar0b5w99-jq-1.6-lib [...] 42 fixture: "image-nixos-jq-pkg-db", 43 wantPkgs: []string{ 44 "glibc @ 2.37-8 (/nix/var/nix/db/db.sqlite)", 45 "jq @ 1.6 (/nix/var/nix/db/db.sqlite)", // lib output 46 "jq @ 1.6 (/nix/var/nix/db/db.sqlite)", // bin output 47 "libidn2 @ 2.3.4 (/nix/var/nix/db/db.sqlite)", 48 "libunistring @ 1.1 (/nix/var/nix/db/db.sqlite)", 49 "oniguruma @ 6.9.8 (/nix/var/nix/db/db.sqlite)", 50 "xgcc @ 12.3.0 (/nix/var/nix/db/db.sqlite)", 51 }, 52 wantRel: []string{ 53 // used the DB cataloger, thus has a complete dependency graph 54 "glibc @ 2.37-8 (/nix/var/nix/db/db.sqlite) [dependency-of] jq @ 1.6 (/nix/var/nix/db/db.sqlite)", // jq bin output 55 "glibc @ 2.37-8 (/nix/var/nix/db/db.sqlite) [dependency-of] jq @ 1.6 (/nix/var/nix/db/db.sqlite)", // jq lib output 56 "glibc @ 2.37-8 (/nix/var/nix/db/db.sqlite) [dependency-of] oniguruma @ 6.9.8 (/nix/var/nix/db/db.sqlite)", 57 "jq @ 1.6 (/nix/var/nix/db/db.sqlite) [dependency-of] jq @ 1.6 (/nix/var/nix/db/db.sqlite)", // jq bin to lib output dependency 58 "libidn2 @ 2.3.4 (/nix/var/nix/db/db.sqlite) [dependency-of] glibc @ 2.37-8 (/nix/var/nix/db/db.sqlite)", 59 "libunistring @ 1.1 (/nix/var/nix/db/db.sqlite) [dependency-of] libidn2 @ 2.3.4 (/nix/var/nix/db/db.sqlite)", 60 "oniguruma @ 6.9.8 (/nix/var/nix/db/db.sqlite) [dependency-of] jq @ 1.6 (/nix/var/nix/db/db.sqlite)", // jq bin output 61 "oniguruma @ 6.9.8 (/nix/var/nix/db/db.sqlite) [dependency-of] jq @ 1.6 (/nix/var/nix/db/db.sqlite)", // jq lib output 62 "xgcc @ 12.3.0 (/nix/var/nix/db/db.sqlite) [dependency-of] glibc @ 2.37-8 (/nix/var/nix/db/db.sqlite)", 63 }, 64 }, 65 } 66 for _, tt := range tests { 67 t.Run(tt.fixture, func(t *testing.T) { 68 pkgtest.NewCatalogTester(). 69 WithImageResolver(t, tt.fixture). 70 ExpectsPackageStrings(tt.wantPkgs). 71 ExpectsRelationshipStrings(tt.wantRel). 72 TestCataloger(t, NewCataloger(DefaultConfig())) 73 }) 74 } 75 } 76 77 func TestCataloger_Image_FilesListing(t *testing.T) { 78 tests := []struct { 79 fixture string 80 wantPkgFiles map[string][]string 81 }{ 82 { 83 fixture: "image-nixos-jq-pkg-db", 84 wantPkgFiles: map[string][]string{ 85 "libidn2": { 86 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/lib/libidn2.la", 87 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/lib/libidn2.so.0.3.8", 88 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/cs/LC_MESSAGES/libidn2.mo", 89 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/da/LC_MESSAGES/libidn2.mo", 90 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/de/LC_MESSAGES/libidn2.mo", 91 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/eo/LC_MESSAGES/libidn2.mo", 92 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/es/LC_MESSAGES/libidn2.mo", 93 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/fi/LC_MESSAGES/libidn2.mo", 94 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/fr/LC_MESSAGES/libidn2.mo", 95 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/fur/LC_MESSAGES/libidn2.mo", 96 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/hr/LC_MESSAGES/libidn2.mo", 97 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/hu/LC_MESSAGES/libidn2.mo", 98 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/id/LC_MESSAGES/libidn2.mo", 99 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/it/LC_MESSAGES/libidn2.mo", 100 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/ja/LC_MESSAGES/libidn2.mo", 101 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/ka/LC_MESSAGES/libidn2.mo", 102 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/ko/LC_MESSAGES/libidn2.mo", 103 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/nl/LC_MESSAGES/libidn2.mo", 104 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/pl/LC_MESSAGES/libidn2.mo", 105 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/pt_BR/LC_MESSAGES/libidn2.mo", 106 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/ro/LC_MESSAGES/libidn2.mo", 107 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/ru/LC_MESSAGES/libidn2.mo", 108 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/sr/LC_MESSAGES/libidn2.mo", 109 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/sv/LC_MESSAGES/libidn2.mo", 110 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/uk/LC_MESSAGES/libidn2.mo", 111 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/vi/LC_MESSAGES/libidn2.mo", 112 "/nix/store/k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4/share/locale/zh_CN/LC_MESSAGES/libidn2.mo", 113 }, 114 }, 115 }, 116 } 117 for _, tt := range tests { 118 t.Run(tt.fixture, func(t *testing.T) { 119 pkgtest.NewCatalogTester(). 120 WithImageResolver(t, tt.fixture). 121 ExpectsAssertion(func(t *testing.T, pkgs []pkg.Package, relationships []artifact.Relationship) { 122 found := strset.New() 123 for _, p := range pkgs { 124 if files, ok := tt.wantPkgFiles[p.Name]; ok { 125 m, ok := p.Metadata.(pkg.NixStoreEntry) 126 require.True(t, ok) 127 if d := cmp.Diff(files, m.Files); d != "" { 128 t.Errorf("unexpected files for package %q: %s", p.Name, d) 129 } 130 found.Add(p.Name) 131 } 132 } 133 expected := strset.New() 134 for n := range tt.wantPkgFiles { 135 expected.Add(n) 136 } 137 assert.ElementsMatch(t, expected.List(), found.List()) 138 }). 139 TestCataloger(t, NewCataloger(Config{CaptureOwnedFiles: true})) 140 }) 141 } 142 } 143 144 func TestCataloger_Directory(t *testing.T) { 145 146 tests := []struct { 147 fixture string 148 wantPkgs []pkg.Package 149 wantRel []artifact.Relationship 150 }{ 151 { 152 fixture: "test-fixtures/fixture-1", 153 wantPkgs: []pkg.Package{ 154 { 155 Name: "glibc", 156 Version: "2.34-210", 157 PURL: "pkg:nix/glibc@2.34-210?drvpath=5av396z8xa13jg89g9jws145c0k26k2x-glibc-2.34-210.drv&output=bin&outputhash=h0cnbmfcn93xm5dg2x27ixhag1cwndga", 158 Locations: file.NewLocationSet( 159 file.NewLocation("nix/store/h0cnbmfcn93xm5dg2x27ixhag1cwndga-glibc-2.34-210-bin").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), 160 file.NewLocation("nix/store/5av396z8xa13jg89g9jws145c0k26k2x-glibc-2.34-210.drv").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.SupportingEvidenceAnnotation), 161 ), 162 FoundBy: "nix-cataloger", 163 Type: pkg.NixPkg, 164 Metadata: pkg.NixStoreEntry{ 165 Path: "/nix/store/h0cnbmfcn93xm5dg2x27ixhag1cwndga-glibc-2.34-210-bin", 166 Derivation: pkg.NixDerivation{ 167 Path: "nix/store/5av396z8xa13jg89g9jws145c0k26k2x-glibc-2.34-210.drv", 168 System: "aarch64-linux", 169 InputDerivations: []pkg.NixDerivationReference{ 170 { 171 Path: "/nix/store/1zi0k7y01rhqr2gfqb42if0icswg65sj-locale-C.diff.drv", 172 Outputs: []string{"out"}, 173 }, 174 { 175 Path: "/nix/store/45j86ggi8mlpfslcrgvjf7m6phia21fp-raw.drv", 176 Outputs: []string{"out"}, 177 }, 178 { 179 Path: "/nix/store/4fnfsd9sc7bam6886hwyaprdsww66dg3-bison-3.8.2.drv", 180 Outputs: []string{"out"}, 181 }, 182 { 183 Path: "/nix/store/51azdrrvcqrk2hbky7ryphlwd99yz25d-linux-headers-5.18.drv", 184 Outputs: []string{"out"}, 185 }, 186 { 187 Path: "/nix/store/67s0qc21gyarmdwc181bqmjc3qzv8zkz-libidn2-2.3.2.drv", 188 Outputs: []string{"out"}, 189 }, 190 { 191 Path: "/nix/store/9rhliwskh3mrrs5nfzgz0x6wrccyfg7k-bootstrap-stage0-glibc-bootstrap.drv", 192 Outputs: []string{"out"}, 193 }, 194 { 195 Path: "/nix/store/cl1wcw2v1ifzjlkzi50h32a6lms9m25s-binutils-2.38.drv", 196 Outputs: []string{"out"}, 197 }, 198 { 199 Path: "/nix/store/ghjc8bkfk8lh53z14mk2nk7h059zh7vx-python3-minimal-3.10.5.drv", 200 Outputs: []string{"out"}, 201 }, 202 { 203 Path: "/nix/store/k3786wfzw637r7sylccdmm92saqp73d8-glibc-2.34.tar.xz.drv", 204 Outputs: []string{"out"}, 205 }, 206 { 207 Path: "/nix/store/l5zr5m1agvvnic49fg6qc44g5fgj3la1-glibc-reinstate-prlimit64-fallback.patch?id=eab07e78b691ae7866267fc04d31c7c3ad6b0eeb.drv", 208 Outputs: []string{"out"}, 209 }, 210 { 211 Path: "/nix/store/mf5kz6d01ab8h0rswzyr04mbcd6g5x9n-bootstrap-stage2-stdenv-linux.drv", 212 Outputs: []string{"out"}, 213 }, 214 { 215 Path: "/nix/store/nd1zy67vp028707pbh466qhrfqh4cpq6-bootstrap-stage2-gcc-wrapper-.drv", 216 Outputs: []string{"out"}, 217 }, 218 { 219 Path: "/nix/store/ra77ww7p2xx8jh8n4m9vmj6wc8wxijdb-bootstrap-tools.drv", 220 Outputs: []string{"out"}, 221 }, 222 { 223 Path: "/nix/store/wlldapf5bg58kivw520ll5bw0fmlaid7-raw.drv", 224 Outputs: []string{"out"}, 225 }, 226 }, 227 InputSources: []string{ 228 "/nix/store/001gp43bjqzx60cg345n2slzg7131za8-nix-nss-open-files.patch", 229 "/nix/store/7kw224hdyxd7115lrqh9a4dv2x8msq2s-fix-x64-abi.patch", 230 "/nix/store/8haph3ng4mgsqr6p4024vj8k6kg3mqc4-nix-locale-archive.patch", 231 "/nix/store/95hp6hs9g73h93safadb8x6vajyqkv6q-0001-Revert-Remove-all-usage-of-BASH-or-BASH-in-installed.patch", 232 "/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh", 233 "/nix/store/b1w7zbvm39ff1i52iyjggyvw2rdxz104-dont-use-system-ld-so-cache.patch", 234 "/nix/store/ikmqczy0y20n04a2b8qfflzwihv8139g-separate-debug-info.sh", 235 "/nix/store/mgx19wbmgrh3rblbxhs6vi47sha15n11-2.34-master.patch.gz", 236 "/nix/store/mnglr8rr7nl444h7p50ysyq8qd0fm1lm-dont-use-system-ld-so-preload.patch", 237 "/nix/store/xkd50xxii6k7l1kmw4l5x6xzbhamcs87-allow-kernel-2.6.32.patch", 238 "/nix/store/za0pg7fmysrcwrqcal26fnmzw6vycgdn-fix_path_attribute_in_getconf.patch", 239 }, 240 }, 241 OutputHash: "h0cnbmfcn93xm5dg2x27ixhag1cwndga", 242 Output: "bin", 243 Files: nil, // default cataloger configure does not capture owned files 244 }, 245 }, 246 }, 247 }, 248 } 249 for _, tt := range tests { 250 t.Run(tt.fixture, func(t *testing.T) { 251 pkgtest.NewCatalogTester(). 252 FromDirectory(t, tt.fixture). 253 Expects(tt.wantPkgs, tt.wantRel). 254 TestCataloger(t, NewCataloger(DefaultConfig())) 255 }) 256 } 257 }