github.com/creativeprojects/go-selfupdate@v1.2.0/detect_test.go (about) 1 package selfupdate 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 stdlog "log" 8 "os" 9 "strconv" 10 "strings" 11 "testing" 12 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/require" 15 ) 16 17 var ( 18 testGithubRepository = NewRepositorySlug("creativeprojects", "resticprofile") 19 ) 20 21 func skipRateLimitExceeded(t *testing.T, err error) { 22 if err == nil { 23 return 24 } 25 if strings.Contains(err.Error(), "403 API rate limit") { 26 t.Skip("Test skipped because of GitHub API rate limit exceeded") 27 } 28 } 29 30 func TestDetectReleaseWithVersionPrefix(t *testing.T) { 31 testData := []struct { 32 run bool 33 name string 34 updater *Updater 35 }{ 36 {true, "Mock", newMockUpdater(t, Config{Source: mockSourceRepository(t)})}, 37 {!testing.Short(), "GitHub", DefaultUpdater()}, 38 } 39 40 for _, testItem := range testData { 41 if !testItem.run { 42 continue 43 } 44 t.Run(testItem.name, func(t *testing.T) { 45 r, ok, err := testItem.updater.DetectLatest(context.Background(), testGithubRepository) 46 skipRateLimitExceeded(t, err) 47 require.NoError(t, err) 48 assert.True(t, ok, "Failed to detect latest") 49 require.NotNil(t, r, "No release returned") 50 if r.LessThan("0.10.0") { 51 t.Error("Incorrect version:", r.Version()) 52 } 53 if !strings.HasSuffix(r.AssetURL, ".zip") && !strings.HasSuffix(r.AssetURL, ".tar.gz") { 54 t.Error("Incorrect URL for asset:", r.AssetURL) 55 } 56 assert.NotEmpty(t, r.URL, "Document URL should not be empty") 57 assert.NotEmpty(t, r.ReleaseNotes, "Description should not be empty for this repo") 58 assert.NotEmpty(t, r.Name, "Release name is unexpectedly empty") 59 assert.NotEmpty(t, r.AssetByteSize, "Asset's size is unexpectedly zero") 60 assert.NotEmpty(t, r.AssetID, "Asset's ID is unexpectedly zero") 61 assert.NotZero(t, r.PublishedAt, "Release time is unexpectedly zero") 62 }) 63 } 64 } 65 66 func TestDetectVersionExisting(t *testing.T) { 67 testVersion := "v0.10.0" 68 gitHub, _ := NewUpdater(Config{Validator: &ChecksumValidator{UniqueFilename: "checksums.txt"}}) 69 testData := []struct { 70 run bool 71 name string 72 updater *Updater 73 }{ 74 {true, "Mock", newMockUpdater(t, Config{Source: mockSourceRepository(t), Validator: &ChecksumValidator{UniqueFilename: "checksums.txt"}})}, 75 {!testing.Short(), "GitHub", gitHub}, 76 } 77 78 for _, testItem := range testData { 79 if !testItem.run { 80 continue 81 } 82 t.Run(testItem.name, func(t *testing.T) { 83 r, ok, err := testItem.updater.DetectVersion(context.Background(), testGithubRepository, testVersion) 84 skipRateLimitExceeded(t, err) 85 require.NoError(t, err) 86 assert.Truef(t, ok, "Failed to detect %s", testVersion) 87 require.NotNil(t, r, "No release returned") 88 assert.Greater(t, r.ValidationAssetID, int64(-1)) 89 }) 90 } 91 } 92 93 func TestDetectVersionExistingWithNoValidationFile(t *testing.T) { 94 testVersion := "v0.10.0" 95 gitHub, _ := NewUpdater(Config{Validator: &ChecksumValidator{UniqueFilename: "notfound.txt"}}) 96 testData := []struct { 97 run bool 98 name string 99 updater *Updater 100 }{ 101 {true, "Mock", newMockUpdater(t, Config{Source: mockSourceRepository(t), Validator: &ChecksumValidator{UniqueFilename: "notfound.txt"}})}, 102 {!testing.Short(), "GitHub", gitHub}, 103 } 104 105 for _, testItem := range testData { 106 if !testItem.run { 107 continue 108 } 109 t.Run(testItem.name, func(t *testing.T) { 110 _, _, err := testItem.updater.DetectVersion(context.Background(), testGithubRepository, testVersion) 111 skipRateLimitExceeded(t, err) 112 require.Error(t, err) 113 assert.True(t, errors.Is(err, ErrValidationAssetNotFound)) 114 }) 115 } 116 } 117 118 func TestDetectVersionNotExisting(t *testing.T) { 119 testData := []struct { 120 run bool 121 name string 122 updater *Updater 123 }{ 124 {true, "Mock", newMockUpdater(t, Config{Source: mockSourceRepository(t)})}, 125 {!testing.Short(), "GitHub", DefaultUpdater()}, 126 } 127 128 for _, testItem := range testData { 129 if !testItem.run { 130 continue 131 } 132 t.Run(testItem.name, func(t *testing.T) { 133 r, ok, err := testItem.updater.DetectVersion(context.Background(), testGithubRepository, "foobar") 134 skipRateLimitExceeded(t, err) 135 require.NoError(t, err) 136 assert.False(t, ok, "Failed to correctly detect foobar") 137 assert.Nil(t, r, "Release not detected but got a returned value for it") 138 }) 139 } 140 } 141 142 func TestDetectPrerelease(t *testing.T) { 143 testFixtures := []struct { 144 prerelease bool 145 version string 146 }{ 147 {false, "1.0.0"}, 148 {true, "2.0.0-beta"}, 149 } 150 for _, testFixture := range testFixtures { 151 t.Run(strconv.FormatBool(testFixture.prerelease), func(t *testing.T) { 152 updater := newMockUpdater(t, Config{ 153 Source: mockSourceRepository(t), 154 Prerelease: testFixture.prerelease, 155 }) 156 r, ok, err := updater.DetectLatest(context.Background(), RepositorySlug{owner: "owner", repo: "repo"}) 157 require.NotNil(t, r) 158 assert.True(t, ok) 159 assert.NoError(t, err) 160 161 assert.Equal(t, testFixture.prerelease, r.Prerelease) 162 assert.Equal(t, testFixture.version, r.Version()) 163 }) 164 } 165 } 166 167 func TestDetectReleasesForVariousArchives(t *testing.T) { 168 for _, tc := range []struct { 169 slug string 170 prefix string 171 }{ 172 {"rhysd-test/test-release-zip", "v"}, 173 {"rhysd-test/test-release-tar", "v"}, 174 {"rhysd-test/test-release-gzip", "v"}, 175 {"rhysd-test/test-release-xz", "release-v"}, 176 {"rhysd-test/test-release-tar-xz", "release-"}, 177 } { 178 t.Run(tc.slug, func(t *testing.T) { 179 source, err := NewGitHubSource(GitHubConfig{}) 180 require.NoError(t, err, "failed to create source") 181 updater, err := NewUpdater(Config{Source: source, Arch: "amd64"}) 182 require.NoError(t, err, "failed to create updater") 183 r, ok, err := updater.DetectLatest(context.Background(), ParseSlug(tc.slug)) 184 skipRateLimitExceeded(t, err) 185 186 assert.NoError(t, err, "fetch failed") 187 assert.True(t, ok, "not found") 188 require.NotNil(t, r, "release not detected") 189 assert.Truef(t, r.Equal("1.2.3"), "incorrect release: expected 1.2.3 but got %v", r.Version()) 190 191 url := fmt.Sprintf("https://github.com/%s/releases/tag/%s1.2.3", tc.slug, tc.prefix) 192 assert.Equal(t, url, r.URL) 193 assert.NotEmpty(t, r.ReleaseNotes, "Release note is unexpectedly empty") 194 195 if !strings.HasPrefix(r.AssetURL, fmt.Sprintf("https://github.com/%s/releases/download/%s1.2.3/", tc.slug, tc.prefix)) { 196 t.Error("Unexpected asset URL:", r.AssetURL) 197 } 198 199 assert.NotEmpty(t, r.Name, "Release name is unexpectedly empty") 200 assert.NotEmpty(t, r.AssetByteSize, "Asset's size is unexpectedly zero") 201 assert.NotEmpty(t, r.AssetID, "Asset's ID is unexpectedly zero") 202 assert.NotZero(t, r.PublishedAt) 203 }) 204 } 205 } 206 207 func TestDetectReleaseButNoAsset(t *testing.T) { 208 testData := []struct { 209 run bool 210 name string 211 updater *Updater 212 }{ 213 {true, "Mock", newMockUpdater(t, Config{Source: NewMockSource( 214 []SourceRelease{ 215 &GitHubRelease{ 216 name: "first", 217 tagName: "v1.0", 218 assets: nil, 219 }, 220 &GitHubRelease{ 221 name: "second", 222 tagName: "v2.0", 223 assets: nil, 224 }, 225 }, 226 nil, 227 )})}, 228 {!testing.Short(), "GitHub", DefaultUpdater()}, 229 } 230 231 for _, testItem := range testData { 232 if !testItem.run { 233 continue 234 } 235 t.Run(testItem.name, func(t *testing.T) { 236 _, ok, err := testItem.updater.DetectLatest(context.Background(), ParseSlug("rhysd/clever-f.vim")) 237 skipRateLimitExceeded(t, err) 238 require.NoError(t, err) 239 assert.False(t, ok, "When no asset found, result should be marked as 'not found'") 240 }) 241 } 242 } 243 244 func TestNonExistingRepo(t *testing.T) { 245 testData := []struct { 246 run bool 247 name string 248 updater *Updater 249 }{ 250 {true, "Mock", newMockUpdater(t, Config{Source: NewMockSource(nil, nil)})}, 251 {!testing.Short(), "GitHub", DefaultUpdater()}, 252 } 253 254 for _, testItem := range testData { 255 if !testItem.run { 256 continue 257 } 258 t.Run(testItem.name, func(t *testing.T) { 259 _, ok, err := testItem.updater.DetectLatest(context.Background(), ParseSlug("rhysd/non-existing-repo")) 260 skipRateLimitExceeded(t, err) 261 require.NoError(t, err) 262 assert.False(t, ok, "Release for non-existing repo should not be found") 263 }) 264 } 265 } 266 267 func TestNoReleaseFound(t *testing.T) { 268 testData := []struct { 269 run bool 270 name string 271 updater *Updater 272 }{ 273 {true, "Mock", newMockUpdater(t, Config{Source: NewMockSource(nil, nil)})}, 274 {!testing.Short(), "GitHub", DefaultUpdater()}, 275 } 276 277 for _, testItem := range testData { 278 if !testItem.run { 279 continue 280 } 281 t.Run(testItem.name, func(t *testing.T) { 282 _, ok, err := testItem.updater.DetectLatest(context.Background(), ParseSlug("rhysd/misc")) 283 skipRateLimitExceeded(t, err) 284 require.NoError(t, err) 285 assert.False(t, ok, "Repo having no release should not be found") 286 }) 287 } 288 } 289 290 func TestFindAssetFromRelease(t *testing.T) { 291 type findReleaseAndAssetFixture struct { 292 name string 293 config Config 294 release SourceRelease 295 targetVersion string 296 expectedAsset string 297 expectedVersion string 298 expectedFound bool 299 } 300 301 rel1 := "rel1" 302 v1 := "1.0.0" 303 rel11 := "rel11" 304 v11 := "1.1.0" 305 asset1 := "asset1.gz" 306 asset2 := "asset2.gz" 307 wrongAsset1 := "asset1.yaml" 308 asset11 := "asset11.gz" 309 url1 := "https://asset1" 310 url2 := "https://asset2" 311 url11 := "https://asset11" 312 313 testData := []findReleaseAndAssetFixture{ 314 { 315 name: "empty fixture", 316 config: Config{}, 317 release: nil, 318 targetVersion: "", 319 expectedFound: false, 320 }, 321 { 322 name: "find asset, no filters", 323 release: &GitHubRelease{ 324 name: rel1, 325 tagName: v1, 326 assets: []SourceAsset{ 327 &GitHubAsset{name: asset1, url: url1}, 328 }, 329 }, 330 targetVersion: "1.0.0", 331 expectedAsset: asset1, 332 expectedVersion: "1.0.0", 333 expectedFound: true, 334 }, 335 { 336 name: "find asset, no target version", 337 release: &GitHubRelease{ 338 name: rel1, 339 tagName: v1, 340 assets: []SourceAsset{ 341 &GitHubAsset{name: asset1, url: url1}, 342 }, 343 }, 344 targetVersion: "", 345 expectedAsset: asset1, 346 expectedVersion: "1.0.0", 347 expectedFound: true, 348 }, 349 { 350 name: "don't find prerelease", 351 release: &GitHubRelease{ 352 name: rel1, 353 tagName: v1, 354 assets: []SourceAsset{ 355 &GitHubAsset{name: asset1, url: url1}, 356 }, 357 prerelease: true, 358 }, 359 targetVersion: "", 360 expectedAsset: asset1, 361 expectedVersion: "1.0.0", 362 expectedFound: false, 363 }, 364 { 365 name: "find named prerelease", 366 release: &GitHubRelease{ 367 name: rel1, 368 tagName: v1, 369 assets: []SourceAsset{ 370 &GitHubAsset{name: asset1, url: url1}, 371 }, 372 prerelease: true, 373 }, 374 targetVersion: "1.0.0", 375 expectedAsset: asset1, 376 expectedVersion: "1.0.0", 377 expectedFound: true, 378 }, 379 { 380 name: "find prerelease", 381 config: Config{Prerelease: true}, 382 release: &GitHubRelease{ 383 name: rel1, 384 tagName: v1, 385 assets: []SourceAsset{ 386 &GitHubAsset{name: asset1, url: url1}, 387 }, 388 prerelease: true, 389 }, 390 targetVersion: "", 391 expectedAsset: asset1, 392 expectedVersion: "1.0.0", 393 expectedFound: true, 394 }, 395 { 396 name: "don't find asset with wrong extension, no filters", 397 release: &GitHubRelease{ 398 name: rel11, 399 tagName: v11, 400 assets: []SourceAsset{ 401 &GitHubAsset{name: wrongAsset1, url: url11}, 402 }, 403 }, 404 targetVersion: "1.1.0", 405 expectedFound: false, 406 }, 407 { 408 name: "find asset with different name, no filters", 409 release: &GitHubRelease{ 410 name: rel11, 411 tagName: v11, 412 assets: []SourceAsset{ 413 &GitHubAsset{name: asset1, url: url11}, 414 }, 415 }, 416 targetVersion: "1.1.0", 417 expectedAsset: asset1, 418 expectedVersion: "1.1.0", 419 expectedFound: true, 420 }, 421 { 422 name: "find asset, no filters (2)", 423 release: &GitHubRelease{ 424 name: rel11, 425 tagName: v11, 426 assets: []SourceAsset{ 427 &GitHubAsset{name: asset11, url: url11}, 428 }, 429 }, 430 targetVersion: "1.1.0", 431 expectedAsset: asset11, 432 expectedVersion: "1.1.0", 433 expectedFound: true, 434 }, 435 { 436 name: "find asset, match filter", 437 release: &GitHubRelease{ 438 name: rel11, 439 tagName: v11, 440 assets: []SourceAsset{ 441 &GitHubAsset{name: asset11, url: url11}, 442 &GitHubAsset{name: asset1, url: url1}, 443 }, 444 }, 445 targetVersion: "1.1.0", 446 config: Config{Filters: []string{"11"}}, 447 expectedAsset: asset11, 448 expectedVersion: "1.1.0", 449 expectedFound: true, 450 }, 451 { 452 name: "find asset, match another filter", 453 release: &GitHubRelease{ 454 name: rel11, 455 tagName: v11, 456 assets: []SourceAsset{ 457 &GitHubAsset{name: asset11, url: url11}, 458 &GitHubAsset{name: asset1, url: url1}, 459 }, 460 }, 461 targetVersion: "1.1.0", 462 config: Config{Filters: []string{"([^1])1{1}([^1])"}}, 463 expectedAsset: asset1, 464 expectedVersion: "1.1.0", 465 expectedFound: true, 466 }, 467 { 468 name: "find asset, match any filter", 469 release: &GitHubRelease{ 470 name: rel11, 471 tagName: v11, 472 assets: []SourceAsset{ 473 &GitHubAsset{name: asset11, url: url11}, 474 &GitHubAsset{name: asset2, url: url2}, 475 }, 476 }, 477 targetVersion: "1.1.0", 478 config: Config{Filters: []string{"([^1])1{1}([^1])", "([^1])2{1}([^1])"}}, 479 expectedAsset: asset2, 480 expectedVersion: "1.1.0", 481 expectedFound: true, 482 }, 483 { 484 name: "find asset, match no filter", 485 release: &GitHubRelease{ 486 name: rel11, 487 tagName: v11, 488 assets: []SourceAsset{ 489 &GitHubAsset{name: asset11, url: url11}, 490 &GitHubAsset{name: asset2, url: url2}, 491 }, 492 }, 493 targetVersion: "", 494 config: Config{Filters: []string{"another", "binary"}}, 495 expectedFound: false, 496 }, 497 } 498 499 for _, fixture := range testData { 500 t.Run(fixture.name, func(t *testing.T) { 501 updater := newMockUpdater(t, fixture.config) 502 asset, ver, found := updater.findAssetFromRelease(fixture.release, []string{".gz"}, fixture.targetVersion) 503 if fixture.expectedFound { 504 if !found { 505 t.Fatalf("expected to find an asset for this fixture: %q", fixture.name) 506 } 507 if asset.GetName() == "" { 508 t.Fatalf("invalid asset struct returned from fixture: %q, got: %v", fixture.name, asset) 509 } 510 if asset.GetName() != fixture.expectedAsset { 511 t.Fatalf("expected asset %q in fixture: %q, got: %s", fixture.expectedAsset, fixture.name, asset.GetName()) 512 } 513 t.Logf("asset %v, %v", asset, ver) 514 } else if found { 515 t.Fatalf("expected not to find an asset for this fixture: %q, but got: %v", fixture.name, asset) 516 } 517 }) 518 } 519 } 520 521 func TestFindReleaseAndAsset(t *testing.T) { 522 SetLogger(stdlog.New(os.Stderr, "", 0)) 523 defer SetLogger(&emptyLogger{}) 524 525 tag2 := "v2.0.0" 526 rel2 := "rel2" 527 assetLinux386 := "asset_linux_386.tgz" 528 assetLinuxAMD64 := "asset_linux_amd64.tgz" 529 assetLinuxX86_64 := "asset_linux_x86_64.tgz" 530 assetLinuxARM := "asset_linux_arm.tgz" 531 assetLinuxARMv5 := "asset_linux_armv5.tgz" 532 assetLinuxARMv6 := "asset_linux_armv6.tgz" 533 assetLinuxARMv7 := "asset_linux_armv7.tgz" 534 assetLinuxARM64 := "asset_linux_arm64.tgz" 535 testData := []struct { 536 name string 537 os string 538 arch string 539 arm uint8 540 releases []SourceRelease 541 version string 542 filters []string 543 found bool 544 expectedAssetName string 545 }{ 546 { 547 name: "no match", 548 os: "darwin", 549 arch: "amd64", 550 releases: []SourceRelease{ 551 &GitHubRelease{ 552 name: rel2, 553 tagName: tag2, 554 assets: []SourceAsset{ 555 &GitHubAsset{ 556 name: assetLinux386, 557 }, 558 &GitHubAsset{ 559 name: assetLinuxAMD64, 560 }, 561 }, 562 }, 563 }, 564 version: "v2.0.0", 565 filters: nil, 566 found: false, 567 expectedAssetName: assetLinuxAMD64, 568 }, 569 { 570 name: "simple match", 571 os: "linux", 572 arch: "amd64", 573 releases: []SourceRelease{ 574 &GitHubRelease{ 575 name: rel2, 576 tagName: tag2, 577 assets: []SourceAsset{ 578 &GitHubAsset{ 579 name: assetLinux386, 580 }, 581 &GitHubAsset{ 582 name: assetLinuxAMD64, 583 }, 584 }, 585 }, 586 }, 587 version: "v2.0.0", 588 filters: nil, 589 found: true, 590 expectedAssetName: assetLinuxAMD64, 591 }, 592 { 593 name: "simple match case insensitive", 594 os: "linux", 595 arch: "amd64", 596 releases: []SourceRelease{ 597 &GitHubRelease{ 598 name: rel2, 599 tagName: tag2, 600 assets: []SourceAsset{ 601 &GitHubAsset{ 602 name: assetLinux386, 603 }, 604 &GitHubAsset{ 605 name: "asset_Linux_AMD64.tgz", 606 }, 607 }, 608 }, 609 }, 610 version: "v2.0.0", 611 filters: nil, 612 found: true, 613 expectedAssetName: "asset_Linux_AMD64.tgz", 614 }, 615 { 616 name: "match default arm", 617 os: "linux", 618 arch: "arm", 619 releases: []SourceRelease{ 620 &GitHubRelease{ 621 name: rel2, 622 tagName: tag2, 623 assets: []SourceAsset{ 624 &GitHubAsset{ 625 name: assetLinuxARM, 626 }, 627 &GitHubAsset{ 628 name: assetLinuxARM64, 629 }, 630 &GitHubAsset{ 631 name: assetLinuxARMv5, 632 }, 633 &GitHubAsset{ 634 name: assetLinuxARMv6, 635 }, 636 &GitHubAsset{ 637 name: assetLinuxARMv7, 638 }, 639 }, 640 }, 641 }, 642 version: "v2.0.0", 643 filters: nil, 644 found: true, 645 expectedAssetName: assetLinuxARM, 646 }, 647 { 648 name: "match armv6", 649 os: "linux", 650 arch: "arm", 651 arm: 6, 652 releases: []SourceRelease{ 653 &GitHubRelease{ 654 name: rel2, 655 tagName: tag2, 656 assets: []SourceAsset{ 657 &GitHubAsset{ 658 name: assetLinuxARM, 659 }, 660 &GitHubAsset{ 661 name: assetLinuxARM64, 662 }, 663 &GitHubAsset{ 664 name: assetLinuxARMv5, 665 }, 666 &GitHubAsset{ 667 name: assetLinuxARMv6, 668 }, 669 &GitHubAsset{ 670 name: assetLinuxARMv7, 671 }, 672 }, 673 }, 674 }, 675 version: "v2.0.0", 676 filters: nil, 677 found: true, 678 expectedAssetName: assetLinuxARMv6, 679 }, 680 { 681 name: "fallback to armv5", 682 os: "linux", 683 arch: "arm", 684 arm: 7, 685 releases: []SourceRelease{ 686 &GitHubRelease{ 687 name: rel2, 688 tagName: tag2, 689 assets: []SourceAsset{ 690 &GitHubAsset{ 691 name: assetLinuxARM, 692 }, 693 &GitHubAsset{ 694 name: assetLinuxARM64, 695 }, 696 &GitHubAsset{ 697 name: assetLinuxARMv5, 698 }, 699 }, 700 }, 701 }, 702 version: "v2.0.0", 703 filters: nil, 704 found: true, 705 expectedAssetName: assetLinuxARMv5, 706 }, 707 { 708 name: "fallback to arm", 709 os: "linux", 710 arch: "arm", 711 arm: 5, 712 releases: []SourceRelease{ 713 &GitHubRelease{ 714 name: rel2, 715 tagName: tag2, 716 assets: []SourceAsset{ 717 &GitHubAsset{ 718 name: assetLinuxARM, 719 }, 720 &GitHubAsset{ 721 name: assetLinuxARM64, 722 }, 723 }, 724 }, 725 }, 726 version: "v2.0.0", 727 filters: nil, 728 found: true, 729 expectedAssetName: assetLinuxARM, 730 }, 731 { 732 name: "arm not found", 733 os: "linux", 734 arch: "arm", 735 arm: 6, 736 releases: []SourceRelease{ 737 &GitHubRelease{ 738 name: rel2, 739 tagName: tag2, 740 assets: []SourceAsset{ 741 &GitHubAsset{ 742 name: assetLinuxARMv7, 743 }, 744 &GitHubAsset{ 745 name: assetLinuxARM64, 746 }, 747 }, 748 }, 749 }, 750 version: "v2.0.0", 751 filters: nil, 752 found: false, 753 expectedAssetName: assetLinuxARM, 754 }, 755 { 756 name: "match x86_64 for adm64", 757 os: "linux", 758 arch: "amd64", 759 releases: []SourceRelease{ 760 &GitHubRelease{ 761 name: rel2, 762 tagName: tag2, 763 assets: []SourceAsset{ 764 &GitHubAsset{ 765 name: assetLinux386, 766 }, 767 &GitHubAsset{ 768 name: assetLinuxX86_64, 769 }, 770 }, 771 }, 772 }, 773 version: "v2.0.0", 774 filters: nil, 775 found: true, 776 expectedAssetName: assetLinuxX86_64, 777 }, 778 } 779 780 for _, testItem := range testData { 781 t.Run(testItem.name, func(t *testing.T) { 782 updater, err := NewUpdater(Config{ 783 Filters: testItem.filters, 784 OS: testItem.os, 785 Arch: testItem.arch, 786 Arm: testItem.arm, 787 }) 788 require.NoError(t, err) 789 _, asset, _, found := updater.findReleaseAndAsset(testItem.releases, testItem.version) 790 assert.Equal(t, testItem.found, found) 791 if found { 792 assert.Equal(t, testItem.expectedAssetName, asset.GetName()) 793 } 794 }) 795 } 796 } 797 798 func TestBuildMultistepValidationChain(t *testing.T) { 799 testVersion := "v0.10.0" 800 source, keyRing := mockPGPSourceRepository(t) 801 checksumValidator := &ChecksumValidator{UniqueFilename: "checksums.txt"} 802 803 t.Run("ValidConfig", func(t *testing.T) { 804 updater, _ := NewUpdater(Config{ 805 Source: source, 806 Validator: NewChecksumWithPGPValidator("checksums.txt", keyRing), 807 }) 808 809 release, found, err := updater.DetectVersion(context.Background(), testGithubRepository, testVersion) 810 require.True(t, found) 811 assert.NoError(t, err) 812 assert.Equal(t, 2, len(release.ValidationChain)) 813 assert.Equal(t, "checksums.txt", release.ValidationChain[0].ValidationAssetName) 814 assert.Equal(t, "checksums.txt.asc", release.ValidationChain[1].ValidationAssetName) 815 }) 816 817 t.Run("LoopConfig", func(t *testing.T) { 818 updater, _ := NewUpdater(Config{ 819 Source: source, 820 Validator: new(PatternValidator). 821 Add("*", checksumValidator), 822 }) 823 824 _, _, err := updater.DetectVersion(context.Background(), testGithubRepository, testVersion) 825 assert.NoError(t, err) 826 }) 827 828 t.Run("InvalidLoopConfig", func(t *testing.T) { 829 updater, _ := NewUpdater(Config{ 830 Source: source, 831 Validator: new(PatternValidator). 832 Add("*.*z*", checksumValidator). 833 Add("*", new(SHAValidator)), 834 }) 835 836 _, _, err := updater.DetectVersion(context.Background(), testGithubRepository, testVersion) 837 assert.EqualError(t, err, "validation file not found: \"checksums.txt.sha256\"") 838 }) 839 } 840 841 func newMockUpdater(t *testing.T, config Config) *Updater { 842 t.Helper() 843 updater, err := NewUpdater(config) 844 require.NoError(t, err) 845 return updater 846 }