1 package embeddedpostgres
2
3 import (
4 "archive/tar"
5 "errors"
6 "fmt"
7 "io"
8 "os"
9 "path"
10 "path/filepath"
11 "syscall"
12 "testing"
13
14 "github.com/stretchr/testify/assert"
15 "github.com/stretchr/testify/require"
16 "github.com/xi2/xz"
17 )
18
19 func Test_decompressTarXz(t *testing.T) {
20 tempDir, err := os.MkdirTemp("", "temp_tar_test")
21 if err != nil {
22 panic(err)
23 }
24 if err := syscall.Rmdir(tempDir); err != nil {
25 panic(err)
26 }
27
28 archive, cleanUp := createTempXzArchive()
29 defer cleanUp()
30
31 err = decompressTarXz(defaultTarReader, archive, tempDir)
32
33 assert.NoError(t, err)
34
35 expectedExtractedFileLocation := filepath.Join(tempDir, "dir1", "dir2", "some_content")
36 assert.FileExists(t, expectedExtractedFileLocation)
37
38 fileContentBytes, err := os.ReadFile(expectedExtractedFileLocation)
39 assert.NoError(t, err)
40
41 assert.Equal(t, "b33r is g00d", string(fileContentBytes))
42 }
43
44 func Test_decompressTarXz_ErrorWhenFileNotExists(t *testing.T) {
45 err := decompressTarXz(defaultTarReader, "/does-not-exist", "/also-fake")
46
47 assert.Error(t, err)
48 assert.Contains(
49 t,
50 err.Error(),
51 "unable to extract postgres archive /does-not-exist to /also-fake, if running parallel tests, configure RuntimePath to isolate testing directories",
52 )
53 }
54
55 func Test_decompressTarXz_ErrorWhenErrorDuringRead(t *testing.T) {
56 tempDir, err := os.MkdirTemp("", "temp_tar_test")
57 if err != nil {
58 panic(err)
59 }
60 if err := syscall.Rmdir(tempDir); err != nil {
61 panic(err)
62 }
63
64 archive, cleanUp := createTempXzArchive()
65 defer cleanUp()
66
67 err = decompressTarXz(func(reader *xz.Reader) (func() (*tar.Header, error), func() io.Reader) {
68 return func() (*tar.Header, error) {
69 return nil, errors.New("oh noes")
70 }, nil
71 }, archive, tempDir)
72
73 assert.EqualError(t, err, "unable to extract postgres archive: oh noes")
74 }
75
76 func Test_decompressTarXz_ErrorWhenFailedToReadFileToCopy(t *testing.T) {
77 tempDir, err := os.MkdirTemp("", "temp_tar_test")
78 if err != nil {
79 panic(err)
80 }
81
82 archive, cleanUp := createTempXzArchive()
83 defer cleanUp()
84
85 blockingFile := filepath.Join(tempDir, "blocking")
86
87 if err = os.WriteFile(blockingFile, []byte("wazz"), 0000); err != nil {
88 panic(err)
89 }
90
91 fileBlockingExtractTarReader := func(reader *xz.Reader) (func() (*tar.Header, error), func() io.Reader) {
92 shouldReadFile := true
93
94 return func() (*tar.Header, error) {
95 if shouldReadFile {
96 shouldReadFile = false
97
98 return &tar.Header{
99 Typeflag: tar.TypeReg,
100 Name: "blocking",
101 }, nil
102 }
103
104 return nil, io.EOF
105 }, func() io.Reader {
106 open, _ := os.Open("file_not_exists")
107 return open
108 }
109 }
110
111 err = decompressTarXz(fileBlockingExtractTarReader, archive, tempDir)
112
113 assert.Regexp(t, "^unable to extract postgres archive:.+$", err)
114 }
115
116 func Test_decompressTarXz_ErrorWhenFileToCopyToNotExists(t *testing.T) {
117 tempDir, err := os.MkdirTemp("", "temp_tar_test")
118 if err != nil {
119 panic(err)
120 }
121 if err := syscall.Rmdir(tempDir); err != nil {
122 panic(err)
123 }
124
125 archive, cleanUp := createTempXzArchive()
126 defer cleanUp()
127
128 fileBlockingExtractTarReader := func(reader *xz.Reader) (func() (*tar.Header, error), func() io.Reader) {
129 shouldReadFile := true
130
131 return func() (*tar.Header, error) {
132 if shouldReadFile {
133 shouldReadFile = false
134
135 return &tar.Header{
136 Typeflag: tar.TypeReg,
137 Name: "some_dir/wazz/dazz/fazz",
138 }, nil
139 }
140
141 return nil, io.EOF
142 }, func() io.Reader {
143 open, _ := os.Open("file_not_exists")
144 return open
145 }
146 }
147
148 err = decompressTarXz(fileBlockingExtractTarReader, archive, tempDir)
149
150 assert.Regexp(t, "^unable to extract postgres archive:.+$", err)
151 }
152
153 func Test_decompressTarXz_ErrorWhenArchiveCorrupted(t *testing.T) {
154 tempDir, err := os.MkdirTemp("", "temp_tar_test")
155 if err != nil {
156 panic(err)
157 }
158 if err := syscall.Rmdir(tempDir); err != nil {
159 panic(err)
160 }
161
162 archive, cleanup := createTempXzArchive()
163
164 defer cleanup()
165
166 file, err := os.OpenFile(archive, os.O_WRONLY, 0664)
167 if err != nil {
168 panic(err)
169 }
170
171 if _, err := file.Seek(35, 0); err != nil {
172 panic(err)
173 }
174
175 if _, err := file.WriteString("someJunk"); err != nil {
176 panic(err)
177 }
178
179 if err := file.Close(); err != nil {
180 panic(err)
181 }
182
183 err = decompressTarXz(defaultTarReader, archive, tempDir)
184
185 assert.EqualError(t, err, "unable to extract postgres archive: xz: data is corrupt")
186 }
187
188 func Test_decompressTarXz_ErrorWithInvalidDestination(t *testing.T) {
189 archive, cleanUp := createTempXzArchive()
190 defer cleanUp()
191
192 tempDir, err := os.MkdirTemp("", "temp_tar_test")
193 require.NoError(t, err)
194 defer func() {
195 os.RemoveAll(tempDir)
196 }()
197
198 op := fmt.Sprintf(path.Join(tempDir, "%c"), rune(0))
199
200 err = decompressTarXz(defaultTarReader, archive, op)
201 assert.EqualError(
202 t,
203 err,
204 fmt.Sprintf("unable to extract postgres archive: mkdir %s: invalid argument", op),
205 )
206 }
207
View as plain text