github.com/creativeprojects/go-selfupdate@v1.2.0/decompress_test.go (about) 1 package selfupdate 2 3 import ( 4 "bytes" 5 "io" 6 "os" 7 "path/filepath" 8 "runtime" 9 "strings" 10 "testing" 11 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 ) 15 16 func TestCompressionNotRequired(t *testing.T) { 17 buf := []byte{'a', 'b', 'c'} 18 want := bytes.NewReader(buf) 19 r, err := DecompressCommand(want, "https://github.com/foo/bar/releases/download/v1.2.3/foo", "foo", runtime.GOOS, runtime.GOOS) 20 require.NoError(t, err) 21 22 have, err := io.ReadAll(r) 23 require.NoError(t, err) 24 assert.Equal(t, buf, have) 25 } 26 27 func getArchiveFileExt(file string) string { 28 if strings.HasSuffix(file, ".tar.gz") { 29 return ".tar.gz" 30 } 31 if strings.HasSuffix(file, ".tar.xz") { 32 return ".tar.xz" 33 } 34 return filepath.Ext(file) 35 } 36 37 func TestDecompress(t *testing.T) { 38 for _, testCase := range []string{ 39 "testdata/foo.zip", 40 "testdata/single-file.zip", 41 "testdata/single-file.gz", 42 "testdata/single-file.gzip", 43 "testdata/foo.tar.gz", 44 "testdata/foo.tgz", 45 "testdata/foo.tar.xz", 46 "testdata/single-file.xz", 47 "testdata/single-file.bz2", 48 } { 49 t.Run(testCase, func(t *testing.T) { 50 f, err := os.Open(testCase) 51 require.NoError(t, err) 52 53 ext := getArchiveFileExt(testCase) 54 url := "https://github.com/foo/bar/releases/download/v1.2.3/bar" + ext 55 r, err := DecompressCommand(f, url, "bar", runtime.GOOS, runtime.GOOS) 56 require.NoError(t, err) 57 58 content, err := io.ReadAll(r) 59 require.NoError(t, err) 60 61 assert.Equal(t, "this is test\n", string(content), "Decompressing zip failed into unexpected content") 62 }) 63 } 64 } 65 66 func TestDecompressInvalidArchive(t *testing.T) { 67 for _, testCase := range []struct { 68 name string 69 msg string 70 }{ 71 {"testdata/invalid.zip", "failed to decompress zip file"}, 72 {"testdata/invalid.gz", "failed to decompress gzip file"}, 73 {"testdata/invalid-tar.tar.gz", "failed to decompress tar file"}, 74 {"testdata/invalid-gzip.tar.gz", "failed to decompress tar.gz file"}, 75 {"testdata/invalid.xz", "failed to decompress xzip file"}, 76 {"testdata/invalid-tar.tar.xz", "failed to decompress tar file"}, 77 {"testdata/invalid-xz.tar.xz", "failed to decompress tar.xz file"}, 78 } { 79 f, err := os.Open(testCase.name) 80 require.NoError(t, err) 81 82 ext := getArchiveFileExt(testCase.name) 83 url := "https://github.com/foo/bar/releases/download/v1.2.3/bar" + ext 84 _, err = DecompressCommand(f, url, "bar", runtime.GOOS, runtime.GOOS) 85 assert.ErrorIs(t, err, ErrCannotDecompressFile) 86 if !strings.Contains(err.Error(), testCase.msg) { 87 t.Fatal("Unexpected error:", err) 88 } 89 } 90 } 91 92 func TestTargetNotFound(t *testing.T) { 93 for _, testCase := range []struct { 94 name string 95 msg string 96 }{ 97 {"testdata/empty.zip", "not found"}, 98 {"testdata/bar-not-found.zip", "not found"}, 99 {"testdata/bar-not-found.gzip", "not found"}, 100 {"testdata/empty.tar.gz", "not found"}, 101 {"testdata/bar-not-found.tar.gz", "not found"}, 102 } { 103 t.Run(testCase.name, func(t *testing.T) { 104 f, err := os.Open(testCase.name) 105 require.NoError(t, err) 106 107 ext := getArchiveFileExt(testCase.name) 108 url := "https://github.com/foo/bar/releases/download/v1.2.3/bar" + ext 109 _, err = DecompressCommand(f, url, "bar", runtime.GOOS, runtime.GOOS) 110 assert.ErrorIs(t, err, ErrExecutableNotFoundInArchive) 111 }) 112 } 113 } 114 115 func TestMatchExecutableName(t *testing.T) { 116 testData := []struct { 117 cmd string 118 os string 119 arch string 120 target string 121 found bool 122 }{ 123 // valid 124 {"gostuff", "linux", "amd64", "gostuff", true}, 125 {"gostuff", "linux", "amd64", "gostuff_0.16.0", true}, 126 {"gostuff", "linux", "amd64", "gostuff-0.16.0", true}, 127 {"gostuff", "linux", "amd64", "gostuff_linux_amd64", true}, 128 {"gostuff", "linux", "amd64", "gostuff-linux-amd64", true}, 129 {"gostuff", "linux", "amd64", "gostuff_0.16.0_linux_amd64", true}, 130 {"gostuff", "linux", "amd64", "gostuff-0.16.0-linux-amd64", true}, 131 // invalid 132 {"gostuff", "linux", "amd64", "gostuff_darwin_amd64", false}, 133 {"gostuff", "linux", "amd64", "gostuff0.16.0", false}, 134 {"gostuff", "linux", "amd64", "gostuff_0.16.0_amd64", false}, 135 {"gostuff", "linux", "amd64", "gostuff_0.16.0_linux", false}, 136 // windows valid 137 {"gostuff", "windows", "amd64", "gostuff.exe", true}, 138 {"gostuff", "windows", "amd64", "gostuff_0.16.0.exe", true}, 139 {"gostuff", "windows", "amd64", "gostuff-0.16.0.exe", true}, 140 {"gostuff", "windows", "amd64", "gostuff_windows_amd64.exe", true}, 141 {"gostuff", "windows", "amd64", "gostuff-windows-amd64.exe", true}, 142 {"gostuff", "windows", "amd64", "gostuff_0.16.0_windows_amd64.exe", true}, 143 {"gostuff", "windows", "amd64", "gostuff-0.16.0-windows-amd64.exe", true}, 144 // windows invalid 145 {"gostuff", "windows", "amd64", "gostuff_darwin_amd64.exe", false}, 146 {"gostuff", "windows", "amd64", "gostuff0.16.0.exe", false}, 147 {"gostuff", "windows", "amd64", "gostuff_0.16.0_amd64.exe", false}, 148 {"gostuff", "windows", "amd64", "gostuff_0.16.0_windows.exe", false}, 149 } 150 151 for _, testItem := range testData { 152 t.Run(testItem.target, func(t *testing.T) { 153 assert.Equal(t, testItem.found, matchExecutableName(testItem.cmd, testItem.os, testItem.arch, testItem.target)) 154 }) 155 // also try with .exe already in cmd for windows 156 if testItem.os == "windows" { 157 t.Run(testItem.target, func(t *testing.T) { 158 assert.Equal(t, testItem.found, matchExecutableName(testItem.cmd+".exe", testItem.os, testItem.arch, testItem.target)) 159 }) 160 } 161 } 162 } 163 164 func TestErrorFromReader(t *testing.T) { 165 extensions := []string{ 166 "zip", 167 "tar.gz", 168 "tgz", 169 "gzip", 170 "gz", 171 "tar.xz", 172 "xz", 173 "bz2", 174 } 175 176 for _, extension := range extensions { 177 t.Run(extension, func(t *testing.T) { 178 reader, err := DecompressCommand(&bogusReader{}, "foo."+extension, "foo."+extension, runtime.GOOS, runtime.GOARCH) 179 if err != nil { 180 t.Log(err) 181 assert.ErrorIs(t, err, ErrCannotDecompressFile) 182 } else { 183 // bz2 does not return an error straight away: it only fails when you start reading from the output reader 184 _, err = io.ReadAll(reader) 185 t.Log(err) 186 assert.Error(t, err) 187 } 188 }) 189 } 190 }