~juju-qa/ubuntu/xenial/juju/xenial-2.0-beta3

« back to all changes in this revision

Viewing changes to src/github.com/juju/zip/writer_test.go

  • Committer: Martin Packman
  • Date: 2016-03-30 19:31:08 UTC
  • mfrom: (1.1.41)
  • Revision ID: martin.packman@canonical.com-20160330193108-h9iz3ak334uk0z5r
Merge new upstream source 2.0~beta3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2011 The Go Authors. All rights reserved.
 
2
// Use of this source code is governed by a BSD-style
 
3
// license that can be found in the LICENSE file.
 
4
 
 
5
package zip
 
6
 
 
7
import (
 
8
        "bytes"
 
9
        "io"
 
10
        "io/ioutil"
 
11
        "math/rand"
 
12
        "os"
 
13
        "testing"
 
14
)
 
15
 
 
16
// TODO(adg): a more sophisticated test suite
 
17
 
 
18
type WriteTest struct {
 
19
        Name   string
 
20
        Data   []byte
 
21
        Method uint16
 
22
        Mode   os.FileMode
 
23
}
 
24
 
 
25
var writeTests = []WriteTest{
 
26
        {
 
27
                Name:   "foo",
 
28
                Data:   []byte("Rabbits, guinea pigs, gophers, marsupial rats, and quolls."),
 
29
                Method: Store,
 
30
                Mode:   0666,
 
31
        },
 
32
        {
 
33
                Name:   "bar",
 
34
                Data:   nil, // large data set in the test
 
35
                Method: Deflate,
 
36
                Mode:   0644,
 
37
        },
 
38
        {
 
39
                Name:   "setuid",
 
40
                Data:   []byte("setuid file"),
 
41
                Method: Deflate,
 
42
                Mode:   0755 | os.ModeSetuid,
 
43
        },
 
44
        {
 
45
                Name:   "setgid",
 
46
                Data:   []byte("setgid file"),
 
47
                Method: Deflate,
 
48
                Mode:   0755 | os.ModeSetgid,
 
49
        },
 
50
        {
 
51
                Name:   "symlink",
 
52
                Data:   []byte("../link/target"),
 
53
                Method: Deflate,
 
54
                Mode:   0755 | os.ModeSymlink,
 
55
        },
 
56
}
 
57
 
 
58
func TestWriter(t *testing.T) {
 
59
        largeData := make([]byte, 1<<17)
 
60
        for i := range largeData {
 
61
                largeData[i] = byte(rand.Int())
 
62
        }
 
63
        writeTests[1].Data = largeData
 
64
        defer func() {
 
65
                writeTests[1].Data = nil
 
66
        }()
 
67
 
 
68
        // write a zip file
 
69
        buf := new(bytes.Buffer)
 
70
        w := NewWriter(buf)
 
71
 
 
72
        for _, wt := range writeTests {
 
73
                testCreate(t, w, &wt)
 
74
        }
 
75
 
 
76
        if err := w.Close(); err != nil {
 
77
                t.Fatal(err)
 
78
        }
 
79
 
 
80
        // read it back
 
81
        r, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
 
82
        if err != nil {
 
83
                t.Fatal(err)
 
84
        }
 
85
        for i, wt := range writeTests {
 
86
                testReadFile(t, r.File[i], &wt)
 
87
        }
 
88
}
 
89
 
 
90
func TestAppend(t *testing.T) {
 
91
        // write a zip file
 
92
        buf := new(bytes.Buffer)
 
93
        w := NewWriter(buf)
 
94
 
 
95
        for _, wt := range writeTests {
 
96
                testCreate(t, w, &wt)
 
97
        }
 
98
 
 
99
        if err := w.Close(); err != nil {
 
100
                t.Fatal(err)
 
101
        }
 
102
 
 
103
        // read it back
 
104
        r, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
 
105
        if err != nil {
 
106
                t.Fatal(err)
 
107
        }
 
108
 
 
109
        // append a file to it.
 
110
        abuf := new(bytes.Buffer)
 
111
        w = r.Append(abuf)
 
112
 
 
113
        wt := WriteTest{
 
114
                Name:   "foo",
 
115
                Data:   []byte("Badgers, canines, weasels, owls, and snakes"),
 
116
                Method: Store,
 
117
                Mode:   0755,
 
118
        }
 
119
        testCreate(t, w, &wt)
 
120
 
 
121
        if err := w.Close(); err != nil {
 
122
                t.Fatal(err)
 
123
        }
 
124
 
 
125
        // read the whole thing back.
 
126
        allBytes := append(buf.Bytes(), abuf.Bytes()...)
 
127
 
 
128
        r, err = NewReader(bytes.NewReader(allBytes), int64(len(allBytes)))
 
129
        if err != nil {
 
130
                t.Fatal(err)
 
131
        }
 
132
 
 
133
        writeTests := append(writeTests[1:], wt)
 
134
        for i, wt := range writeTests {
 
135
                testReadFile(t, r.File[i], &wt)
 
136
        }
 
137
}
 
