zotregistry.io/zot@v1.4.4-0.20231124084042-02a8ed785457/pkg/cli/client/search_functions_internal_test.go (about) 1 //go:build search 2 // +build search 3 4 // 5 //nolint:dupl 6 package client 7 8 import ( 9 "bytes" 10 "context" 11 "io" 12 "os" 13 "regexp" 14 "strings" 15 "sync" 16 "testing" 17 "time" 18 19 godigest "github.com/opencontainers/go-digest" 20 ispec "github.com/opencontainers/image-spec/specs-go/v1" 21 . "github.com/smartystreets/goconvey/convey" 22 "github.com/spf13/cobra" 23 24 zerr "zotregistry.io/zot/errors" 25 "zotregistry.io/zot/pkg/common" 26 ) 27 28 func TestSearchAllImages(t *testing.T) { 29 Convey("SearchAllImages", t, func() { 30 buff := bytes.NewBufferString("") 31 searchConfig := getMockSearchConfig(buff, mockService{ 32 getAllImagesFn: func(ctx context.Context, config SearchConfig, username, password string, 33 channel chan stringResult, wtgrp *sync.WaitGroup, 34 ) { 35 str, err := getMockImageStruct().stringPlainText(10, 10, 10, false) 36 37 channel <- stringResult{StrValue: str, Err: err} 38 }, 39 }) 40 41 err := SearchAllImages(searchConfig) 42 So(err, ShouldBeNil) 43 space := regexp.MustCompile(`\s+`) 44 str := space.ReplaceAllString(buff.String(), " ") 45 actual := strings.TrimSpace(str) 46 So(actual, ShouldContainSubstring, "repo tag os/arch 8c25cb36 false 100B") 47 }) 48 } 49 50 func TestSearchAllImagesGQL(t *testing.T) { 51 Convey("SearchAllImagesGQL", t, func() { 52 buff := bytes.NewBufferString("") 53 searchConfig := getMockSearchConfig(buff, mockService{ 54 getImagesGQLFn: func(ctx context.Context, config SearchConfig, username, password, imageName string, 55 ) (*common.ImageListResponse, error) { 56 return &common.ImageListResponse{ImageList: common.ImageList{ 57 PaginatedImagesResult: common.PaginatedImagesResult{ 58 Results: []common.ImageSummary{getMockImageSummary()}, 59 }, 60 }}, nil 61 }, 62 }) 63 64 err := SearchAllImagesGQL(searchConfig) 65 So(err, ShouldBeNil) 66 space := regexp.MustCompile(`\s+`) 67 str := space.ReplaceAllString(buff.String(), " ") 68 actual := strings.TrimSpace(str) 69 So(actual, ShouldContainSubstring, "repo tag os/arch 8c25cb36 false 100B") 70 }) 71 72 Convey("SearchAllImagesGQL error", t, func() { 73 buff := bytes.NewBufferString("") 74 searchConfig := getMockSearchConfig(buff, mockService{ 75 getImagesGQLFn: func(ctx context.Context, config SearchConfig, username, password, imageName string, 76 ) (*common.ImageListResponse, error) { 77 return &common.ImageListResponse{ImageList: common.ImageList{ 78 PaginatedImagesResult: common.PaginatedImagesResult{ 79 Results: []common.ImageSummary{getMockImageSummary()}, 80 }, 81 }}, zerr.ErrInjected 82 }, 83 }) 84 85 err := SearchAllImagesGQL(searchConfig) 86 So(err, ShouldNotBeNil) 87 }) 88 } 89 90 func TestSearchImageByName(t *testing.T) { 91 Convey("SearchImageByName", t, func() { 92 buff := bytes.NewBufferString("") 93 searchConfig := getMockSearchConfig(buff, mockService{ 94 getImageByNameFn: func(ctx context.Context, config SearchConfig, username string, password string, imageName string, 95 channel chan stringResult, wtgrp *sync.WaitGroup, 96 ) { 97 str, err := getMockImageStruct().stringPlainText(10, 10, 10, false) 98 99 channel <- stringResult{StrValue: str, Err: err} 100 }, 101 }) 102 103 err := SearchImageByName(searchConfig, "repo") 104 So(err, ShouldBeNil) 105 space := regexp.MustCompile(`\s+`) 106 str := space.ReplaceAllString(buff.String(), " ") 107 actual := strings.TrimSpace(str) 108 So(actual, ShouldContainSubstring, "repo tag os/arch 8c25cb36 false 100B") 109 }) 110 111 Convey("SearchImageByName error", t, func() { 112 buff := bytes.NewBufferString("") 113 searchConfig := getMockSearchConfig(buff, mockService{ 114 getImageByNameFn: func(ctx context.Context, config SearchConfig, username string, password string, imageName string, 115 channel chan stringResult, wtgrp *sync.WaitGroup, 116 ) { 117 channel <- stringResult{StrValue: "", Err: zerr.ErrInjected} 118 }, 119 }) 120 121 err := SearchImageByName(searchConfig, "repo") 122 So(err, ShouldNotBeNil) 123 }) 124 } 125 126 func TestSearchImageByNameGQL(t *testing.T) { 127 Convey("SearchImageByNameGQL", t, func() { 128 buff := bytes.NewBufferString("") 129 searchConfig := getMockSearchConfig(buff, mockService{ 130 getImagesGQLFn: func(ctx context.Context, config SearchConfig, username, password, imageName string, 131 ) (*common.ImageListResponse, error) { 132 return &common.ImageListResponse{ImageList: common.ImageList{ 133 PaginatedImagesResult: common.PaginatedImagesResult{ 134 Results: []common.ImageSummary{getMockImageSummary()}, 135 }, 136 }}, nil 137 }, 138 }) 139 140 err := SearchImageByNameGQL(searchConfig, "repo") 141 So(err, ShouldBeNil) 142 space := regexp.MustCompile(`\s+`) 143 str := space.ReplaceAllString(buff.String(), " ") 144 actual := strings.TrimSpace(str) 145 So(actual, ShouldContainSubstring, "repo tag os/arch 8c25cb36 false 100B") 146 }) 147 148 Convey("SearchImageByNameGQL error", t, func() { 149 buff := bytes.NewBufferString("") 150 searchConfig := getMockSearchConfig(buff, mockService{ 151 getImagesGQLFn: func(ctx context.Context, config SearchConfig, username, password, imageName string, 152 ) (*common.ImageListResponse, error) { 153 return &common.ImageListResponse{ImageList: common.ImageList{ 154 PaginatedImagesResult: common.PaginatedImagesResult{ 155 Results: []common.ImageSummary{getMockImageSummary()}, 156 }, 157 }}, zerr.ErrInjected 158 }, 159 }) 160 161 err := SearchImageByNameGQL(searchConfig, "repo") 162 So(err, ShouldNotBeNil) 163 }) 164 } 165 166 func TestSearchImagesByDigest(t *testing.T) { 167 Convey("SearchImagesByDigest", t, func() { 168 buff := bytes.NewBufferString("") 169 searchConfig := getMockSearchConfig(buff, mockService{ 170 getImagesByDigestFn: func(ctx context.Context, config SearchConfig, username string, password string, digest string, 171 rch chan stringResult, wtgrp *sync.WaitGroup, 172 ) { 173 str, err := getMockImageStruct().stringPlainText(10, 10, 10, false) 174 175 rch <- stringResult{StrValue: str, Err: err} 176 }, 177 }) 178 179 err := SearchImagesByDigest(searchConfig, godigest.FromString("str").String()) 180 So(err, ShouldBeNil) 181 space := regexp.MustCompile(`\s+`) 182 str := space.ReplaceAllString(buff.String(), " ") 183 actual := strings.TrimSpace(str) 184 So(actual, ShouldContainSubstring, "repo tag os/arch 8c25cb36 false 100B") 185 }) 186 187 Convey("SearchImagesByDigest error", t, func() { 188 buff := bytes.NewBufferString("") 189 searchConfig := getMockSearchConfig(buff, mockService{ 190 getImagesByDigestFn: func(ctx context.Context, config SearchConfig, username string, password string, digest string, 191 rch chan stringResult, wtgrp *sync.WaitGroup, 192 ) { 193 rch <- stringResult{StrValue: "", Err: zerr.ErrInjected} 194 }, 195 }) 196 197 err := SearchImagesByDigest(searchConfig, godigest.FromString("str").String()) 198 So(err, ShouldNotBeNil) 199 }) 200 } 201 202 func TestSearchDerivedImageListGQL(t *testing.T) { 203 Convey("SearchDerivedImageListGQL", t, func() { 204 buff := bytes.NewBufferString("") 205 searchConfig := getMockSearchConfig(buff, mockService{ 206 getDerivedImageListGQLFn: func(ctx context.Context, config SearchConfig, username string, password string, 207 derivedImage string) (*common.DerivedImageListResponse, error, 208 ) { 209 return &common.DerivedImageListResponse{DerivedImageList: common.DerivedImageList{ 210 PaginatedImagesResult: common.PaginatedImagesResult{ 211 Results: []common.ImageSummary{ 212 getMockImageSummary(), 213 }, 214 }, 215 }}, nil 216 }, 217 }) 218 219 err := SearchDerivedImageListGQL(searchConfig, "repo:tag") 220 So(err, ShouldBeNil) 221 space := regexp.MustCompile(`\s+`) 222 str := space.ReplaceAllString(buff.String(), " ") 223 actual := strings.TrimSpace(str) 224 So(actual, ShouldContainSubstring, "repo tag os/arch 8c25cb36 false 100B") 225 }) 226 227 Convey("SearchDerivedImageListGQL error", t, func() { 228 buff := bytes.NewBufferString("") 229 searchConfig := getMockSearchConfig(buff, mockService{ 230 getDerivedImageListGQLFn: func(ctx context.Context, config SearchConfig, username string, password string, 231 derivedImage string) (*common.DerivedImageListResponse, error, 232 ) { 233 return &common.DerivedImageListResponse{DerivedImageList: common.DerivedImageList{ 234 PaginatedImagesResult: common.PaginatedImagesResult{Results: []common.ImageSummary{}}, 235 }}, zerr.ErrInjected 236 }, 237 }) 238 239 err := SearchDerivedImageListGQL(searchConfig, "repo:tag") 240 So(err, ShouldNotBeNil) 241 }) 242 } 243 244 func TestSearchBaseImageListGQL(t *testing.T) { 245 Convey("SearchBaseImageListGQL", t, func() { 246 buff := bytes.NewBufferString("") 247 searchConfig := getMockSearchConfig(buff, mockService{ 248 getBaseImageListGQLFn: func(ctx context.Context, config SearchConfig, username string, password string, 249 derivedImage string) (*common.BaseImageListResponse, error, 250 ) { 251 return &common.BaseImageListResponse{BaseImageList: common.BaseImageList{ 252 PaginatedImagesResult: common.PaginatedImagesResult{Results: []common.ImageSummary{ 253 getMockImageSummary(), 254 }}, 255 }}, nil 256 }, 257 }) 258 259 err := SearchBaseImageListGQL(searchConfig, "repo:tag") 260 So(err, ShouldBeNil) 261 space := regexp.MustCompile(`\s+`) 262 str := space.ReplaceAllString(buff.String(), " ") 263 actual := strings.TrimSpace(str) 264 So(actual, ShouldContainSubstring, "repo tag os/arch 8c25cb36 false 100B") 265 }) 266 267 Convey("SearchBaseImageListGQL error", t, func() { 268 buff := bytes.NewBufferString("") 269 searchConfig := getMockSearchConfig(buff, mockService{ 270 getBaseImageListGQLFn: func(ctx context.Context, config SearchConfig, username string, password string, 271 derivedImage string) (*common.BaseImageListResponse, error, 272 ) { 273 return &common.BaseImageListResponse{BaseImageList: common.BaseImageList{ 274 PaginatedImagesResult: common.PaginatedImagesResult{Results: []common.ImageSummary{}}, 275 }}, zerr.ErrInjected 276 }, 277 }) 278 279 err := SearchBaseImageListGQL(searchConfig, "repo:tag") 280 So(err, ShouldNotBeNil) 281 }) 282 } 283 284 func TestSearchImagesForDigestGQL(t *testing.T) { 285 Convey("SearchImagesForDigestGQL", t, func() { 286 buff := bytes.NewBufferString("") 287 searchConfig := getMockSearchConfig(buff, mockService{ 288 getImagesForDigestGQLFn: func(ctx context.Context, config SearchConfig, username string, 289 password string, digest string) (*common.ImagesForDigest, error, 290 ) { 291 return &common.ImagesForDigest{ImagesForDigestList: common.ImagesForDigestList{ 292 PaginatedImagesResult: common.PaginatedImagesResult{ 293 Results: []common.ImageSummary{getMockImageSummary()}, 294 }, 295 }}, nil 296 }, 297 }) 298 299 err := SearchImagesForDigestGQL(searchConfig, "digest") 300 So(err, ShouldBeNil) 301 space := regexp.MustCompile(`\s+`) 302 str := space.ReplaceAllString(buff.String(), " ") 303 actual := strings.TrimSpace(str) 304 So(actual, ShouldContainSubstring, "repo tag os/arch 8c25cb36 false 100B") 305 }) 306 307 Convey("SearchImagesForDigestGQL error", t, func() { 308 buff := bytes.NewBufferString("") 309 searchConfig := getMockSearchConfig(buff, mockService{ 310 getImagesForDigestGQLFn: func(ctx context.Context, config SearchConfig, username string, 311 password string, digest string) (*common.ImagesForDigest, error, 312 ) { 313 return &common.ImagesForDigest{ImagesForDigestList: common.ImagesForDigestList{ 314 PaginatedImagesResult: common.PaginatedImagesResult{}, 315 }}, zerr.ErrInjected 316 }, 317 }) 318 319 err := SearchImagesForDigestGQL(searchConfig, "digest") 320 So(err, ShouldNotBeNil) 321 }) 322 } 323 324 func TestSearchCVEForImageGQL(t *testing.T) { 325 Convey("SearchCVEForImageGQL", t, func() { 326 buff := bytes.NewBufferString("") 327 searchConfig := getMockSearchConfig(buff, mockService{ 328 getCveByImageGQLFn: func(ctx context.Context, config SearchConfig, username string, password string, 329 imageName string, searchedCVE string) (*cveResult, error, 330 ) { 331 return &cveResult{ 332 Data: cveData{ 333 CVEListForImage: cveListForImage{ 334 CVEList: []cve{ 335 { 336 ID: "dummyCVEID", 337 Description: "Description of the CVE", 338 Title: "Title of that CVE", 339 Severity: "HIGH", 340 PackageList: []packageList{ 341 { 342 Name: "packagename", 343 FixedVersion: "fixedver", 344 InstalledVersion: "installedver", 345 }, 346 }, 347 }, 348 }, 349 }, 350 }, 351 }, nil 352 }, 353 }) 354 355 err := SearchCVEForImageGQL(searchConfig, "repo-test", "dummyCVEID") 356 So(err, ShouldBeNil) 357 space := regexp.MustCompile(`\s+`) 358 str := space.ReplaceAllString(buff.String(), " ") 359 actual := strings.TrimSpace(str) 360 So(actual, ShouldContainSubstring, "dummyCVEID HIGH Title of that CVE") 361 }) 362 363 Convey("SearchCVEForImageGQL", t, func() { 364 buff := bytes.NewBufferString("") 365 searchConfig := getMockSearchConfig(buff, mockService{ 366 getCveByImageGQLFn: func(ctx context.Context, config SearchConfig, username string, password string, 367 imageName string, searchedCVE string) (*cveResult, error, 368 ) { 369 return &cveResult{}, zerr.ErrInjected 370 }, 371 }) 372 373 err := SearchCVEForImageGQL(searchConfig, "repo-test", "dummyCVEID") 374 So(err, ShouldNotBeNil) 375 }) 376 } 377 378 func TestSearchImagesByCVEIDGQL(t *testing.T) { 379 Convey("SearchImagesByCVEIDGQL", t, func() { 380 buff := bytes.NewBufferString("") 381 searchConfig := getMockSearchConfig(buff, mockService{ 382 getTagsForCVEGQLFn: func(ctx context.Context, config SearchConfig, username, password, 383 imageName, cveID string) (*common.ImagesForCve, error, 384 ) { 385 return &common.ImagesForCve{ 386 ImagesForCVEList: common.ImagesForCVEList{ 387 PaginatedImagesResult: common.PaginatedImagesResult{ 388 Results: []common.ImageSummary{ 389 getMockImageSummary(), 390 }, 391 }, 392 }, 393 }, nil 394 }, 395 }) 396 397 err := SearchImagesByCVEIDGQL(searchConfig, "repo", "CVE-12345") 398 So(err, ShouldBeNil) 399 space := regexp.MustCompile(`\s+`) 400 str := space.ReplaceAllString(buff.String(), " ") 401 actual := strings.TrimSpace(str) 402 So(actual, ShouldContainSubstring, "repo tag os/arch 8c25cb36 false 100B") 403 }) 404 405 Convey("SearchImagesByCVEIDGQL error", t, func() { 406 buff := bytes.NewBufferString("") 407 searchConfig := getMockSearchConfig(buff, mockService{ 408 getTagsForCVEGQLFn: func(ctx context.Context, config SearchConfig, username, password, 409 imageName, cveID string) (*common.ImagesForCve, error, 410 ) { 411 return &common.ImagesForCve{ 412 ImagesForCVEList: common.ImagesForCVEList{ 413 PaginatedImagesResult: common.PaginatedImagesResult{}, 414 }, 415 }, zerr.ErrInjected 416 }, 417 }) 418 419 err := SearchImagesByCVEIDGQL(searchConfig, "repo", "CVE-12345") 420 So(err, ShouldNotBeNil) 421 }) 422 } 423 424 func TestSearchFixedTagsGQL(t *testing.T) { 425 Convey("SearchFixedTagsGQL", t, func() { 426 buff := bytes.NewBufferString("") 427 searchConfig := getMockSearchConfig(buff, mockService{ 428 getFixedTagsForCVEGQLFn: func(ctx context.Context, config SearchConfig, username, password, 429 imageName, cveID string) (*common.ImageListWithCVEFixedResponse, error, 430 ) { 431 return &common.ImageListWithCVEFixedResponse{ 432 ImageListWithCVEFixed: common.ImageListWithCVEFixed{ 433 PaginatedImagesResult: common.PaginatedImagesResult{ 434 Results: []common.ImageSummary{getMockImageSummary()}, 435 }, 436 }, 437 }, nil 438 }, 439 }) 440 441 err := SearchFixedTagsGQL(searchConfig, "repo", "CVE-12345") 442 So(err, ShouldBeNil) 443 space := regexp.MustCompile(`\s+`) 444 str := space.ReplaceAllString(buff.String(), " ") 445 actual := strings.TrimSpace(str) 446 So(actual, ShouldContainSubstring, "repo tag os/arch 8c25cb36 false 100B") 447 }) 448 449 Convey("SearchFixedTagsGQL error", t, func() { 450 buff := bytes.NewBufferString("") 451 searchConfig := getMockSearchConfig(buff, mockService{ 452 getFixedTagsForCVEGQLFn: func(ctx context.Context, config SearchConfig, username, password, 453 imageName, cveID string) (*common.ImageListWithCVEFixedResponse, error, 454 ) { 455 return &common.ImageListWithCVEFixedResponse{ 456 ImageListWithCVEFixed: common.ImageListWithCVEFixed{ 457 PaginatedImagesResult: common.PaginatedImagesResult{}, 458 }, 459 }, zerr.ErrInjected 460 }, 461 }) 462 463 err := SearchFixedTagsGQL(searchConfig, "repo", "CVE-12345") 464 So(err, ShouldNotBeNil) 465 }) 466 } 467 468 func TestSearchReferrersGQL(t *testing.T) { 469 Convey("SearchReferrersGQL", t, func() { 470 buff := bytes.NewBufferString("") 471 searchConfig := getMockSearchConfig(buff, mockService{ 472 getReferrersGQLFn: func(ctx context.Context, config SearchConfig, username, password, 473 repo, digest string) (*common.ReferrersResp, error, 474 ) { 475 return &common.ReferrersResp{ 476 ReferrersResult: common.ReferrersResult{ 477 Referrers: []common.Referrer{{ 478 MediaType: ispec.MediaTypeImageManifest, 479 Size: 100, 480 ArtifactType: "art.type", 481 Digest: godigest.FromString("123").String(), 482 }}, 483 }, 484 }, nil 485 }, 486 }) 487 488 err := SearchReferrersGQL(searchConfig, "repo@"+godigest.FromString("str").String()) 489 So(err, ShouldBeNil) 490 space := regexp.MustCompile(`\s+`) 491 str := space.ReplaceAllString(buff.String(), " ") 492 actual := strings.TrimSpace(str) 493 So(actual, ShouldContainSubstring, 494 "art.type 100 B sha256:a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3") 495 }) 496 497 Convey("SearchReferrersGQL error", t, func() { 498 buff := bytes.NewBufferString("") 499 searchConfig := getMockSearchConfig(buff, mockService{ 500 getReferrersGQLFn: func(ctx context.Context, config SearchConfig, username, password, 501 repo, digest string) (*common.ReferrersResp, error, 502 ) { 503 return &common.ReferrersResp{}, zerr.ErrInjected 504 }, 505 }) 506 507 err := SearchReferrersGQL(searchConfig, "repo@"+godigest.FromString("str").String()) 508 So(err, ShouldNotBeNil) 509 }) 510 } 511 512 func TestGlobalSearchGQL(t *testing.T) { 513 Convey("GlobalSearchGQL", t, func() { 514 buff := bytes.NewBufferString("") 515 searchConfig := getMockSearchConfig(buff, mockService{ 516 globalSearchGQLFn: func(ctx context.Context, config SearchConfig, username, password, 517 query string) (*common.GlobalSearch, error, 518 ) { 519 return &common.GlobalSearch{ 520 Repos: []common.RepoSummary{{ 521 Name: "repo", 522 Size: "100", 523 LastUpdated: time.Date(2010, 1, 1, 1, 1, 1, 0, time.UTC), 524 }}, 525 }, nil 526 }, 527 }) 528 529 err := GlobalSearchGQL(searchConfig, "repo") 530 So(err, ShouldBeNil) 531 space := regexp.MustCompile(`\s+`) 532 str := space.ReplaceAllString(buff.String(), " ") 533 actual := strings.TrimSpace(str) 534 So(actual, ShouldContainSubstring, 535 "repo ") 536 }) 537 538 Convey("GlobalSearchGQL error", t, func() { 539 buff := bytes.NewBufferString("") 540 searchConfig := getMockSearchConfig(buff, mockService{ 541 globalSearchGQLFn: func(ctx context.Context, config SearchConfig, username, password, 542 query string) (*common.GlobalSearch, error, 543 ) { 544 return &common.GlobalSearch{}, zerr.ErrInjected 545 }, 546 }) 547 548 err := GlobalSearchGQL(searchConfig, "repo") 549 So(err, ShouldNotBeNil) 550 }) 551 } 552 553 func TestSearchReferrers(t *testing.T) { 554 Convey("SearchReferrers", t, func() { 555 buff := bytes.NewBufferString("") 556 searchConfig := getMockSearchConfig(buff, mockService{ 557 getReferrersFn: func(ctx context.Context, config SearchConfig, username string, password string, 558 repo string, digest string) (referrersResult, error, 559 ) { 560 return referrersResult([]common.Referrer{ 561 { 562 MediaType: ispec.MediaTypeImageManifest, 563 Size: 100, 564 ArtifactType: "art.type", 565 Digest: godigest.FromString("123").String(), 566 }, 567 }), nil 568 }, 569 }) 570 571 err := SearchReferrers(searchConfig, "repo@"+godigest.FromString("str").String()) 572 So(err, ShouldBeNil) 573 space := regexp.MustCompile(`\s+`) 574 str := space.ReplaceAllString(buff.String(), " ") 575 actual := strings.TrimSpace(str) 576 So(actual, ShouldContainSubstring, 577 "art.type 100 B sha256:a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3") 578 }) 579 580 Convey("SearchReferrers error", t, func() { 581 buff := bytes.NewBufferString("") 582 searchConfig := getMockSearchConfig(buff, mockService{ 583 getReferrersFn: func(ctx context.Context, config SearchConfig, username string, password string, 584 repo string, digest string) (referrersResult, error, 585 ) { 586 return referrersResult{}, zerr.ErrInjected 587 }, 588 }) 589 590 err := SearchReferrers(searchConfig, "repo@"+godigest.FromString("str").String()) 591 So(err, ShouldNotBeNil) 592 }) 593 } 594 595 func TestSearchRepos(t *testing.T) { 596 Convey("SearchRepos", t, func() { 597 buff := bytes.NewBufferString("") 598 searchConfig := getMockSearchConfig(buff, mockService{}) 599 600 err := SearchRepos(searchConfig) 601 So(err, ShouldBeNil) 602 space := regexp.MustCompile(`\s+`) 603 str := space.ReplaceAllString(buff.String(), " ") 604 actual := strings.TrimSpace(str) 605 So(actual, ShouldContainSubstring, "repo1") 606 So(actual, ShouldContainSubstring, "repo2") 607 }) 608 } 609 610 func getMockSearchConfig(buff *bytes.Buffer, mockService mockService) SearchConfig { 611 return SearchConfig{ 612 ResultWriter: buff, 613 User: "", 614 SearchService: mockService, 615 ServURL: "http://127.0.0.1:8000", 616 OutputFormat: "", 617 VerifyTLS: false, 618 FixedFlag: false, 619 Verbose: false, 620 Debug: false, 621 } 622 } 623 624 func getMockImageStruct() imageStruct { 625 return imageStruct(common.ImageSummary{ 626 RepoName: "repo", Tag: "tag", 627 MediaType: ispec.MediaTypeImageManifest, 628 Digest: godigest.FromString("str").String(), 629 Size: "100", 630 Manifests: []common.ManifestSummary{{ 631 Size: "100", 632 Platform: common.Platform{Os: "os", Arch: "arch"}, 633 Digest: godigest.FromString("str").String(), 634 ConfigDigest: godigest.FromString("str").String(), 635 }}, 636 }) 637 } 638 639 func getMockImageSummary() common.ImageSummary { 640 return common.ImageSummary{ 641 RepoName: "repo", Tag: "tag", 642 MediaType: ispec.MediaTypeImageManifest, 643 Digest: godigest.FromString("str").String(), 644 Size: "100", 645 Manifests: []common.ManifestSummary{{ 646 Size: "100", 647 Platform: common.Platform{Os: "os", Arch: "arch"}, 648 Digest: godigest.FromString("str").String(), 649 ConfigDigest: godigest.FromString("str").String(), 650 }}, 651 } 652 } 653 654 func TestUtils(t *testing.T) { 655 Convey("Utils", t, func() { 656 ok := haveSameArgs(field{"query", []struct { 657 Name string `json:"name"` 658 }{ 659 {Name: "arg1"}, {Name: "arg2"}, 660 }}, GQLQuery{ 661 Name: "query", Args: []string{"arg1"}, 662 }) 663 So(ok, ShouldBeFalse) 664 665 ok = haveSameArgs(field{"query", []struct { 666 Name string `json:"name"` 667 }{ 668 {Name: "arg1"}, {Name: "arg2"}, 669 }}, GQLQuery{ 670 Name: "query", Args: []string{"arg1", "arg3"}, 671 }) 672 So(ok, ShouldBeFalse) 673 674 err := containsGQLQueryWithParams( 675 []field{ 676 {Name: "query"}, 677 }, 678 []typeInfo{}, 679 GQLQuery{Name: "other-name"}, 680 ) 681 So(err, ShouldNotBeNil) 682 }) 683 684 Convey("GetConfigOptions", t, func() { 685 // no flags 686 cmd := &cobra.Command{} 687 isSpinner, verifyTLS, err := GetCliConfigOptions(cmd) 688 So(err, ShouldNotBeNil) 689 So(isSpinner, ShouldBeFalse) 690 So(verifyTLS, ShouldBeFalse) 691 692 // bad showspinner 693 configPath := makeConfigFile(`{"configs":[{"_name":"imagetest","showspinner":"bad", "verify-tls": false}]}`) 694 cmd = &cobra.Command{} 695 cmd.Flags().String(ConfigFlag, "imagetest", "") 696 isSpinner, verifyTLS, err = GetCliConfigOptions(cmd) 697 So(err, ShouldNotBeNil) 698 So(isSpinner, ShouldBeFalse) 699 So(verifyTLS, ShouldBeFalse) 700 os.Remove(configPath) 701 702 // bad verify-tls 703 configPath = makeConfigFile(`{"configs":[{"_name":"imagetest","showspinner":false, "verify-tls": "bad"}]}`) 704 cmd = &cobra.Command{} 705 cmd.Flags().String(ConfigFlag, "imagetest", "") 706 isSpinner, verifyTLS, err = GetCliConfigOptions(cmd) 707 So(err, ShouldNotBeNil) 708 So(isSpinner, ShouldBeFalse) 709 So(verifyTLS, ShouldBeFalse) 710 os.Remove(configPath) 711 }) 712 713 Convey("GetServerURLFromFlags", t, func() { 714 cmd := &cobra.Command{} 715 cmd.Flags().String(URLFlag, "url", "") 716 url, err := GetServerURLFromFlags(cmd) 717 So(url, ShouldResemble, "url") 718 So(err, ShouldBeNil) 719 720 // err no config or url 721 cmd = &cobra.Command{} 722 url, err = GetServerURLFromFlags(cmd) 723 So(url, ShouldResemble, "") 724 So(err, ShouldNotBeNil) 725 726 // err ulr from config is empty 727 configPath := makeConfigFile(`{"configs":[{"_name":"imagetest"}]}`) 728 cmd = &cobra.Command{} 729 cmd.Flags().String(ConfigFlag, "imagetest", "") 730 url, err = GetServerURLFromFlags(cmd) 731 So(url, ShouldResemble, "") 732 So(err, ShouldNotBeNil) 733 os.Remove(configPath) 734 735 // err reading the server url from config 736 configPath = makeConfigFile("{}") 737 cmd = &cobra.Command{} 738 cmd.Flags().String(ConfigFlag, "imagetest", "") 739 url, err = GetServerURLFromFlags(cmd) 740 So(url, ShouldResemble, "") 741 So(err, ShouldNotBeNil) 742 os.Remove(configPath) 743 }) 744 745 Convey("CheckExtEndPointQuery", t, func() { 746 // invalid url 747 err := CheckExtEndPointQuery(SearchConfig{ 748 User: "", 749 ServURL: "bad-url", 750 }) 751 So(err, ShouldNotBeNil) 752 753 // good url but no connection 754 err = CheckExtEndPointQuery(SearchConfig{ 755 User: "", 756 ServURL: "http://127.0.0.1:5000", 757 VerifyTLS: false, 758 Debug: false, 759 ResultWriter: io.Discard, 760 }) 761 So(err, ShouldNotBeNil) 762 }) 763 }