master
go 221 lines 4.97 KB
Raw
1 package migrations
2
3 import (
4 "archive/tar"
5 "archive/zip"
6 "bufio"
7 "compress/gzip"
8 "io"
9 "os"
10 "path"
11 "path/filepath"
12 "strings"
13 "testing"
14 )
15
16 func TestUnpackArchive(t *testing.T) {
17 // Check unrecognized archive type
18 err := unpackArchive("", "no-arch-type", "", "", "")
19 if err == nil || err.Error() != "unrecognized archive type: no-arch-type" {
20 t.Fatal("expected 'unrecognized archive type' error")
21 }
22
23 // Test cannot open errors
24 err = unpackArchive("no-archive", "tar.gz", "", "", "")
25 if err == nil || !strings.HasPrefix(err.Error(), "cannot open archive file") {
26 t.Fatal("expected 'cannot open' error, got:", err)
27 }
28 err = unpackArchive("no-archive", "zip", "", "", "")
29 if err == nil || !strings.HasPrefix(err.Error(), "error opening zip reader") {
30 t.Fatal("expected 'cannot open' error, got:", err)
31 }
32 }
33
34 func TestUnpackTgz(t *testing.T) {
35 tmpDir := t.TempDir()
36
37 badTarGzip := filepath.Join(tmpDir, "bad.tar.gz")
38 err := os.WriteFile(badTarGzip, []byte("bad-data\n"), 0o644)
39 if err != nil {
40 panic(err)
41 }
42 err = unpackTgz(badTarGzip, "", "abc", "abc")
43 if err == nil || !strings.HasPrefix(err.Error(), "error opening gzip reader") {
44 t.Fatal("expected error opening gzip reader, got:", err)
45 }
46
47 testTarGzip := filepath.Join(tmpDir, "test.tar.gz")
48 testData := "some data"
49 err = writeTarGzipFile(testTarGzip, "testroot", "testfile", testData)
50 if err != nil {
51 panic(err)
52 }
53
54 out := filepath.Join(tmpDir, "out.txt")
55
56 // Test looking for file that is not in archive
57 err = unpackTgz(testTarGzip, "testroot", "abc", out)
58 if err == nil || err.Error() != "no binary found in archive" {
59 t.Fatal("expected 'no binary found in archive' error, got:", err)
60 }
61
62 // Test that unpack works.
63 err = unpackTgz(testTarGzip, "testroot", "testfile", out)
64 if err != nil {
65 t.Fatal(err)
66 }
67
68 fi, err := os.Stat(out)
69 if err != nil {
70 t.Fatal(err)
71 }
72 if fi.Size() != int64(len(testData)) {
73 t.Fatal("unpacked file size is", fi.Size(), "expected", len(testData))
74 }
75 }
76
77 func TestUnpackZip(t *testing.T) {
78 tmpDir := t.TempDir()
79
80 badZip := filepath.Join(tmpDir, "bad.zip")
81 err := os.WriteFile(badZip, []byte("bad-data\n"), 0o644)
82 if err != nil {
83 panic(err)
84 }
85 err = unpackZip(badZip, "", "abc", "abc")
86 if err == nil || !strings.HasPrefix(err.Error(), "error opening zip reader") {
87 t.Fatal("expected error opening zip reader, got:", err)
88 }
89
90 testZip := filepath.Join(tmpDir, "test.zip")
91 testData := "some data"
92 err = writeZipFile(testZip, "testroot", "testfile", testData)
93 if err != nil {
94 panic(err)
95 }
96
97 out := filepath.Join(tmpDir, "out.txt")
98
99 // Test looking for file that is not in archive
100 err = unpackZip(testZip, "testroot", "abc", out)
101 if err == nil || err.Error() != "no binary found in archive" {
102 t.Fatal("expected 'no binary found in archive' error, got:", err)
103 }
104
105 // Test that unpack works.
106 err = unpackZip(testZip, "testroot", "testfile", out)
107 if err != nil {
108 t.Fatal(err)
109 }
110
111 fi, err := os.Stat(out)
112 if err != nil {
113 t.Fatal(err)
114 }
115 if fi.Size() != int64(len(testData)) {
116 t.Fatal("unpacked file size is", fi.Size(), "expected", len(testData))
117 }
118 }
119
120 func writeTarGzipFile(archName, root, fileName, data string) error {
121 archFile, err := os.Create(archName)
122 if err != nil {
123 return err
124 }
125 defer archFile.Close()
126 w := bufio.NewWriter(archFile)
127
128 err = writeTarGzip(root, fileName, data, w)
129 if err != nil {
130 return err
131 }
132 // Flush buffered data to file
133 if err = w.Flush(); err != nil {
134 return err
135 }
136 // Close tar file
137 if err = archFile.Close(); err != nil {
138 return err
139 }
140 return nil
141 }
142
143 func writeTarGzip(root, fileName, data string, w io.Writer) error {
144 // gzip writer writes to buffer
145 gzw := gzip.NewWriter(w)
146 defer gzw.Close()
147 // tar writer writes to gzip
148 tw := tar.NewWriter(gzw)
149 defer tw.Close()
150
151 var err error
152 if fileName != "" {
153 hdr := &tar.Header{
154 Name: path.Join(root, fileName),
155 Mode: 0o600,
156 Size: int64(len(data)),
157 }
158 // Write header
159 if err = tw.WriteHeader(hdr); err != nil {
160 return err
161 }
162 // Write file body
163 if _, err := tw.Write([]byte(data)); err != nil {
164 return err
165 }
166 }
167
168 if err = tw.Close(); err != nil {
169 return err
170 }
171 // Close gzip writer; finish writing gzip data to buffer
172 if err = gzw.Close(); err != nil {
173 return err
174 }
175 return nil
176 }
177
178 func writeZipFile(archName, root, fileName, data string) error {
179 archFile, err := os.Create(archName)
180 if err != nil {
181 return err
182 }
183 defer archFile.Close()
184 w := bufio.NewWriter(archFile)
185
186 err = writeZip(root, fileName, data, w)
187 if err != nil {
188 return err
189 }
190 // Flush buffered data to file
191 if err = w.Flush(); err != nil {
192 return err
193 }
194 // Close zip file
195 if err = archFile.Close(); err != nil {
196 return err
197 }
198 return nil
199 }
200
201 func writeZip(root, fileName, data string, w io.Writer) error {
202 zw := zip.NewWriter(w)
203 defer zw.Close()
204
205 // Write file name
206 f, err := zw.Create(path.Join(root, fileName))
207 if err != nil {
208 return err
209 }
210 // Write file data
211 _, err = f.Write([]byte(data))
212 if err != nil {
213 return err
214 }
215
216 // Close zip writer
217 if err = zw.Close(); err != nil {
218 return err
219 }
220 return nil
221 }