From 79d641a2f6057818f6ed229fc41b9392c4925221 Mon Sep 17 00:00:00 2001 From: rhysd Date: Sat, 30 Dec 2017 01:37:09 +0900 Subject: [PATCH] add tests for downloading and updating binary --- selfupdate/detect_test.go | 38 +++++ selfupdate/e2e_test.go | 7 +- .../testdata/github-release-test/main.go | 5 + selfupdate/update.go | 4 +- selfupdate/update_test.go | 137 ++++++++++++++++++ 5 files changed, 188 insertions(+), 3 deletions(-) create mode 100644 selfupdate/testdata/github-release-test/main.go create mode 100644 selfupdate/update_test.go diff --git a/selfupdate/detect_test.go b/selfupdate/detect_test.go index 11f3466..f077283 100644 --- a/selfupdate/detect_test.go +++ b/selfupdate/detect_test.go @@ -1,6 +1,7 @@ package selfupdate import ( + "fmt" "github.com/blang/semver" "os" "strings" @@ -40,6 +41,40 @@ func TestDetectReleaseWithVersionPrefix(t *testing.T) { } } +func TestDetectReleasesForVariousArchives(t *testing.T) { + for _, repo := range []string{ + "rhysd-test/test-release-zip", + "rhysd-test/test-release-tar", + "rhysd-test/test-release-gzip", + } { + t.Run(repo, func(t *testing.T) { + r, ok, err := DetectLatest(repo) + if err != nil { + t.Fatal("Fetch failed:", err) + } + if !ok { + t.Fatal(repo, "not found") + } + if r == nil { + t.Fatal("Release not detected") + } + if !r.Version.Equals(semver.MustParse("1.2.3")) { + t.Error("") + } + url := fmt.Sprintf("https://github.com/%s/releases/tag/v1.2.3", repo) + if r.URL != url { + t.Error("URL is not wrong. Want", url, "but got", r.URL) + } + if r.ReleaseNotes == "" { + t.Error("Release note is unexpectedly empty") + } + if !strings.HasPrefix(r.AssetURL, fmt.Sprintf("https://github.com/%s/releases/download/v1.2.3/", repo)) { + t.Error("Unexpected asset URL:", r.AssetURL) + } + }) + } +} + func TestDetectReleaseButNoAsset(t *testing.T) { _, ok, err := DetectLatest("rhysd/clever-f.vim") if err != nil { @@ -74,6 +109,9 @@ func TestInvalidSlug(t *testing.T) { if err == nil { t.Error(slug, "should be invalid slug") } + if !strings.Contains(err.Error(), "Invalid slug format") { + t.Error("Unexpected error for", slug, ":", err) + } } } diff --git a/selfupdate/e2e_test.go b/selfupdate/e2e_test.go index 94eeeed..6ae1481 100644 --- a/selfupdate/e2e_test.go +++ b/selfupdate/e2e_test.go @@ -1,6 +1,7 @@ package selfupdate import ( + "os" "os/exec" "testing" ) @@ -10,8 +11,12 @@ func TestRunSelfUpdateExample(t *testing.T) { t.Skip("skipping test in short mode.") } + t.Skip("TODO") + if err := exec.Command("go", "build", "../cmd/selfupdate-example").Run(); err != nil { t.Fatal(err) } - t.Fatal("TODO") + defer os.Remove("selfupdate-example") + + // TODO } diff --git a/selfupdate/testdata/github-release-test/main.go b/selfupdate/testdata/github-release-test/main.go new file mode 100644 index 0000000..d4ee4c4 --- /dev/null +++ b/selfupdate/testdata/github-release-test/main.go @@ -0,0 +1,5 @@ +package main + +func main() { + println("not released yet!") +} diff --git a/selfupdate/update.go b/selfupdate/update.go index 592822a..77a3612 100644 --- a/selfupdate/update.go +++ b/selfupdate/update.go @@ -13,11 +13,11 @@ import ( func UpdateTo(assetURL, cmdPath string) error { res, err := http.Get(assetURL) if err != nil { - return err + return fmt.Errorf("Failed to download a release file from %s: %s", assetURL, err) } if res.StatusCode != 200 { - return fmt.Errorf("Failed to download a release file from %s ", assetURL) + return fmt.Errorf("Failed to download a release file from %s", assetURL) } defer res.Body.Close() diff --git a/selfupdate/update_test.go b/selfupdate/update_test.go new file mode 100644 index 0000000..bba6036 --- /dev/null +++ b/selfupdate/update_test.go @@ -0,0 +1,137 @@ +package selfupdate + +import ( + "github.com/blang/semver" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" +) + +func setupTestBinary() { + if err := exec.Command("go", "build", "./testdata/github-release-test/").Run(); err != nil { + panic(err) + } +} + +func teardownTestBinary() { + if err := os.Remove("github-release-test"); err != nil { + panic(err) + } +} + +func TestUpdateCommand(t *testing.T) { + if testing.Short() { + t.Skip("skip tests in short mode.") + } + + for _, slug := range []string{ + "rhysd-test/test-release-zip", + "rhysd-test/test-release-tar", + "rhysd-test/test-release-gzip", + } { + t.Run(slug, func(t *testing.T) { + setupTestBinary() + defer teardownTestBinary() + latest := semver.MustParse("1.2.3") + prev := semver.MustParse("1.2.2") + rel, err := UpdateCommand("github-release-test", prev, slug) + if err != nil { + t.Fatal(err) + } + if rel.Version.NE(latest) { + t.Error("Version is not latest", rel.Version) + } + bytes, err := exec.Command(filepath.FromSlash("./github-release-test")).Output() + if err != nil { + t.Fatal("Failed to run test binary after update:", err) + } + out := string(bytes) + if out != "v1.2.3\n" { + t.Error("Output from test binary after update is unexpected:", out) + } + }) + } +} + +func TestNoReleaseFoundForUpdate(t *testing.T) { + v := semver.MustParse("1.0.0") + rel, err := UpdateCommand("foo", v, "rhysd/misc") + if err != nil { + t.Fatal("No release should not make an error:", err) + } + if rel.Version.NE(v) { + t.Error("No release should return the current version as the latest:", rel.Version) + } + if rel.URL != "" { + t.Error("Browse URL should be empty when no release found:", rel.URL) + } + if rel.AssetURL != "" { + t.Error("Asset URL should be empty when no release found:", rel.AssetURL) + } + if rel.ReleaseNotes != "" { + t.Error("Release notes should be empty when no release found:", rel.ReleaseNotes) + } +} + +func TestCurrentIsTheLatest(t *testing.T) { + v := semver.MustParse("1.2.3") + rel, err := UpdateCommand("github-release-test", v, "rhysd-test/test-release-zip") + if err != nil { + t.Fatal(err) + } + if rel.Version.NE(v) { + t.Error("v1.2.3 should be the latest:", rel.Version) + } + if rel.URL == "" { + t.Error("Browse URL should not be empty when release found:", rel.URL) + } + if rel.AssetURL == "" { + t.Error("Asset URL should not be empty when release found:", rel.AssetURL) + } + if rel.ReleaseNotes == "" { + t.Error("Release notes should not be empty when release found:", rel.ReleaseNotes) + } +} + +func TestBrokenBinaryUpdate(t *testing.T) { + _, err := UpdateCommand("foo", semver.MustParse("1.2.2"), "rhysd-test/test-incorrect-release") + if err == nil { + t.Fatal("Error should occur for broken package") + } + if !strings.Contains(err.Error(), "Failed to uncompress .tar.gz file") { + t.Fatal("Unexpected error:", err) + } +} + +func TestInvalidSlugForUpdate(t *testing.T) { + _, err := UpdateCommand("foo", semver.MustParse("1.0.0"), "rhysd/") + if err == nil { + t.Fatal("Unknown repo should cause an error") + } + if !strings.Contains(err.Error(), "Invalid slug format") { + t.Fatal("Unexpected error:", err) + } +} + +func TestInvalidAssetURL(t *testing.T) { + err := UpdateTo("https://github.com/rhysd/non-existing-repo/releases/download/v1.2.3/foo.zip", "foo") + if err == nil { + t.Fatal("Error should occur for URL not found") + } + if !strings.Contains(err.Error(), "Failed to download a release file") { + t.Fatal("Unexpected error:", err) + } +} + +func TestBrokenAsset(t *testing.T) { + asset := "https://github.com/rhysd-test/test-incorrect-release/releases/download/invalid/broken-zip.zip" + err := UpdateTo(asset, "foo") + if err == nil { + t.Fatal("Error should occur for URL not found") + } + if !strings.Contains(err.Error(), "Failed to uncompress zip file") { + t.Fatal("Unexpected error:", err) + } +}