Browse code

Add test on archive.go (#11603)

- Trying to add or complete unit test to each ``func``
- Removing dead code (``escapeName``)

Signed-off-by: Vincent Demeester <vincent@sbr.pm>

Vincent Demeester authored on 2015/04/08 20:29:32
Showing 2 changed files
... ...
@@ -388,22 +388,6 @@ func Tar(path string, compression Compression) (io.ReadCloser, error) {
388 388
 	return TarWithOptions(path, &TarOptions{Compression: compression})
389 389
 }
390 390
 
391
-func escapeName(name string) string {
392
-	escaped := make([]byte, 0)
393
-	for i, c := range []byte(name) {
394
-		if i == 0 && c == '/' {
395
-			continue
396
-		}
397
-		// all printable chars except "-" which is 0x2d
398
-		if (0x20 <= c && c <= 0x7E) && c != 0x2d {
399
-			escaped = append(escaped, c)
400
-		} else {
401
-			escaped = append(escaped, fmt.Sprintf("\\%03o", c)...)
402
-		}
403
-	}
404
-	return string(escaped)
405
-}
406
-
407 391
 // TarWithOptions creates an archive from the directory at `path`, only including files whose relative
408 392
 // paths are included in `options.IncludeFiles` (if non-nil) or not in `options.ExcludePatterns`.
409 393
 func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) {
... ...
@@ -14,9 +14,150 @@ import (
14 14
 	"testing"
15 15
 	"time"
16 16
 
17
+	"github.com/docker/docker/pkg/system"
17 18
 	"github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
18 19
 )
19 20
 
21
+func TestIsArchiveNilHeader(t *testing.T) {
22
+	out := IsArchive(nil)
23
+	if out {
24
+		t.Fatalf("isArchive should return false as nil is not a valid archive header")
25
+	}
26
+}
27
+
28
+func TestIsArchiveInvalidHeader(t *testing.T) {
29
+	header := []byte{0x00, 0x01, 0x02}
30
+	out := IsArchive(header)
31
+	if out {
32
+		t.Fatalf("isArchive should return false as %s is not a valid archive header", header)
33
+	}
34
+}
35
+
36
+func TestIsArchiveBzip2(t *testing.T) {
37
+	header := []byte{0x42, 0x5A, 0x68}
38
+	out := IsArchive(header)
39
+	if !out {
40
+		t.Fatalf("isArchive should return true as %s is a bz2 header", header)
41
+	}
42
+}
43
+
44
+func TestIsArchive7zip(t *testing.T) {
45
+	header := []byte{0x50, 0x4b, 0x03, 0x04}
46
+	out := IsArchive(header)
47
+	if out {
48
+		t.Fatalf("isArchive should return false as %s is a 7z header and it is not supported", header)
49
+	}
50
+}
51
+
52
+func TestDecompressStreamGzip(t *testing.T) {
53
+	cmd := exec.Command("/bin/sh", "-c", "touch /tmp/archive && gzip -f /tmp/archive")
54
+	output, err := cmd.CombinedOutput()
55
+	if err != nil {
56
+		t.Fatalf("Fail to create an archive file for test : %s.", output)
57
+	}
58
+	archive, err := os.Open("/tmp/archive.gz")
59
+	_, err = DecompressStream(archive)
60
+	if err != nil {
61
+		t.Fatalf("Failed to decompress a gzip file.")
62
+	}
63
+}
64
+
65
+func TestDecompressStreamBzip2(t *testing.T) {
66
+	cmd := exec.Command("/bin/sh", "-c", "touch /tmp/archive && bzip2 -f /tmp/archive")
67
+	output, err := cmd.CombinedOutput()
68
+	if err != nil {
69
+		t.Fatalf("Fail to create an archive file for test : %s.", output)
70
+	}
71
+	archive, err := os.Open("/tmp/archive.bz2")
72
+	_, err = DecompressStream(archive)
73
+	if err != nil {
74
+		t.Fatalf("Failed to decompress a bzip2 file.")
75
+	}
76
+}
77
+
78
+func TestDecompressStreamXz(t *testing.T) {
79
+	cmd := exec.Command("/bin/sh", "-c", "touch /tmp/archive && xz -f /tmp/archive")
80
+	output, err := cmd.CombinedOutput()
81
+	if err != nil {
82
+		t.Fatalf("Fail to create an archive file for test : %s.", output)
83
+	}
84
+	archive, err := os.Open("/tmp/archive.xz")
85
+	_, err = DecompressStream(archive)
86
+	if err != nil {
87
+		t.Fatalf("Failed to decompress a xz file.")
88
+	}
89
+}
90
+
91
+func TestCompressStreamXzUnsuported(t *testing.T) {
92
+	dest, err := os.Create("/tmp/dest")
93
+	if err != nil {
94
+		t.Fatalf("Fail to create the destination file")
95
+	}
96
+	_, err = CompressStream(dest, Xz)
97
+	if err == nil {
98
+		t.Fatalf("Should fail as xz is unsupported for compression format.")
99
+	}
100
+}
101
+
102
+func TestCompressStreamBzip2Unsupported(t *testing.T) {
103
+	dest, err := os.Create("/tmp/dest")
104
+	if err != nil {
105
+		t.Fatalf("Fail to create the destination file")
106
+	}
107
+	_, err = CompressStream(dest, Xz)
108
+	if err == nil {
109
+		t.Fatalf("Should fail as xz is unsupported for compression format.")
110
+	}
111
+}
112
+
113
+func TestCompressStreamInvalid(t *testing.T) {
114
+	dest, err := os.Create("/tmp/dest")
115
+	if err != nil {
116
+		t.Fatalf("Fail to create the destination file")
117
+	}
118
+	_, err = CompressStream(dest, -1)
119
+	if err == nil {
120
+		t.Fatalf("Should fail as xz is unsupported for compression format.")
121
+	}
122
+}
123
+
124
+func TestExtensionInvalid(t *testing.T) {
125
+	compression := Compression(-1)
126
+	output := compression.Extension()
127
+	if output != "" {
128
+		t.Fatalf("The extension of an invalid compression should be an empty string.")
129
+	}
130
+}
131
+
132
+func TestExtensionUncompressed(t *testing.T) {
133
+	compression := Uncompressed
134
+	output := compression.Extension()
135
+	if output != "tar" {
136
+		t.Fatalf("The extension of a uncompressed archive should be 'tar'.")
137
+	}
138
+}
139
+func TestExtensionBzip2(t *testing.T) {
140
+	compression := Bzip2
141
+	output := compression.Extension()
142
+	if output != "tar.bz2" {
143
+		t.Fatalf("The extension of a bzip2 archive should be 'tar.bz2'")
144
+	}
145
+}
146
+func TestExtensionGzip(t *testing.T) {
147
+	compression := Gzip
148
+	output := compression.Extension()
149
+	if output != "tar.gz" {
150
+		t.Fatalf("The extension of a bzip2 archive should be 'tar.gz'")
151
+	}
152
+}
153
+func TestExtensionXz(t *testing.T) {
154
+	compression := Xz
155
+	output := compression.Extension()
156
+	if output != "tar.xz" {
157
+		t.Fatalf("The extension of a bzip2 archive should be 'tar.xz'")
158
+	}
159
+}
160
+
20 161
 func TestCmdStreamLargeStderr(t *testing.T) {
21 162
 	cmd := exec.Command("/bin/sh", "-c", "dd if=/dev/zero bs=1k count=1000 of=/dev/stderr; echo hello")
22 163
 	out, err := CmdStream(cmd, nil)
... ...
@@ -179,11 +320,56 @@ func TestTarUntar(t *testing.T) {
179 179
 	}
180 180
 }
181 181
 
182
+func TestTarUntarWithXattr(t *testing.T) {
183
+	origin, err := ioutil.TempDir("", "docker-test-untar-origin")
184
+	if err != nil {
185
+		t.Fatal(err)
186
+	}
187
+	defer os.RemoveAll(origin)
188
+	if err := ioutil.WriteFile(path.Join(origin, "1"), []byte("hello world"), 0700); err != nil {
189
+		t.Fatal(err)
190
+	}
191
+	if err := ioutil.WriteFile(path.Join(origin, "2"), []byte("welcome!"), 0700); err != nil {
192
+		t.Fatal(err)
193
+	}
194
+	if err := ioutil.WriteFile(path.Join(origin, "3"), []byte("will be ignored"), 0700); err != nil {
195
+		t.Fatal(err)
196
+	}
197
+	if err := system.Lsetxattr(path.Join(origin, "2"), "security.capability", []byte{0x00}, 0); err != nil {
198
+		t.Fatal(err)
199
+	}
200
+
201
+	for _, c := range []Compression{
202
+		Uncompressed,
203
+		Gzip,
204
+	} {
205
+		changes, err := tarUntar(t, origin, &TarOptions{
206
+			Compression:     c,
207
+			ExcludePatterns: []string{"3"},
208
+		})
209
+
210
+		if err != nil {
211
+			t.Fatalf("Error tar/untar for compression %s: %s", c.Extension(), err)
212
+		}
213
+
214
+		if len(changes) != 1 || changes[0].Path != "/3" {
215
+			t.Fatalf("Unexpected differences after tarUntar: %v", changes)
216
+		}
217
+		capability, _ := system.Lgetxattr(path.Join(origin, "2"), "security.capability")
218
+		if capability == nil && capability[0] != 0x00 {
219
+			t.Fatalf("Untar should have kept the 'security.capability' xattr.")
220
+		}
221
+	}
222
+}
223
+
182 224
 func TestTarWithOptions(t *testing.T) {
183 225
 	origin, err := ioutil.TempDir("", "docker-test-untar-origin")
184 226
 	if err != nil {
185 227
 		t.Fatal(err)
186 228
 	}
229
+	if _, err := ioutil.TempDir(origin, "folder"); err != nil {
230
+		t.Fatal(err)
231
+	}
187 232
 	defer os.RemoveAll(origin)
188 233
 	if err := ioutil.WriteFile(path.Join(origin, "1"), []byte("hello world"), 0700); err != nil {
189 234
 		t.Fatal(err)
... ...
@@ -196,8 +382,11 @@ func TestTarWithOptions(t *testing.T) {
196 196
 		opts       *TarOptions
197 197
 		numChanges int
198 198
 	}{
199
-		{&TarOptions{IncludeFiles: []string{"1"}}, 1},
199
+		{&TarOptions{IncludeFiles: []string{"1"}}, 2},
200 200
 		{&TarOptions{ExcludePatterns: []string{"2"}}, 1},
201
+		{&TarOptions{ExcludePatterns: []string{"1", "folder*"}}, 2},
202
+		{&TarOptions{IncludeFiles: []string{"1", "1"}}, 2},
203
+		{&TarOptions{Name: "test", IncludeFiles: []string{"1"}}, 4},
201 204
 	}
202 205
 	for _, testCase := range cases {
203 206
 		changes, err := tarUntar(t, origin, testCase.opts)
... ...
@@ -256,6 +445,58 @@ func TestUntarUstarGnuConflict(t *testing.T) {
256 256
 	}
257 257
 }
258 258
 
259
+func TestTarWithBlockCharFifo(t *testing.T) {
260
+	origin, err := ioutil.TempDir("", "docker-test-tar-hardlink")
261
+	if err != nil {
262
+		t.Fatal(err)
263
+	}
264
+	defer os.RemoveAll(origin)
265
+	if err := ioutil.WriteFile(path.Join(origin, "1"), []byte("hello world"), 0700); err != nil {
266
+		t.Fatal(err)
267
+	}
268
+	if err := system.Mknod(path.Join(origin, "2"), syscall.S_IFBLK, int(system.Mkdev(int64(12), int64(5)))); err != nil {
269
+		t.Fatal(err)
270
+	}
271
+	if err := system.Mknod(path.Join(origin, "3"), syscall.S_IFCHR, int(system.Mkdev(int64(12), int64(5)))); err != nil {
272
+		t.Fatal(err)
273
+	}
274
+	if err := system.Mknod(path.Join(origin, "4"), syscall.S_IFIFO, int(system.Mkdev(int64(12), int64(5)))); err != nil {
275
+		t.Fatal(err)
276
+	}
277
+
278
+	dest, err := ioutil.TempDir("", "docker-test-tar-hardlink-dest")
279
+	if err != nil {
280
+		t.Fatal(err)
281
+	}
282
+	defer os.RemoveAll(dest)
283
+
284
+	// we'll do this in two steps to separate failure
285
+	fh, err := Tar(origin, Uncompressed)
286
+	if err != nil {
287
+		t.Fatal(err)
288
+	}
289
+
290
+	// ensure we can read the whole thing with no error, before writing back out
291
+	buf, err := ioutil.ReadAll(fh)
292
+	if err != nil {
293
+		t.Fatal(err)
294
+	}
295
+
296
+	bRdr := bytes.NewReader(buf)
297
+	err = Untar(bRdr, dest, &TarOptions{Compression: Uncompressed})
298
+	if err != nil {
299
+		t.Fatal(err)
300
+	}
301
+
302
+	changes, err := ChangesDirs(origin, dest)
303
+	if err != nil {
304
+		t.Fatal(err)
305
+	}
306
+	if len(changes) > 0 {
307
+		t.Fatalf("Tar with special device (block, char, fifo) should keep them (recreate them when untar) : %s", changes)
308
+	}
309
+}
310
+
259 311
 func TestTarWithHardLink(t *testing.T) {
260 312
 	origin, err := ioutil.TempDir("", "docker-test-tar-hardlink")
261 313
 	if err != nil {