zotregistry.io/zot@v1.4.4-0.20231124084042-02a8ed785457/pkg/extensions/search/convert/convert_internal_test.go (about) 1 //go:build search 2 3 package convert 4 5 import ( 6 "context" 7 "errors" 8 "testing" 9 10 "github.com/99designs/gqlgen/graphql" 11 ispec "github.com/opencontainers/image-spec/specs-go/v1" 12 . "github.com/smartystreets/goconvey/convey" 13 14 cvemodel "zotregistry.io/zot/pkg/extensions/search/cve/model" 15 "zotregistry.io/zot/pkg/extensions/search/gql_generated" 16 "zotregistry.io/zot/pkg/log" 17 "zotregistry.io/zot/pkg/meta/boltdb" 18 . "zotregistry.io/zot/pkg/test/image-utils" 19 "zotregistry.io/zot/pkg/test/mocks" 20 ) 21 22 var ErrTestError = errors.New("TestError") 23 24 func TestCVEConvert(t *testing.T) { 25 Convey("Test adding CVE information to Summary objects", t, func() { 26 params := boltdb.DBParameters{ 27 RootDir: t.TempDir(), 28 } 29 boltDB, err := boltdb.GetBoltDriver(params) 30 So(err, ShouldBeNil) 31 32 metaDB, err := boltdb.New(boltDB, log.NewLogger("debug", "")) 33 So(err, ShouldBeNil) 34 35 image := CreateImageWith(). 36 Layers([]Layer{{ 37 MediaType: ispec.MediaTypeImageLayerGzip, 38 Digest: ispec.MediaTypeEmptyJSON, 39 Blob: ispec.DescriptorEmptyJSON.Data, 40 }}).DefaultConfig().Build() 41 42 err = metaDB.SetRepoReference(context.Background(), "repo1", "0.1.0", image.AsImageMeta()) 43 So(err, ShouldBeNil) 44 45 repoMetaList, err := metaDB.SearchRepos(context.Background(), "") 46 So(err, ShouldBeNil) 47 48 imageMeta, err := metaDB.FilterImageMeta(context.Background(), []string{image.DigestStr()}) 49 50 ctx := graphql.WithResponseContext(context.Background(), 51 graphql.DefaultErrorPresenter, graphql.DefaultRecover) 52 53 Convey("Add CVE Summary to ImageSummary", func() { 54 var imageSummary *gql_generated.ImageSummary 55 56 So(imageSummary, ShouldBeNil) 57 58 updateImageSummaryVulnerabilities(ctx, 59 imageSummary, 60 SkipQGLField{ 61 Vulnerabilities: false, 62 }, 63 mocks.CveInfoMock{ 64 GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string, 65 ) (cvemodel.ImageCVESummary, error) { 66 return cvemodel.ImageCVESummary{}, ErrTestError 67 }, 68 }, 69 ) 70 71 So(imageSummary, ShouldBeNil) 72 So(graphql.GetErrors(ctx), ShouldBeNil) 73 74 imageSummary, _, err = ImageManifest2ImageSummary(ctx, GetFullImageMeta("0.1.0", repoMetaList[0], 75 imageMeta[image.DigestStr()])) 76 So(err, ShouldBeNil) 77 78 So(imageSummary, ShouldNotBeNil) 79 So(imageSummary.Vulnerabilities, ShouldBeNil) 80 81 updateImageSummaryVulnerabilities(ctx, 82 imageSummary, 83 SkipQGLField{ 84 Vulnerabilities: true, 85 }, 86 mocks.CveInfoMock{}, 87 ) 88 89 So(imageSummary.Vulnerabilities, ShouldNotBeNil) 90 So(*imageSummary.Vulnerabilities.Count, ShouldEqual, 0) 91 So(*imageSummary.Vulnerabilities.MaxSeverity, ShouldEqual, "") 92 So(graphql.GetErrors(ctx), ShouldBeNil) 93 94 imageSummary.Vulnerabilities = nil 95 96 updateImageSummaryVulnerabilities(ctx, 97 imageSummary, 98 SkipQGLField{ 99 Vulnerabilities: false, 100 }, 101 mocks.CveInfoMock{ 102 GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string, 103 ) (cvemodel.ImageCVESummary, error) { 104 return cvemodel.ImageCVESummary{ 105 Count: 1, 106 MaxSeverity: "HIGH", 107 }, nil 108 }, 109 }, 110 ) 111 112 So(imageSummary.Vulnerabilities, ShouldNotBeNil) 113 So(*imageSummary.Vulnerabilities.Count, ShouldEqual, 1) 114 So(*imageSummary.Vulnerabilities.MaxSeverity, ShouldEqual, "HIGH") 115 So(graphql.GetErrors(ctx), ShouldBeNil) 116 So(len(imageSummary.Manifests), ShouldEqual, 1) 117 So(imageSummary.Manifests[0].Vulnerabilities, ShouldNotBeNil) 118 So(*imageSummary.Manifests[0].Vulnerabilities.Count, ShouldEqual, 1) 119 So(*imageSummary.Manifests[0].Vulnerabilities.MaxSeverity, ShouldEqual, "HIGH") 120 121 imageSummary.Vulnerabilities = nil 122 123 updateImageSummaryVulnerabilities(ctx, 124 imageSummary, 125 SkipQGLField{ 126 Vulnerabilities: false, 127 }, 128 mocks.CveInfoMock{ 129 GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string, 130 ) (cvemodel.ImageCVESummary, error) { 131 return cvemodel.ImageCVESummary{}, ErrTestError 132 }, 133 }, 134 ) 135 136 So(imageSummary.Vulnerabilities, ShouldNotBeNil) 137 So(*imageSummary.Vulnerabilities.Count, ShouldEqual, 0) 138 So(*imageSummary.Vulnerabilities.MaxSeverity, ShouldEqual, "") 139 So(graphql.GetErrors(ctx).Error(), ShouldContainSubstring, "unable to run vulnerability scan on tag") 140 }) 141 142 Convey("Add CVE Summary to RepoSummary", func() { 143 var repoSummary *gql_generated.RepoSummary 144 So(repoSummary, ShouldBeNil) 145 146 updateRepoSummaryVulnerabilities(ctx, 147 repoSummary, 148 SkipQGLField{ 149 Vulnerabilities: false, 150 }, 151 mocks.CveInfoMock{ 152 GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string, 153 ) (cvemodel.ImageCVESummary, error) { 154 return cvemodel.ImageCVESummary{ 155 Count: 1, 156 MaxSeverity: "HIGH", 157 }, nil 158 }, 159 }, 160 ) 161 162 So(repoSummary, ShouldBeNil) 163 So(graphql.GetErrors(ctx), ShouldBeNil) 164 165 imageSummary, _, err := ImageManifest2ImageSummary(ctx, GetFullImageMeta("0.1.0", repoMetaList[0], 166 imageMeta[image.DigestStr()])) 167 So(err, ShouldBeNil) 168 169 So(imageSummary, ShouldNotBeNil) 170 171 repoSummary = &gql_generated.RepoSummary{} 172 repoSummary.NewestImage = imageSummary 173 174 So(repoSummary.NewestImage.Vulnerabilities, ShouldBeNil) 175 176 updateImageSummaryVulnerabilities(ctx, 177 imageSummary, 178 SkipQGLField{ 179 Vulnerabilities: false, 180 }, 181 mocks.CveInfoMock{ 182 GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string, 183 ) (cvemodel.ImageCVESummary, error) { 184 return cvemodel.ImageCVESummary{ 185 Count: 1, 186 MaxSeverity: "HIGH", 187 }, nil 188 }, 189 }, 190 ) 191 192 So(repoSummary.NewestImage.Vulnerabilities, ShouldNotBeNil) 193 So(*repoSummary.NewestImage.Vulnerabilities.Count, ShouldEqual, 1) 194 So(*repoSummary.NewestImage.Vulnerabilities.MaxSeverity, ShouldEqual, "HIGH") 195 So(graphql.GetErrors(ctx), ShouldBeNil) 196 }) 197 198 Convey("Add CVE Summary to ManifestSummary", func() { 199 var manifestSummary *gql_generated.ManifestSummary 200 201 So(manifestSummary, ShouldBeNil) 202 203 updateManifestSummaryVulnerabilities(ctx, 204 manifestSummary, 205 "repo1", 206 SkipQGLField{ 207 Vulnerabilities: false, 208 }, 209 mocks.CveInfoMock{ 210 GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string, 211 ) (cvemodel.ImageCVESummary, error) { 212 return cvemodel.ImageCVESummary{ 213 Count: 1, 214 MaxSeverity: "HIGH", 215 }, nil 216 }, 217 }, 218 ) 219 220 So(manifestSummary, ShouldBeNil) 221 So(graphql.GetErrors(ctx), ShouldBeNil) 222 223 imageSummary, _, err := ImageManifest2ImageSummary(ctx, GetFullImageMeta("0.1.0", repoMetaList[0], 224 imageMeta[image.DigestStr()])) 225 So(err, ShouldBeNil) 226 manifestSummary = imageSummary.Manifests[0] 227 228 updateManifestSummaryVulnerabilities(ctx, 229 manifestSummary, 230 "repo1", 231 SkipQGLField{ 232 Vulnerabilities: true, 233 }, 234 mocks.CveInfoMock{}, 235 ) 236 237 So(manifestSummary, ShouldNotBeNil) 238 So(manifestSummary.Vulnerabilities, ShouldNotBeNil) 239 So(*manifestSummary.Vulnerabilities.Count, ShouldEqual, 0) 240 So(*manifestSummary.Vulnerabilities.MaxSeverity, ShouldEqual, "") 241 242 manifestSummary.Vulnerabilities = nil 243 244 updateManifestSummaryVulnerabilities(ctx, 245 manifestSummary, 246 "repo1", 247 SkipQGLField{ 248 Vulnerabilities: false, 249 }, 250 mocks.CveInfoMock{ 251 GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string, 252 ) (cvemodel.ImageCVESummary, error) { 253 return cvemodel.ImageCVESummary{ 254 Count: 1, 255 MaxSeverity: "HIGH", 256 }, nil 257 }, 258 }, 259 ) 260 261 So(manifestSummary.Vulnerabilities, ShouldNotBeNil) 262 So(*manifestSummary.Vulnerabilities.Count, ShouldEqual, 1) 263 So(*manifestSummary.Vulnerabilities.MaxSeverity, ShouldEqual, "HIGH") 264 265 manifestSummary.Vulnerabilities = nil 266 267 updateManifestSummaryVulnerabilities(ctx, 268 manifestSummary, 269 "repo1", 270 SkipQGLField{ 271 Vulnerabilities: false, 272 }, 273 mocks.CveInfoMock{ 274 GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string, 275 ) (cvemodel.ImageCVESummary, error) { 276 return cvemodel.ImageCVESummary{}, ErrTestError 277 }, 278 }, 279 ) 280 281 So(manifestSummary.Vulnerabilities, ShouldNotBeNil) 282 So(*manifestSummary.Vulnerabilities.Count, ShouldEqual, 0) 283 So(*manifestSummary.Vulnerabilities.MaxSeverity, ShouldEqual, "") 284 So(graphql.GetErrors(ctx).Error(), ShouldContainSubstring, "unable to run vulnerability scan in repo") 285 }) 286 }) 287 }