github.com/anchore/syft@v1.38.2/syft/pkg/cataloger/conda/cataloger_test.go (about)

     1  package conda
     2  
     3  import (
     4  	"context"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/go-test/deep"
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/anchore/syft/syft/file"
    12  	"github.com/anchore/syft/syft/pkg"
    13  	"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
    14  )
    15  
    16  func Test_CondaCataloger(t *testing.T) {
    17  	ctx := context.TODO()
    18  
    19  	tests := []struct {
    20  		name             string
    21  		fixture          string
    22  		expectedPackages []pkg.Package
    23  		wantErr          require.ErrorAssertionFunc
    24  	}{
    25  		{
    26  			name:    "multiple packages in conda meta (python, c binaries, ...)",
    27  			fixture: "test-fixtures/conda-meta-python-c-etc",
    28  			wantErr: require.NoError,
    29  			expectedPackages: []pkg.Package{
    30  				{
    31  					Name:    "jupyterlab",
    32  					Version: "4.4.3",
    33  					FoundBy: "conda-meta-cataloger",
    34  					Locations: file.NewLocationSet(
    35  						file.NewLocation("conda-meta/jupyterlab-4.4.3-pyhd8ed1ab_0.json"),
    36  					),
    37  					Language: pkg.UnknownLanguage,
    38  					Type:     pkg.CondaPkg,
    39  					Licenses: pkg.NewLicenseSet(
    40  						pkg.NewLicenseFromLocationsWithContext(ctx, "BSD-3-Clause", file.NewLocation("conda-meta/jupyterlab-4.4.3-pyhd8ed1ab_0.json")),
    41  					),
    42  					Metadata: pkg.CondaMetaPackage{
    43  						Name:                "jupyterlab",
    44  						Version:             "4.4.3",
    45  						Build:               "pyhd8ed1ab_0",
    46  						BuildNumber:         0,
    47  						Channel:             "https://conda.anaconda.org/conda-forge/",
    48  						Subdir:              "noarch",
    49  						Noarch:              "python",
    50  						License:             "BSD-3-Clause",
    51  						LicenseFamily:       "BSD",
    52  						MD5:                 "4861a0c2a5a5d0481a450a9dfaf9febe",
    53  						SHA256:              "fc0235a71d852734fe92183a78cb91827367573450eba82465ae522c64230736",
    54  						Size:                8236973,
    55  						Timestamp:           1748273017680,
    56  						Filename:            "jupyterlab-4.4.3-pyhd8ed1ab_0.conda",
    57  						URL:                 "https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.4.3-pyhd8ed1ab_0.conda",
    58  						ExtractedPackageDir: "/Users/example-user/Library/Caches/rattler/cache/pkgs/jupyterlab-4.4.3-pyhd8ed1ab_0",
    59  						Depends: []string{
    60  							"async-lru >=1.0.0",
    61  							"httpx >=0.25.0",
    62  							"importlib-metadata >=4.8.3",
    63  							"ipykernel >=6.5.0",
    64  							"jinja2 >=3.0.3",
    65  							"jupyter-lsp >=2.0.0",
    66  							"jupyter_core",
    67  							"jupyter_server >=2.4.0,<3",
    68  							"jupyterlab_server >=2.27.1,<3",
    69  							"notebook-shim >=0.2",
    70  							"packaging",
    71  							"python >=3.9",
    72  							"setuptools >=41.1.0",
    73  							"tomli >=1.2.2",
    74  							"tornado >=6.2.0",
    75  							"traitlets",
    76  						},
    77  						Files: []string{
    78  							"lib/python3.13/site-packages/jupyterlab/schemas/@jupyterlab/apputils-extension/kernels-settings.json",
    79  							"lib/python3.13/site-packages/jupyterlab/schemas/@jupyterlab/apputils-extension/notification.json",
    80  						},
    81  						PathsData: &pkg.CondaPathsData{
    82  							PathsVersion: 1,
    83  							Paths: []pkg.CondaPathData{
    84  								{
    85  									Path:           "lib/python3.13/site-packages/jupyterlab/schemas/@jupyterlab/apputils-extension/kernels-settings.json",
    86  									PathType:       "hardlink",
    87  									SHA256:         "081a7e126deffbcd596863f3349a19416fbbe1fd570ab392270315f7cf5a8c27",
    88  									SHA256InPrefix: "081a7e126deffbcd596863f3349a19416fbbe1fd570ab392270315f7cf5a8c27",
    89  									SizeInBytes:    935,
    90  								},
    91  								{
    92  									Path:           "lib/python3.13/site-packages/jupyterlab/schemas/@jupyterlab/apputils-extension/notification.json",
    93  									PathType:       "hardlink",
    94  									SHA256:         "f9f42636592f62cdd03e3d5552b020811e3f8be6fc47c03d5a92396941b8d5d8",
    95  									SHA256InPrefix: "f9f42636592f62cdd03e3d5552b020811e3f8be6fc47c03d5a92396941b8d5d8",
    96  									SizeInBytes:    1565,
    97  								},
    98  							},
    99  						},
   100  						Link: &pkg.CondaLink{
   101  							Source: "/Users/example-user/Library/Caches/rattler/cache/pkgs/jupyterlab-4.4.3-pyhd8ed1ab_0",
   102  							Type:   1,
   103  						},
   104  					},
   105  				},
   106  				{
   107  					Name:    "zlib",
   108  					Version: "1.2.11",
   109  					FoundBy: "conda-meta-cataloger",
   110  					Locations: file.NewLocationSet(
   111  						file.NewLocation("conda-meta/zlib-1.2.11-h90dfc92_1014.json"),
   112  					),
   113  					Language: pkg.UnknownLanguage,
   114  					Type:     pkg.CondaPkg,
   115  					Licenses: pkg.NewLicenseSet(
   116  						pkg.NewLicenseFromLocationsWithContext(ctx, "Zlib", file.NewLocation("conda-meta/zlib-1.2.11-h90dfc92_1014.json")),
   117  					),
   118  					Metadata: pkg.CondaMetaPackage{
   119  						Arch:                "arm64",
   120  						Name:                "zlib",
   121  						Version:             "1.2.11",
   122  						Build:               "h90dfc92_1014",
   123  						BuildNumber:         1014,
   124  						Channel:             "https://conda.anaconda.org/conda-forge/",
   125  						Subdir:              "osx-arm64",
   126  						Noarch:              "",
   127  						License:             "Zlib",
   128  						LicenseFamily:       "Other",
   129  						MD5:                 "348a30b1350c9d91a4dbf05f5e46e0bb",
   130  						SHA256:              "a70c028fd3b9af1d7ea3d7099d810f3d2588096237bb472db331a51a36f931c0",
   131  						Size:                86757,
   132  						Timestamp:           1648307332172,
   133  						Filename:            "zlib-1.2.11-h90dfc92_1014.tar.bz2",
   134  						URL:                 "https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.2.11-h90dfc92_1014.tar.bz2",
   135  						ExtractedPackageDir: "/Users/example-user/Library/Caches/rattler/cache/pkgs/zlib-1.2.11-h90dfc92_1014",
   136  						Depends: []string{
   137  							"libzlib 1.2.11 h90dfc92_1014",
   138  						},
   139  						Files: []string{
   140  							"include/zconf.h",
   141  							"include/zlib.h",
   142  							"lib/pkgconfig/zlib.pc",
   143  							"lib/libz.a",
   144  							"lib/libz.dylib",
   145  						},
   146  						PathsData: &pkg.CondaPathsData{
   147  							PathsVersion: 1,
   148  							Paths: []pkg.CondaPathData{
   149  								{
   150  									Path:           "include/zconf.h",
   151  									PathType:       "hardlink",
   152  									SHA256:         "77304005ceb5f0d03ad4c37eb8386a10866e4ceeb204f7c3b6599834c7319541",
   153  									SHA256InPrefix: "77304005ceb5f0d03ad4c37eb8386a10866e4ceeb204f7c3b6599834c7319541",
   154  									SizeInBytes:    16262,
   155  								},
   156  								{
   157  									Path:           "include/zlib.h",
   158  									PathType:       "hardlink",
   159  									SHA256:         "4ddc82b4af931ab55f44d977bde81bfbc4151b5dcdccc03142831a301b5ec3c8",
   160  									SHA256InPrefix: "4ddc82b4af931ab55f44d977bde81bfbc4151b5dcdccc03142831a301b5ec3c8",
   161  									SizeInBytes:    96239,
   162  								},
   163  								{
   164  									Path:           "lib/pkgconfig/zlib.pc",
   165  									PathType:       "hardlink",
   166  									SHA256:         "357773df3c44a5ebd77fdadd0869b5b06394bbf556c2d6c9736dd53e9df3b2c2",
   167  									SHA256InPrefix: "5b4eb6062f97875eaadb3b6c7cf8cfeff3808798ecbf2bfc095f18dcecc509bf",
   168  									SizeInBytes:    285,
   169  								},
   170  								{
   171  									Path:           "lib/libz.a",
   172  									PathType:       "hardlink",
   173  									SHA256:         "40c056a5d8155d9b3f42adfe35f7fc6e5fa15cc6588ffad0f09fe67517feada0",
   174  									SHA256InPrefix: "40c056a5d8155d9b3f42adfe35f7fc6e5fa15cc6588ffad0f09fe67517feada0",
   175  									SizeInBytes:    107128,
   176  								},
   177  								{
   178  									Path:           "lib/libz.dylib",
   179  									PathType:       "softlink",
   180  									SHA256:         "67ed489e2f378880f72fb1c0d1cc916e184b9632eccf2b5c1b34ddf01ed1701c",
   181  									SHA256InPrefix: "09e47dbc60aa970e153913fe84551ad7f5aa51c21907591340a0cc999adab859",
   182  									SizeInBytes:    122478,
   183  								},
   184  							},
   185  						},
   186  						Link: &pkg.CondaLink{
   187  							Source: "/Users/example-user/Library/Caches/rattler/cache/pkgs/zlib-1.2.11-h90dfc92_1014",
   188  							Type:   1,
   189  						},
   190  					},
   191  				},
   192  			},
   193  		},
   194  		{
   195  			name:             "badly formatted conda meta json file",
   196  			fixture:          "test-fixtures/conda-meta-bad-json",
   197  			expectedPackages: nil,
   198  			wantErr: func(t require.TestingT, err error, msgAndArgs ...interface{}) {
   199  				require.Error(t, err)
   200  				require.Contains(t, err.Error(), "failed to parse conda-meta package file at conda-meta/package-1.2.3-pyhd8ed1ab_0.json")
   201  				require.Contains(t, err.Error(), "invalid character")
   202  			},
   203  		},
   204  	}
   205  
   206  	for _, test := range tests {
   207  		t.Run(test.name, func(t *testing.T) {
   208  			pkgtest.NewCatalogTester().
   209  				FromDirectory(t, test.fixture).
   210  				Expects(test.expectedPackages, nil).
   211  				WithErrorAssertion(test.wantErr).
   212  				TestCataloger(t, NewCondaMetaCataloger())
   213  		})
   214  	}
   215  }
   216  
   217  func TestCondaMetaPackageMetadata_FileOwner(t *testing.T) {
   218  	tests := []struct {
   219  		metadata pkg.CondaMetaPackage
   220  		expected []string
   221  	}{
   222  		{
   223  			metadata: pkg.CondaMetaPackage{
   224  				Files: []string{
   225  					"include/zconf.h",
   226  					"include/zlib.h",
   227  					"lib/pkgconfig/zlib.pc",
   228  					"lib/libz.a",
   229  					"lib/libz.dylib",
   230  				},
   231  			},
   232  			expected: []string{
   233  				"include/zconf.h",
   234  				"include/zlib.h",
   235  				"lib/libz.a",
   236  				"lib/libz.dylib",
   237  				"lib/pkgconfig/zlib.pc",
   238  			},
   239  		},
   240  	}
   241  
   242  	for _, test := range tests {
   243  		t.Run(strings.Join(test.expected, ","), func(t *testing.T) {
   244  			actual := test.metadata.OwnedFiles()
   245  			for _, d := range deep.Equal(test.expected, actual) {
   246  				t.Errorf("diff: %+v", d)
   247  			}
   248  		})
   249  	}
   250  }