add tests for uncompressing .zip and .gzip

This commit is contained in:
rhysd 2017-12-29 19:34:18 +09:00
parent 4e9b48163c
commit 9cf8d19c61
18 changed files with 181 additions and 13 deletions

View File

@ -15,8 +15,4 @@ guard :shell do
puts "#{Time.now}: #{m[0]}"
system 'go build ./cmd/selfupdate-example/'
end
watch /^testdata\// do |m|
system "go test -v -short ./selfupdate/"
end
end

View File

@ -25,7 +25,7 @@ func findSuitableReleaseAndAsset(rels []*github.RepositoryRelease) (*github.Repo
// Generate candidates
cs := make([]string, 0, 8)
for _, sep := range []rune{'_', '-'} {
for _, ext := range []string{".zip", ".tar.gz", ".gzip", ""} {
for _, ext := range []string{".zip", ".tar.gz", ".gzip", ".gz", ""} {
suffix := fmt.Sprintf("%s%c%s%s", runtime.GOOS, sep, runtime.GOARCH, ext)
cs = append(cs, suffix)
if runtime.GOOS == "windows" {

BIN
selfupdate/testdata/bar-not-found.gzip vendored Normal file

Binary file not shown.

BIN
selfupdate/testdata/bar-not-found.tar.gz vendored Normal file

Binary file not shown.

BIN
selfupdate/testdata/bar-not-found.zip vendored Normal file

Binary file not shown.

BIN
selfupdate/testdata/empty.tar.gz vendored Normal file

Binary file not shown.

BIN
selfupdate/testdata/empty.zip vendored Normal file

Binary file not shown.

BIN
selfupdate/testdata/foo.tar.gz vendored Normal file

Binary file not shown.

BIN
selfupdate/testdata/foo.zip vendored Normal file

Binary file not shown.

View File

BIN
selfupdate/testdata/invalid-tar.tar.gz vendored Normal file

Binary file not shown.

0
selfupdate/testdata/invalid.gz vendored Normal file
View File

0
selfupdate/testdata/invalid.zip vendored Normal file
View File

BIN
selfupdate/testdata/single-file.gz vendored Normal file

Binary file not shown.

BIN
selfupdate/testdata/single-file.gzip vendored Normal file

Binary file not shown.

BIN
selfupdate/testdata/single-file.zip vendored Normal file

Binary file not shown.

View File

@ -8,6 +8,7 @@ import (
"fmt"
"io"
"io/ioutil"
"path/filepath"
"strings"
)
@ -17,28 +18,27 @@ func uncompress(src io.Reader, url, cmd string) (io.Reader, error) {
// So we need to read the HTTP response into a buffer at first.
buf, err := ioutil.ReadAll(src)
if err != nil {
return nil, err
return nil, fmt.Errorf("Failed to create buffer for zip file: %s", err)
}
r := bytes.NewReader(buf)
z, err := zip.NewReader(r, r.Size())
if err != nil {
return nil, err
return nil, fmt.Errorf("Failed to uncompress zip file: %s", err)
}
for _, file := range z.File {
if file.Name == cmd {
_, name := filepath.Split(file.Name)
if !file.FileInfo().IsDir() && name == cmd {
return file.Open()
}
}
return nil, fmt.Errorf("File '%s' for the command is not found in %s", cmd, url)
} else if strings.HasSuffix(url, ".gzip") {
return gzip.NewReader(src)
} else if strings.HasSuffix(url, ".tar.gz") {
gz, err := gzip.NewReader(src)
if err != nil {
return nil, err
return nil, fmt.Errorf("Failed to uncompress .tar.gz file: %s", err)
}
t := tar.NewReader(gz)
@ -48,14 +48,27 @@ func uncompress(src io.Reader, url, cmd string) (io.Reader, error) {
break
}
if err != nil {
return nil, err
return nil, fmt.Errorf("Failed to unarchive .tar file: %s", err)
}
if h.Name == cmd {
_, name := filepath.Split(h.Name)
if name == cmd {
return t, nil
}
}
return nil, fmt.Errorf("File '%s' for the command is not found in %s", cmd, url)
} else if strings.HasSuffix(url, ".gzip") || strings.HasSuffix(url, ".gz") {
r, err := gzip.NewReader(src)
if err != nil {
return nil, fmt.Errorf("Failed to uncompress gzip file downloaded from %s: %s", url, err)
}
name := r.Header.Name
if name != cmd {
return nil, fmt.Errorf("File name '%s' does not match to command '%s' found in %s", name, cmd, url)
}
return r, nil
}
return src, nil

View File

@ -0,0 +1,159 @@
package selfupdate
import (
"bytes"
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
)
func TestCompressionNotRequired(t *testing.T) {
buf := []byte{'a', 'b', 'c'}
want := bytes.NewReader(buf)
r, err := uncompress(want, "https://github.com/foo/bar/releases/download/v1.2.3/foo", "foo")
if err != nil {
t.Fatal(err)
}
have, err := ioutil.ReadAll(r)
if err != nil {
t.Fatal(err)
}
for i, b := range have {
if buf[i] != b {
t.Error(i, "th elem is not the same as wanted. want", buf[i], "but got", b)
}
}
}
func TestUncompress(t *testing.T) {
for _, n := range []string{
"testdata/foo.zip",
"testdata/single-file.zip",
"testdata/single-file.gz",
"testdata/single-file.gzip",
"testdata/foo.tar.gz",
} {
t.Run(n, func(t *testing.T) {
f, err := os.Open(n)
if err != nil {
t.Fatal(err)
}
var ext string
if strings.HasSuffix(n, ".tar.gz") {
ext = ".tar.gz"
} else {
ext = filepath.Ext(n)
}
url := "https://github.com/foo/bar/releases/download/v1.2.3/bar" + ext
r, err := uncompress(f, url, "bar")
if err != nil {
t.Fatal(err)
}
bytes, err := ioutil.ReadAll(r)
if err != nil {
t.Fatal(err)
}
s := string(bytes)
if s != "this is test\n" {
t.Fatal("Uncompressing zip failed into unexpected content", s)
}
})
}
}
func TestUncompressInvalidArchive(t *testing.T) {
for _, a := range []struct {
name string
msg string
}{
{"testdata/invalid.zip", "not a valid zip file"},
{"testdata/invalid.gz", "Failed to uncompress gzip file"},
{"testdata/invalid-tar.tar.gz", "Failed to unarchive .tar file"},
{"testdata/invalid-gzip.tar.gz", "Failed to uncompress .tar.gz file"},
} {
f, err := os.Open(a.name)
if err != nil {
t.Fatal(err)
}
var ext string
if strings.HasSuffix(a.name, ".tar.gz") {
ext = ".tar.gz"
} else {
ext = filepath.Ext(a.name)
}
url := "https://github.com/foo/bar/releases/download/v1.2.3/bar" + ext
_, err = uncompress(f, url, "bar")
if err == nil {
t.Fatal("Error should be raised")
}
if !strings.Contains(err.Error(), a.msg) {
t.Fatal("Unexpected error:", err)
}
}
}
func TestTargetNotFoundInZip(t *testing.T) {
for _, f := range []string{
"testdata/empty.zip",
"testdata/bar-not-found.zip",
} {
t.Run(f, func(t *testing.T) {
f, err := os.Open(f)
if err != nil {
t.Fatal(err)
}
_, err = uncompress(f, "https://github.com/foo/bar/releases/download/v1.2.3/bar.zip", "bar")
if err == nil {
t.Fatal("Error should be raised for")
}
if !strings.Contains(err.Error(), "command is not found") {
t.Fatal("Unexpected error:", err)
}
})
}
}
func TestTargetNotFoundInGZip(t *testing.T) {
f, err := os.Open("testdata/bar-not-found.gzip")
if err != nil {
t.Fatal(err)
}
_, err = uncompress(f, "https://github.com/foo/bar/releases/download/v1.2.3/bar.gzip", "bar")
if err == nil {
t.Fatal("Error should be raised for")
}
if !strings.Contains(err.Error(), "does not match to command") {
t.Fatal("Unexpected error:", err)
}
}
func TestTargetNotFoundInTarGz(t *testing.T) {
for _, f := range []string{
"testdata/empty.tar.gz",
"testdata/bar-not-found.tar.gz",
} {
t.Run(f, func(t *testing.T) {
f, err := os.Open(f)
if err != nil {
t.Fatal(err)
}
_, err = uncompress(f, "https://github.com/foo/bar/releases/download/v1.2.3/bar.tar.gz", "bar")
if err == nil {
t.Fatal("Error should be raised for")
}
if !strings.Contains(err.Error(), "command is not found") {
t.Fatal("Unexpected error:", err)
}
})
}
}