138
 
 
139
func TestWriterOffset(t *testing.T) {
 
140
        largeData := make([]byte, 1<<17)
 
141
        for i := range largeData {
 
142
                largeData[i] = byte(rand.Int())
 
143
        }
 
144
        writeTests[1].Data = largeData
 
145
        defer func() {
 
146
                writeTests[1].Data = nil
 
147
        }()
 
148
 
 
149
        // write a zip file
 
150
        buf := new(bytes.Buffer)
 
151
        existingData := []byte{1, 2, 3, 1, 2, 3, 1, 2, 3}
 
152
        n, _ := buf.Write(existingData)
 
153
        w := NewWriter(buf)
 
154
        w.SetOffset(int64(n))
 
155
 
 
156
        for _, wt := range writeTests {
 
157
                testCreate(t, w, &wt)
 
158
        }
 
159
 
 
160
        if err := w.Close(); err != nil {
 
161
                t.Fatal(err)
 
162
        }
 
163
 
 
164
        // read it back
 
165
        r, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
 
166
        if err != nil {
 
167
                t.Fatal(err)
 
168
        }
 
169
        for i, wt := range writeTests {
 
170
                testReadFile(t, r.File[i], &wt)
 
171
        }
 
172
}
 
173
 
 
174
func TestWriterFlush(t *testing.T) {
 
175
        var buf bytes.Buffer
 
176
        w := NewWriter(struct{ io.Writer }{&buf})
 
177
        _, err := w.Create("foo")
 
178
        if err != nil {
 
179
                t.Fatal(err)
 
180
        }
 
181
        if buf.Len() > 0 {
 
182
                t.Fatalf("Unexpected %d bytes already in buffer", buf.Len())
 
183
        }
 
184
        if err := w.Flush(); err != nil {
 
185
                t.Fatal(err)
 
186
        }
 
187
        if buf.Len() == 0 {
 
188
                t.Fatal("No bytes written after Flush")
 
189
        }
 
190
}
 
191
 
 
192
func testCreate(t *testing.T, w *Writer, wt *WriteTest) {
 
193
        header := &FileHeader{
 
194
                Name:   wt.Name,
 
195
                Method: wt.Method,
 
196
        }
 
197
        if wt.Mode != 0 {
 
198
                header.SetMode(wt.Mode)
 
199
        }
 
200
        f, err := w.CreateHeader(header)
 
201
        if err != nil {
 
202
                t.Fatal(err)
 
203
        }
 
204
        _, err = f.Write(wt.Data)
 
205
        if err != nil {
 
206
                t.Fatal(err)
 
207
        }
 
208
}
 
209
 
 
210
func testReadFile(t *testing.T, f *File, wt *WriteTest) {
 
211
        if f.Name != wt.Name {
 
212
                t.Fatalf("File name: got %q, want %q", f.Name, wt.Name)
 
213
        }
 
214
        testFileMode(t, wt.Name, f, wt.Mode)
 
215
        rc, err := f.Open()
 
216
        if err != nil {
 
217
                t.Fatal("opening:", err)
 
218
        }
 
219
        b, err := ioutil.ReadAll(rc)
 
220
        if err != nil {
 
221
                t.Fatal("reading:", err)
 
222
        }
 
223
        err = rc.Close()
 
224
        if err != nil {
 
225
                t.Fatal("closing:", err)
 
226
        }
 
227
        if !bytes.Equal(b, wt.Data) {
 
228
                t.Errorf("File contents %q, want %q", b, wt.Data)
 
229
        }
 
230
}
 
231
 
 
232
func BenchmarkCompressedZipGarbage(b *testing.B) {
 
233
        b.ReportAllocs()
 
234
        var buf bytes.Buffer
 
235
        bigBuf := bytes.Repeat([]byte("a"), 1<<20)
 
236
        for i := 0; i < b.N; i++ {
 
237
                buf.Reset()
 
238
                zw := NewWriter(&buf)
 
239
                for j := 0; j < 3; j++ {
 
240
                        w, _ := zw.CreateHeader(&FileHeader{
 
241
                                Name:   "foo",
 
242
                                Method: Deflate,
 
243
                        })
 
244
                        w.Write(bigBuf)
 
245
                }
 
246
                zw.Close()
 
247
        }
 
248
}