xref: /aosp_15_r20/build/soong/zip/zip_test.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2018 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage zip
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"bytes"
19*333d2b36SAndroid Build Coastguard Worker	"encoding/hex"
20*333d2b36SAndroid Build Coastguard Worker	"hash/crc32"
21*333d2b36SAndroid Build Coastguard Worker	"io"
22*333d2b36SAndroid Build Coastguard Worker	"os"
23*333d2b36SAndroid Build Coastguard Worker	"reflect"
24*333d2b36SAndroid Build Coastguard Worker	"syscall"
25*333d2b36SAndroid Build Coastguard Worker	"testing"
26*333d2b36SAndroid Build Coastguard Worker
27*333d2b36SAndroid Build Coastguard Worker	"android/soong/third_party/zip"
28*333d2b36SAndroid Build Coastguard Worker
29*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/pathtools"
30*333d2b36SAndroid Build Coastguard Worker)
31*333d2b36SAndroid Build Coastguard Worker
32*333d2b36SAndroid Build Coastguard Workervar (
33*333d2b36SAndroid Build Coastguard Worker	fileA        = []byte("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
34*333d2b36SAndroid Build Coastguard Worker	fileB        = []byte("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB")
35*333d2b36SAndroid Build Coastguard Worker	fileC        = []byte("CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC")
36*333d2b36SAndroid Build Coastguard Worker	fileEmpty    = []byte("")
37*333d2b36SAndroid Build Coastguard Worker	fileManifest = []byte("Manifest-Version: 1.0\nCreated-By: soong_zip\n\n")
38*333d2b36SAndroid Build Coastguard Worker
39*333d2b36SAndroid Build Coastguard Worker	sha256FileA = "d53eda7a637c99cc7fb566d96e9fa109bf15c478410a3f5eb4d4c4e26cd081f6"
40*333d2b36SAndroid Build Coastguard Worker	sha256FileB = "430c56c5818e62bcb6d478901ef86284e97714c138f3c86aa14fd6a84b7ce5d3"
41*333d2b36SAndroid Build Coastguard Worker	sha256FileC = "31c5ab6111f1d6aa13c2c4e92bb3c0f7c76b61b42d141af1e846eb7f6586a51c"
42*333d2b36SAndroid Build Coastguard Worker
43*333d2b36SAndroid Build Coastguard Worker	fileCustomManifest  = []byte("Custom manifest: true\n")
44*333d2b36SAndroid Build Coastguard Worker	customManifestAfter = []byte("Manifest-Version: 1.0\nCreated-By: soong_zip\nCustom manifest: true\n\n")
45*333d2b36SAndroid Build Coastguard Worker)
46*333d2b36SAndroid Build Coastguard Worker
47*333d2b36SAndroid Build Coastguard Workervar mockFs = pathtools.MockFs(map[string][]byte{
48*333d2b36SAndroid Build Coastguard Worker	"a/a/a":               fileA,
49*333d2b36SAndroid Build Coastguard Worker	"a/a/b":               fileB,
50*333d2b36SAndroid Build Coastguard Worker	"a/a/c -> ../../c":    nil,
51*333d2b36SAndroid Build Coastguard Worker	"dangling -> missing": nil,
52*333d2b36SAndroid Build Coastguard Worker	"a/a/d -> b":          nil,
53*333d2b36SAndroid Build Coastguard Worker	"c":                   fileC,
54*333d2b36SAndroid Build Coastguard Worker	"d/a/a":               nil,
55*333d2b36SAndroid Build Coastguard Worker	"l_nl":                []byte("a/a/a\na/a/b\nc\n\\[\n"),
56*333d2b36SAndroid Build Coastguard Worker	"l_sp":                []byte("a/a/a a/a/b c \\["),
57*333d2b36SAndroid Build Coastguard Worker	"l2":                  []byte("missing\n"),
58*333d2b36SAndroid Build Coastguard Worker	"rsp":                 []byte("'a/a/a'\na/a/b\n'@'\n'foo'\\''bar'\n'['"),
59*333d2b36SAndroid Build Coastguard Worker	"@ -> c":              nil,
60*333d2b36SAndroid Build Coastguard Worker	"foo'bar -> c":        nil,
61*333d2b36SAndroid Build Coastguard Worker	"manifest.txt":        fileCustomManifest,
62*333d2b36SAndroid Build Coastguard Worker	"[":                   fileEmpty,
63*333d2b36SAndroid Build Coastguard Worker})
64*333d2b36SAndroid Build Coastguard Worker
65*333d2b36SAndroid Build Coastguard Workerfunc fh(name string, contents []byte, method uint16) zip.FileHeader {
66*333d2b36SAndroid Build Coastguard Worker	return zip.FileHeader{
67*333d2b36SAndroid Build Coastguard Worker		Name:               name,
68*333d2b36SAndroid Build Coastguard Worker		Method:             method,
69*333d2b36SAndroid Build Coastguard Worker		CRC32:              crc32.ChecksumIEEE(contents),
70*333d2b36SAndroid Build Coastguard Worker		UncompressedSize64: uint64(len(contents)),
71*333d2b36SAndroid Build Coastguard Worker		ExternalAttrs:      (syscall.S_IFREG | 0644) << 16,
72*333d2b36SAndroid Build Coastguard Worker	}
73*333d2b36SAndroid Build Coastguard Worker}
74*333d2b36SAndroid Build Coastguard Worker
75*333d2b36SAndroid Build Coastguard Workerfunc fhWithSHA256(name string, contents []byte, method uint16, sha256 string) zip.FileHeader {
76*333d2b36SAndroid Build Coastguard Worker	h := fh(name, contents, method)
77*333d2b36SAndroid Build Coastguard Worker	// The extra field contains 38 bytes, including 2 bytes of header ID, 2 bytes
78*333d2b36SAndroid Build Coastguard Worker	// of size, 2 bytes of signature, and 32 bytes of checksum data block.
79*333d2b36SAndroid Build Coastguard Worker	var extra [38]byte
80*333d2b36SAndroid Build Coastguard Worker	// The first 6 bytes contains Sha256HeaderID (0x4967), size (unit(34)) and
81*333d2b36SAndroid Build Coastguard Worker	// Sha256HeaderSignature (0x9514)
82*333d2b36SAndroid Build Coastguard Worker	copy(extra[0:], []byte{103, 73, 34, 0, 20, 149})
83*333d2b36SAndroid Build Coastguard Worker	sha256Bytes, _ := hex.DecodeString(sha256)
84*333d2b36SAndroid Build Coastguard Worker	copy(extra[6:], sha256Bytes)
85*333d2b36SAndroid Build Coastguard Worker	h.Extra = append(h.Extra, extra[:]...)
86*333d2b36SAndroid Build Coastguard Worker	return h
87*333d2b36SAndroid Build Coastguard Worker}
88*333d2b36SAndroid Build Coastguard Worker
89*333d2b36SAndroid Build Coastguard Workerfunc fhManifest(contents []byte) zip.FileHeader {
90*333d2b36SAndroid Build Coastguard Worker	return zip.FileHeader{
91*333d2b36SAndroid Build Coastguard Worker		Name:               "META-INF/MANIFEST.MF",
92*333d2b36SAndroid Build Coastguard Worker		Method:             zip.Store,
93*333d2b36SAndroid Build Coastguard Worker		CRC32:              crc32.ChecksumIEEE(contents),
94*333d2b36SAndroid Build Coastguard Worker		UncompressedSize64: uint64(len(contents)),
95*333d2b36SAndroid Build Coastguard Worker		ExternalAttrs:      (syscall.S_IFREG | 0644) << 16,
96*333d2b36SAndroid Build Coastguard Worker	}
97*333d2b36SAndroid Build Coastguard Worker}
98*333d2b36SAndroid Build Coastguard Worker
99*333d2b36SAndroid Build Coastguard Workerfunc fhLink(name string, to string) zip.FileHeader {
100*333d2b36SAndroid Build Coastguard Worker	return zip.FileHeader{
101*333d2b36SAndroid Build Coastguard Worker		Name:               name,
102*333d2b36SAndroid Build Coastguard Worker		Method:             zip.Store,
103*333d2b36SAndroid Build Coastguard Worker		CRC32:              crc32.ChecksumIEEE([]byte(to)),
104*333d2b36SAndroid Build Coastguard Worker		UncompressedSize64: uint64(len(to)),
105*333d2b36SAndroid Build Coastguard Worker		ExternalAttrs:      (syscall.S_IFLNK | 0777) << 16,
106*333d2b36SAndroid Build Coastguard Worker	}
107*333d2b36SAndroid Build Coastguard Worker}
108*333d2b36SAndroid Build Coastguard Worker
109*333d2b36SAndroid Build Coastguard Workertype fhDirOptions struct {
110*333d2b36SAndroid Build Coastguard Worker	extra []byte
111*333d2b36SAndroid Build Coastguard Worker}
112*333d2b36SAndroid Build Coastguard Worker
113*333d2b36SAndroid Build Coastguard Workerfunc fhDir(name string, opts fhDirOptions) zip.FileHeader {
114*333d2b36SAndroid Build Coastguard Worker	return zip.FileHeader{
115*333d2b36SAndroid Build Coastguard Worker		Name:               name,
116*333d2b36SAndroid Build Coastguard Worker		Method:             zip.Store,
117*333d2b36SAndroid Build Coastguard Worker		CRC32:              crc32.ChecksumIEEE(nil),
118*333d2b36SAndroid Build Coastguard Worker		UncompressedSize64: 0,
119*333d2b36SAndroid Build Coastguard Worker		ExternalAttrs:      (syscall.S_IFDIR|0755)<<16 | 0x10,
120*333d2b36SAndroid Build Coastguard Worker		Extra:              opts.extra,
121*333d2b36SAndroid Build Coastguard Worker	}
122*333d2b36SAndroid Build Coastguard Worker}
123*333d2b36SAndroid Build Coastguard Worker
124*333d2b36SAndroid Build Coastguard Workerfunc fileArgsBuilder() *FileArgsBuilder {
125*333d2b36SAndroid Build Coastguard Worker	return &FileArgsBuilder{
126*333d2b36SAndroid Build Coastguard Worker		fs: mockFs,
127*333d2b36SAndroid Build Coastguard Worker	}
128*333d2b36SAndroid Build Coastguard Worker}
129*333d2b36SAndroid Build Coastguard Worker
130*333d2b36SAndroid Build Coastguard Workerfunc TestZip(t *testing.T) {
131*333d2b36SAndroid Build Coastguard Worker	testCases := []struct {
132*333d2b36SAndroid Build Coastguard Worker		name               string
133*333d2b36SAndroid Build Coastguard Worker		args               *FileArgsBuilder
134*333d2b36SAndroid Build Coastguard Worker		compressionLevel   int
135*333d2b36SAndroid Build Coastguard Worker		emulateJar         bool
136*333d2b36SAndroid Build Coastguard Worker		nonDeflatedFiles   map[string]bool
137*333d2b36SAndroid Build Coastguard Worker		dirEntries         bool
138*333d2b36SAndroid Build Coastguard Worker		manifest           string
139*333d2b36SAndroid Build Coastguard Worker		storeSymlinks      bool
140*333d2b36SAndroid Build Coastguard Worker		ignoreMissingFiles bool
141*333d2b36SAndroid Build Coastguard Worker		sha256Checksum     bool
142*333d2b36SAndroid Build Coastguard Worker
143*333d2b36SAndroid Build Coastguard Worker		files []zip.FileHeader
144*333d2b36SAndroid Build Coastguard Worker		err   error
145*333d2b36SAndroid Build Coastguard Worker	}{
146*333d2b36SAndroid Build Coastguard Worker		{
147*333d2b36SAndroid Build Coastguard Worker			name: "empty args",
148*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder(),
149*333d2b36SAndroid Build Coastguard Worker
150*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{},
151*333d2b36SAndroid Build Coastguard Worker		},
152*333d2b36SAndroid Build Coastguard Worker		{
153*333d2b36SAndroid Build Coastguard Worker			name: "files",
154*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
155*333d2b36SAndroid Build Coastguard Worker				File("a/a/a").
156*333d2b36SAndroid Build Coastguard Worker				File("a/a/b").
157*333d2b36SAndroid Build Coastguard Worker				File("c").
158*333d2b36SAndroid Build Coastguard Worker				File(`\[`),
159*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
160*333d2b36SAndroid Build Coastguard Worker
161*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
162*333d2b36SAndroid Build Coastguard Worker				fh("a/a/a", fileA, zip.Deflate),
163*333d2b36SAndroid Build Coastguard Worker				fh("a/a/b", fileB, zip.Deflate),
164*333d2b36SAndroid Build Coastguard Worker				fh("c", fileC, zip.Deflate),
165*333d2b36SAndroid Build Coastguard Worker				fh("[", fileEmpty, zip.Store),
166*333d2b36SAndroid Build Coastguard Worker			},
167*333d2b36SAndroid Build Coastguard Worker		},
168*333d2b36SAndroid Build Coastguard Worker		{
169*333d2b36SAndroid Build Coastguard Worker			name: "files glob",
170*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
171*333d2b36SAndroid Build Coastguard Worker				SourcePrefixToStrip("a").
172*333d2b36SAndroid Build Coastguard Worker				File("a/**/*"),
173*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
174*333d2b36SAndroid Build Coastguard Worker			storeSymlinks:    true,
175*333d2b36SAndroid Build Coastguard Worker
176*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
177*333d2b36SAndroid Build Coastguard Worker				fh("a/a", fileA, zip.Deflate),
178*333d2b36SAndroid Build Coastguard Worker				fh("a/b", fileB, zip.Deflate),
179*333d2b36SAndroid Build Coastguard Worker				fhLink("a/c", "../../c"),
180*333d2b36SAndroid Build Coastguard Worker				fhLink("a/d", "b"),
181*333d2b36SAndroid Build Coastguard Worker			},
182*333d2b36SAndroid Build Coastguard Worker		},
183*333d2b36SAndroid Build Coastguard Worker		{
184*333d2b36SAndroid Build Coastguard Worker			name: "dir",
185*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
186*333d2b36SAndroid Build Coastguard Worker				SourcePrefixToStrip("a").
187*333d2b36SAndroid Build Coastguard Worker				Dir("a"),
188*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
189*333d2b36SAndroid Build Coastguard Worker			storeSymlinks:    true,
190*333d2b36SAndroid Build Coastguard Worker
191*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
192*333d2b36SAndroid Build Coastguard Worker				fh("a/a", fileA, zip.Deflate),
193*333d2b36SAndroid Build Coastguard Worker				fh("a/b", fileB, zip.Deflate),
194*333d2b36SAndroid Build Coastguard Worker				fhLink("a/c", "../../c"),
195*333d2b36SAndroid Build Coastguard Worker				fhLink("a/d", "b"),
196*333d2b36SAndroid Build Coastguard Worker			},
197*333d2b36SAndroid Build Coastguard Worker		},
198*333d2b36SAndroid Build Coastguard Worker		{
199*333d2b36SAndroid Build Coastguard Worker			name: "stored files",
200*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
201*333d2b36SAndroid Build Coastguard Worker				File("a/a/a").
202*333d2b36SAndroid Build Coastguard Worker				File("a/a/b").
203*333d2b36SAndroid Build Coastguard Worker				File("c"),
204*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 0,
205*333d2b36SAndroid Build Coastguard Worker
206*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
207*333d2b36SAndroid Build Coastguard Worker				fh("a/a/a", fileA, zip.Store),
208*333d2b36SAndroid Build Coastguard Worker				fh("a/a/b", fileB, zip.Store),
209*333d2b36SAndroid Build Coastguard Worker				fh("c", fileC, zip.Store),
210*333d2b36SAndroid Build Coastguard Worker			},
211*333d2b36SAndroid Build Coastguard Worker		},
212*333d2b36SAndroid Build Coastguard Worker		{
213*333d2b36SAndroid Build Coastguard Worker			name: "symlinks in zip",
214*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
215*333d2b36SAndroid Build Coastguard Worker				File("a/a/a").
216*333d2b36SAndroid Build Coastguard Worker				File("a/a/b").
217*333d2b36SAndroid Build Coastguard Worker				File("a/a/c").
218*333d2b36SAndroid Build Coastguard Worker				File("a/a/d"),
219*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
220*333d2b36SAndroid Build Coastguard Worker			storeSymlinks:    true,
221*333d2b36SAndroid Build Coastguard Worker
222*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
223*333d2b36SAndroid Build Coastguard Worker				fh("a/a/a", fileA, zip.Deflate),
224*333d2b36SAndroid Build Coastguard Worker				fh("a/a/b", fileB, zip.Deflate),
225*333d2b36SAndroid Build Coastguard Worker				fhLink("a/a/c", "../../c"),
226*333d2b36SAndroid Build Coastguard Worker				fhLink("a/a/d", "b"),
227*333d2b36SAndroid Build Coastguard Worker			},
228*333d2b36SAndroid Build Coastguard Worker		},
229*333d2b36SAndroid Build Coastguard Worker		{
230*333d2b36SAndroid Build Coastguard Worker			name: "follow symlinks",
231*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
232*333d2b36SAndroid Build Coastguard Worker				File("a/a/a").
233*333d2b36SAndroid Build Coastguard Worker				File("a/a/b").
234*333d2b36SAndroid Build Coastguard Worker				File("a/a/c").
235*333d2b36SAndroid Build Coastguard Worker				File("a/a/d"),
236*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
237*333d2b36SAndroid Build Coastguard Worker			storeSymlinks:    false,
238*333d2b36SAndroid Build Coastguard Worker
239*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
240*333d2b36SAndroid Build Coastguard Worker				fh("a/a/a", fileA, zip.Deflate),
241*333d2b36SAndroid Build Coastguard Worker				fh("a/a/b", fileB, zip.Deflate),
242*333d2b36SAndroid Build Coastguard Worker				fh("a/a/c", fileC, zip.Deflate),
243*333d2b36SAndroid Build Coastguard Worker				fh("a/a/d", fileB, zip.Deflate),
244*333d2b36SAndroid Build Coastguard Worker			},
245*333d2b36SAndroid Build Coastguard Worker		},
246*333d2b36SAndroid Build Coastguard Worker		{
247*333d2b36SAndroid Build Coastguard Worker			name: "dangling symlinks",
248*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
249*333d2b36SAndroid Build Coastguard Worker				File("dangling"),
250*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
251*333d2b36SAndroid Build Coastguard Worker			storeSymlinks:    true,
252*333d2b36SAndroid Build Coastguard Worker
253*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
254*333d2b36SAndroid Build Coastguard Worker				fhLink("dangling", "missing"),
255*333d2b36SAndroid Build Coastguard Worker			},
256*333d2b36SAndroid Build Coastguard Worker		},
257*333d2b36SAndroid Build Coastguard Worker		{
258*333d2b36SAndroid Build Coastguard Worker			name: "list",
259*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
260*333d2b36SAndroid Build Coastguard Worker				List("l_nl"),
261*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
262*333d2b36SAndroid Build Coastguard Worker
263*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
264*333d2b36SAndroid Build Coastguard Worker				fh("a/a/a", fileA, zip.Deflate),
265*333d2b36SAndroid Build Coastguard Worker				fh("a/a/b", fileB, zip.Deflate),
266*333d2b36SAndroid Build Coastguard Worker				fh("c", fileC, zip.Deflate),
267*333d2b36SAndroid Build Coastguard Worker				fh("[", fileEmpty, zip.Store),
268*333d2b36SAndroid Build Coastguard Worker			},
269*333d2b36SAndroid Build Coastguard Worker		},
270*333d2b36SAndroid Build Coastguard Worker		{
271*333d2b36SAndroid Build Coastguard Worker			name: "list",
272*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
273*333d2b36SAndroid Build Coastguard Worker				List("l_sp"),
274*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
275*333d2b36SAndroid Build Coastguard Worker
276*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
277*333d2b36SAndroid Build Coastguard Worker				fh("a/a/a", fileA, zip.Deflate),
278*333d2b36SAndroid Build Coastguard Worker				fh("a/a/b", fileB, zip.Deflate),
279*333d2b36SAndroid Build Coastguard Worker				fh("c", fileC, zip.Deflate),
280*333d2b36SAndroid Build Coastguard Worker				fh("[", fileEmpty, zip.Store),
281*333d2b36SAndroid Build Coastguard Worker			},
282*333d2b36SAndroid Build Coastguard Worker		},
283*333d2b36SAndroid Build Coastguard Worker		{
284*333d2b36SAndroid Build Coastguard Worker			name: "rsp",
285*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
286*333d2b36SAndroid Build Coastguard Worker				RspFile("rsp"),
287*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
288*333d2b36SAndroid Build Coastguard Worker
289*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
290*333d2b36SAndroid Build Coastguard Worker				fh("a/a/a", fileA, zip.Deflate),
291*333d2b36SAndroid Build Coastguard Worker				fh("a/a/b", fileB, zip.Deflate),
292*333d2b36SAndroid Build Coastguard Worker				fh("@", fileC, zip.Deflate),
293*333d2b36SAndroid Build Coastguard Worker				fh("foo'bar", fileC, zip.Deflate),
294*333d2b36SAndroid Build Coastguard Worker				fh("[", fileEmpty, zip.Store),
295*333d2b36SAndroid Build Coastguard Worker			},
296*333d2b36SAndroid Build Coastguard Worker		},
297*333d2b36SAndroid Build Coastguard Worker		{
298*333d2b36SAndroid Build Coastguard Worker			name: "prefix in zip",
299*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
300*333d2b36SAndroid Build Coastguard Worker				PathPrefixInZip("foo").
301*333d2b36SAndroid Build Coastguard Worker				File("a/a/a").
302*333d2b36SAndroid Build Coastguard Worker				File("a/a/b").
303*333d2b36SAndroid Build Coastguard Worker				File("c"),
304*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
305*333d2b36SAndroid Build Coastguard Worker
306*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
307*333d2b36SAndroid Build Coastguard Worker				fh("foo/a/a/a", fileA, zip.Deflate),
308*333d2b36SAndroid Build Coastguard Worker				fh("foo/a/a/b", fileB, zip.Deflate),
309*333d2b36SAndroid Build Coastguard Worker				fh("foo/c", fileC, zip.Deflate),
310*333d2b36SAndroid Build Coastguard Worker			},
311*333d2b36SAndroid Build Coastguard Worker		},
312*333d2b36SAndroid Build Coastguard Worker		{
313*333d2b36SAndroid Build Coastguard Worker			name: "relative root",
314*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
315*333d2b36SAndroid Build Coastguard Worker				SourcePrefixToStrip("a").
316*333d2b36SAndroid Build Coastguard Worker				File("a/a/a").
317*333d2b36SAndroid Build Coastguard Worker				File("a/a/b"),
318*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
319*333d2b36SAndroid Build Coastguard Worker
320*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
321*333d2b36SAndroid Build Coastguard Worker				fh("a/a", fileA, zip.Deflate),
322*333d2b36SAndroid Build Coastguard Worker				fh("a/b", fileB, zip.Deflate),
323*333d2b36SAndroid Build Coastguard Worker			},
324*333d2b36SAndroid Build Coastguard Worker		},
325*333d2b36SAndroid Build Coastguard Worker		{
326*333d2b36SAndroid Build Coastguard Worker			name: "multiple relative root",
327*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
328*333d2b36SAndroid Build Coastguard Worker				SourcePrefixToStrip("a").
329*333d2b36SAndroid Build Coastguard Worker				File("a/a/a").
330*333d2b36SAndroid Build Coastguard Worker				SourcePrefixToStrip("a/a").
331*333d2b36SAndroid Build Coastguard Worker				File("a/a/b"),
332*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
333*333d2b36SAndroid Build Coastguard Worker
334*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
335*333d2b36SAndroid Build Coastguard Worker				fh("a/a", fileA, zip.Deflate),
336*333d2b36SAndroid Build Coastguard Worker				fh("b", fileB, zip.Deflate),
337*333d2b36SAndroid Build Coastguard Worker			},
338*333d2b36SAndroid Build Coastguard Worker		},
339*333d2b36SAndroid Build Coastguard Worker		{
340*333d2b36SAndroid Build Coastguard Worker			name: "emulate jar",
341*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
342*333d2b36SAndroid Build Coastguard Worker				File("a/a/a").
343*333d2b36SAndroid Build Coastguard Worker				File("a/a/b"),
344*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
345*333d2b36SAndroid Build Coastguard Worker			emulateJar:       true,
346*333d2b36SAndroid Build Coastguard Worker
347*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
348*333d2b36SAndroid Build Coastguard Worker				fhDir("META-INF/", fhDirOptions{extra: []byte{254, 202, 0, 0}}),
349*333d2b36SAndroid Build Coastguard Worker				fhManifest(fileManifest),
350*333d2b36SAndroid Build Coastguard Worker				fhDir("a/", fhDirOptions{}),
351*333d2b36SAndroid Build Coastguard Worker				fhDir("a/a/", fhDirOptions{}),
352*333d2b36SAndroid Build Coastguard Worker				fh("a/a/a", fileA, zip.Deflate),
353*333d2b36SAndroid Build Coastguard Worker				fh("a/a/b", fileB, zip.Deflate),
354*333d2b36SAndroid Build Coastguard Worker			},
355*333d2b36SAndroid Build Coastguard Worker		},
356*333d2b36SAndroid Build Coastguard Worker		{
357*333d2b36SAndroid Build Coastguard Worker			name: "emulate jar with manifest",
358*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
359*333d2b36SAndroid Build Coastguard Worker				File("a/a/a").
360*333d2b36SAndroid Build Coastguard Worker				File("a/a/b"),
361*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
362*333d2b36SAndroid Build Coastguard Worker			emulateJar:       true,
363*333d2b36SAndroid Build Coastguard Worker			manifest:         "manifest.txt",
364*333d2b36SAndroid Build Coastguard Worker
365*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
366*333d2b36SAndroid Build Coastguard Worker				fhDir("META-INF/", fhDirOptions{extra: []byte{254, 202, 0, 0}}),
367*333d2b36SAndroid Build Coastguard Worker				fhManifest(customManifestAfter),
368*333d2b36SAndroid Build Coastguard Worker				fhDir("a/", fhDirOptions{}),
369*333d2b36SAndroid Build Coastguard Worker				fhDir("a/a/", fhDirOptions{}),
370*333d2b36SAndroid Build Coastguard Worker				fh("a/a/a", fileA, zip.Deflate),
371*333d2b36SAndroid Build Coastguard Worker				fh("a/a/b", fileB, zip.Deflate),
372*333d2b36SAndroid Build Coastguard Worker			},
373*333d2b36SAndroid Build Coastguard Worker		},
374*333d2b36SAndroid Build Coastguard Worker		{
375*333d2b36SAndroid Build Coastguard Worker			name: "dir entries",
376*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
377*333d2b36SAndroid Build Coastguard Worker				File("a/a/a").
378*333d2b36SAndroid Build Coastguard Worker				File("a/a/b"),
379*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
380*333d2b36SAndroid Build Coastguard Worker			dirEntries:       true,
381*333d2b36SAndroid Build Coastguard Worker
382*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
383*333d2b36SAndroid Build Coastguard Worker				fhDir("a/", fhDirOptions{}),
384*333d2b36SAndroid Build Coastguard Worker				fhDir("a/a/", fhDirOptions{}),
385*333d2b36SAndroid Build Coastguard Worker				fh("a/a/a", fileA, zip.Deflate),
386*333d2b36SAndroid Build Coastguard Worker				fh("a/a/b", fileB, zip.Deflate),
387*333d2b36SAndroid Build Coastguard Worker			},
388*333d2b36SAndroid Build Coastguard Worker		},
389*333d2b36SAndroid Build Coastguard Worker		{
390*333d2b36SAndroid Build Coastguard Worker			name: "junk paths",
391*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
392*333d2b36SAndroid Build Coastguard Worker				JunkPaths(true).
393*333d2b36SAndroid Build Coastguard Worker				File("a/a/a").
394*333d2b36SAndroid Build Coastguard Worker				File("a/a/b"),
395*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
396*333d2b36SAndroid Build Coastguard Worker
397*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
398*333d2b36SAndroid Build Coastguard Worker				fh("a", fileA, zip.Deflate),
399*333d2b36SAndroid Build Coastguard Worker				fh("b", fileB, zip.Deflate),
400*333d2b36SAndroid Build Coastguard Worker			},
401*333d2b36SAndroid Build Coastguard Worker		},
402*333d2b36SAndroid Build Coastguard Worker		{
403*333d2b36SAndroid Build Coastguard Worker			name: "non deflated files",
404*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
405*333d2b36SAndroid Build Coastguard Worker				File("a/a/a").
406*333d2b36SAndroid Build Coastguard Worker				File("a/a/b"),
407*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
408*333d2b36SAndroid Build Coastguard Worker			nonDeflatedFiles: map[string]bool{"a/a/a": true},
409*333d2b36SAndroid Build Coastguard Worker
410*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
411*333d2b36SAndroid Build Coastguard Worker				fh("a/a/a", fileA, zip.Store),
412*333d2b36SAndroid Build Coastguard Worker				fh("a/a/b", fileB, zip.Deflate),
413*333d2b36SAndroid Build Coastguard Worker			},
414*333d2b36SAndroid Build Coastguard Worker		},
415*333d2b36SAndroid Build Coastguard Worker		{
416*333d2b36SAndroid Build Coastguard Worker			name: "ignore missing files",
417*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
418*333d2b36SAndroid Build Coastguard Worker				File("a/a/a").
419*333d2b36SAndroid Build Coastguard Worker				File("a/a/b").
420*333d2b36SAndroid Build Coastguard Worker				File("missing"),
421*333d2b36SAndroid Build Coastguard Worker			compressionLevel:   9,
422*333d2b36SAndroid Build Coastguard Worker			ignoreMissingFiles: true,
423*333d2b36SAndroid Build Coastguard Worker
424*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
425*333d2b36SAndroid Build Coastguard Worker				fh("a/a/a", fileA, zip.Deflate),
426*333d2b36SAndroid Build Coastguard Worker				fh("a/a/b", fileB, zip.Deflate),
427*333d2b36SAndroid Build Coastguard Worker			},
428*333d2b36SAndroid Build Coastguard Worker		},
429*333d2b36SAndroid Build Coastguard Worker		{
430*333d2b36SAndroid Build Coastguard Worker			name: "duplicate sources",
431*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
432*333d2b36SAndroid Build Coastguard Worker				File("a/a/a").
433*333d2b36SAndroid Build Coastguard Worker				File("a/a/a"),
434*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
435*333d2b36SAndroid Build Coastguard Worker
436*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
437*333d2b36SAndroid Build Coastguard Worker				fh("a/a/a", fileA, zip.Deflate),
438*333d2b36SAndroid Build Coastguard Worker			},
439*333d2b36SAndroid Build Coastguard Worker		},
440*333d2b36SAndroid Build Coastguard Worker		{
441*333d2b36SAndroid Build Coastguard Worker			name: "generate SHA256 checksum",
442*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
443*333d2b36SAndroid Build Coastguard Worker				File("a/a/a").
444*333d2b36SAndroid Build Coastguard Worker				File("a/a/b").
445*333d2b36SAndroid Build Coastguard Worker				File("a/a/c").
446*333d2b36SAndroid Build Coastguard Worker				File("c"),
447*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
448*333d2b36SAndroid Build Coastguard Worker			sha256Checksum:   true,
449*333d2b36SAndroid Build Coastguard Worker
450*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
451*333d2b36SAndroid Build Coastguard Worker				fhWithSHA256("a/a/a", fileA, zip.Deflate, sha256FileA),
452*333d2b36SAndroid Build Coastguard Worker				fhWithSHA256("a/a/b", fileB, zip.Deflate, sha256FileB),
453*333d2b36SAndroid Build Coastguard Worker				fhWithSHA256("a/a/c", fileC, zip.Deflate, sha256FileC),
454*333d2b36SAndroid Build Coastguard Worker				fhWithSHA256("c", fileC, zip.Deflate, sha256FileC),
455*333d2b36SAndroid Build Coastguard Worker			},
456*333d2b36SAndroid Build Coastguard Worker		},
457*333d2b36SAndroid Build Coastguard Worker		{
458*333d2b36SAndroid Build Coastguard Worker			name: "explicit path",
459*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
460*333d2b36SAndroid Build Coastguard Worker				ExplicitPathInZip("foo").
461*333d2b36SAndroid Build Coastguard Worker				File("a/a/a").
462*333d2b36SAndroid Build Coastguard Worker				File("a/a/b"),
463*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
464*333d2b36SAndroid Build Coastguard Worker
465*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
466*333d2b36SAndroid Build Coastguard Worker				fh("foo", fileA, zip.Deflate),
467*333d2b36SAndroid Build Coastguard Worker				fh("a/a/b", fileB, zip.Deflate),
468*333d2b36SAndroid Build Coastguard Worker			},
469*333d2b36SAndroid Build Coastguard Worker		},
470*333d2b36SAndroid Build Coastguard Worker		{
471*333d2b36SAndroid Build Coastguard Worker			name: "explicit path with prefix",
472*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
473*333d2b36SAndroid Build Coastguard Worker				PathPrefixInZip("prefix").
474*333d2b36SAndroid Build Coastguard Worker				ExplicitPathInZip("foo").
475*333d2b36SAndroid Build Coastguard Worker				File("a/a/a").
476*333d2b36SAndroid Build Coastguard Worker				File("a/a/b"),
477*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
478*333d2b36SAndroid Build Coastguard Worker
479*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
480*333d2b36SAndroid Build Coastguard Worker				fh("prefix/foo", fileA, zip.Deflate),
481*333d2b36SAndroid Build Coastguard Worker				fh("prefix/a/a/b", fileB, zip.Deflate),
482*333d2b36SAndroid Build Coastguard Worker			},
483*333d2b36SAndroid Build Coastguard Worker		},
484*333d2b36SAndroid Build Coastguard Worker		{
485*333d2b36SAndroid Build Coastguard Worker			name: "explicit path with glob",
486*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
487*333d2b36SAndroid Build Coastguard Worker				ExplicitPathInZip("foo").
488*333d2b36SAndroid Build Coastguard Worker				File("a/a/a*").
489*333d2b36SAndroid Build Coastguard Worker				File("a/a/b"),
490*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
491*333d2b36SAndroid Build Coastguard Worker
492*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
493*333d2b36SAndroid Build Coastguard Worker				fh("foo", fileA, zip.Deflate),
494*333d2b36SAndroid Build Coastguard Worker				fh("a/a/b", fileB, zip.Deflate),
495*333d2b36SAndroid Build Coastguard Worker			},
496*333d2b36SAndroid Build Coastguard Worker		},
497*333d2b36SAndroid Build Coastguard Worker		{
498*333d2b36SAndroid Build Coastguard Worker			name: "explicit path with junk paths",
499*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
500*333d2b36SAndroid Build Coastguard Worker				JunkPaths(true).
501*333d2b36SAndroid Build Coastguard Worker				ExplicitPathInZip("foo/bar").
502*333d2b36SAndroid Build Coastguard Worker				File("a/a/a*").
503*333d2b36SAndroid Build Coastguard Worker				File("a/a/b"),
504*333d2b36SAndroid Build Coastguard Worker			compressionLevel: 9,
505*333d2b36SAndroid Build Coastguard Worker
506*333d2b36SAndroid Build Coastguard Worker			files: []zip.FileHeader{
507*333d2b36SAndroid Build Coastguard Worker				fh("foo/bar", fileA, zip.Deflate),
508*333d2b36SAndroid Build Coastguard Worker				fh("b", fileB, zip.Deflate),
509*333d2b36SAndroid Build Coastguard Worker			},
510*333d2b36SAndroid Build Coastguard Worker		},
511*333d2b36SAndroid Build Coastguard Worker
512*333d2b36SAndroid Build Coastguard Worker		// errors
513*333d2b36SAndroid Build Coastguard Worker		{
514*333d2b36SAndroid Build Coastguard Worker			name: "error missing file",
515*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
516*333d2b36SAndroid Build Coastguard Worker				File("missing"),
517*333d2b36SAndroid Build Coastguard Worker			err: os.ErrNotExist,
518*333d2b36SAndroid Build Coastguard Worker		},
519*333d2b36SAndroid Build Coastguard Worker		{
520*333d2b36SAndroid Build Coastguard Worker			name: "error missing dir",
521*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
522*333d2b36SAndroid Build Coastguard Worker				Dir("missing"),
523*333d2b36SAndroid Build Coastguard Worker			err: os.ErrNotExist,
524*333d2b36SAndroid Build Coastguard Worker		},
525*333d2b36SAndroid Build Coastguard Worker		{
526*333d2b36SAndroid Build Coastguard Worker			name: "error missing file in list",
527*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
528*333d2b36SAndroid Build Coastguard Worker				List("l2"),
529*333d2b36SAndroid Build Coastguard Worker			err: os.ErrNotExist,
530*333d2b36SAndroid Build Coastguard Worker		},
531*333d2b36SAndroid Build Coastguard Worker		{
532*333d2b36SAndroid Build Coastguard Worker			name: "error incorrect relative root",
533*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
534*333d2b36SAndroid Build Coastguard Worker				SourcePrefixToStrip("b").
535*333d2b36SAndroid Build Coastguard Worker				File("a/a/a"),
536*333d2b36SAndroid Build Coastguard Worker			err: IncorrectRelativeRootError{},
537*333d2b36SAndroid Build Coastguard Worker		},
538*333d2b36SAndroid Build Coastguard Worker		{
539*333d2b36SAndroid Build Coastguard Worker			name: "error conflicting file",
540*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
541*333d2b36SAndroid Build Coastguard Worker				SourcePrefixToStrip("a").
542*333d2b36SAndroid Build Coastguard Worker				File("a/a/a").
543*333d2b36SAndroid Build Coastguard Worker				SourcePrefixToStrip("d").
544*333d2b36SAndroid Build Coastguard Worker				File("d/a/a"),
545*333d2b36SAndroid Build Coastguard Worker			err: ConflictingFileError{},
546*333d2b36SAndroid Build Coastguard Worker		},
547*333d2b36SAndroid Build Coastguard Worker		{
548*333d2b36SAndroid Build Coastguard Worker			name: "error explicit path conflicting",
549*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
550*333d2b36SAndroid Build Coastguard Worker				ExplicitPathInZip("foo").
551*333d2b36SAndroid Build Coastguard Worker				File("a/a/a").
552*333d2b36SAndroid Build Coastguard Worker				ExplicitPathInZip("foo").
553*333d2b36SAndroid Build Coastguard Worker				File("a/a/b"),
554*333d2b36SAndroid Build Coastguard Worker			err: ConflictingFileError{},
555*333d2b36SAndroid Build Coastguard Worker		},
556*333d2b36SAndroid Build Coastguard Worker		{
557*333d2b36SAndroid Build Coastguard Worker			name: "error explicit path conflicting glob",
558*333d2b36SAndroid Build Coastguard Worker			args: fileArgsBuilder().
559*333d2b36SAndroid Build Coastguard Worker				ExplicitPathInZip("foo").
560*333d2b36SAndroid Build Coastguard Worker				File("a/a/*"),
561*333d2b36SAndroid Build Coastguard Worker			err: ConflictingFileError{},
562*333d2b36SAndroid Build Coastguard Worker		},
563*333d2b36SAndroid Build Coastguard Worker	}
564*333d2b36SAndroid Build Coastguard Worker
565*333d2b36SAndroid Build Coastguard Worker	for _, test := range testCases {
566*333d2b36SAndroid Build Coastguard Worker		t.Run(test.name, func(t *testing.T) {
567*333d2b36SAndroid Build Coastguard Worker			if test.args.Error() != nil {
568*333d2b36SAndroid Build Coastguard Worker				t.Fatal(test.args.Error())
569*333d2b36SAndroid Build Coastguard Worker			}
570*333d2b36SAndroid Build Coastguard Worker
571*333d2b36SAndroid Build Coastguard Worker			args := ZipArgs{}
572*333d2b36SAndroid Build Coastguard Worker			args.FileArgs = test.args.FileArgs()
573*333d2b36SAndroid Build Coastguard Worker			args.CompressionLevel = test.compressionLevel
574*333d2b36SAndroid Build Coastguard Worker			args.EmulateJar = test.emulateJar
575*333d2b36SAndroid Build Coastguard Worker			args.AddDirectoryEntriesToZip = test.dirEntries
576*333d2b36SAndroid Build Coastguard Worker			args.NonDeflatedFiles = test.nonDeflatedFiles
577*333d2b36SAndroid Build Coastguard Worker			args.ManifestSourcePath = test.manifest
578*333d2b36SAndroid Build Coastguard Worker			args.StoreSymlinks = test.storeSymlinks
579*333d2b36SAndroid Build Coastguard Worker			args.IgnoreMissingFiles = test.ignoreMissingFiles
580*333d2b36SAndroid Build Coastguard Worker			args.Sha256Checksum = test.sha256Checksum
581*333d2b36SAndroid Build Coastguard Worker			args.Filesystem = mockFs
582*333d2b36SAndroid Build Coastguard Worker			args.Stderr = &bytes.Buffer{}
583*333d2b36SAndroid Build Coastguard Worker
584*333d2b36SAndroid Build Coastguard Worker			buf := &bytes.Buffer{}
585*333d2b36SAndroid Build Coastguard Worker			err := zipTo(args, buf)
586*333d2b36SAndroid Build Coastguard Worker
587*333d2b36SAndroid Build Coastguard Worker			if (err != nil) != (test.err != nil) {
588*333d2b36SAndroid Build Coastguard Worker				t.Fatalf("want error %v, got %v", test.err, err)
589*333d2b36SAndroid Build Coastguard Worker			} else if test.err != nil {
590*333d2b36SAndroid Build Coastguard Worker				if os.IsNotExist(test.err) {
591*333d2b36SAndroid Build Coastguard Worker					if !os.IsNotExist(err) {
592*333d2b36SAndroid Build Coastguard Worker						t.Fatalf("want error %v, got %v", test.err, err)
593*333d2b36SAndroid Build Coastguard Worker					}
594*333d2b36SAndroid Build Coastguard Worker				} else if _, wantRelativeRootErr := test.err.(IncorrectRelativeRootError); wantRelativeRootErr {
595*333d2b36SAndroid Build Coastguard Worker					if _, gotRelativeRootErr := err.(IncorrectRelativeRootError); !gotRelativeRootErr {
596*333d2b36SAndroid Build Coastguard Worker						t.Fatalf("want error %v, got %v", test.err, err)
597*333d2b36SAndroid Build Coastguard Worker					}
598*333d2b36SAndroid Build Coastguard Worker				} else if _, wantConflictingFileError := test.err.(ConflictingFileError); wantConflictingFileError {
599*333d2b36SAndroid Build Coastguard Worker					if _, gotConflictingFileError := err.(ConflictingFileError); !gotConflictingFileError {
600*333d2b36SAndroid Build Coastguard Worker						t.Fatalf("want error %v, got %v", test.err, err)
601*333d2b36SAndroid Build Coastguard Worker					}
602*333d2b36SAndroid Build Coastguard Worker				} else {
603*333d2b36SAndroid Build Coastguard Worker					t.Fatalf("want error %v, got %v", test.err, err)
604*333d2b36SAndroid Build Coastguard Worker				}
605*333d2b36SAndroid Build Coastguard Worker				return
606*333d2b36SAndroid Build Coastguard Worker			}
607*333d2b36SAndroid Build Coastguard Worker
608*333d2b36SAndroid Build Coastguard Worker			br := bytes.NewReader(buf.Bytes())
609*333d2b36SAndroid Build Coastguard Worker			zr, err := zip.NewReader(br, int64(br.Len()))
610*333d2b36SAndroid Build Coastguard Worker			if err != nil {
611*333d2b36SAndroid Build Coastguard Worker				t.Fatal(err)
612*333d2b36SAndroid Build Coastguard Worker			}
613*333d2b36SAndroid Build Coastguard Worker
614*333d2b36SAndroid Build Coastguard Worker			var files []zip.FileHeader
615*333d2b36SAndroid Build Coastguard Worker			for _, f := range zr.File {
616*333d2b36SAndroid Build Coastguard Worker				r, err := f.Open()
617*333d2b36SAndroid Build Coastguard Worker				if err != nil {
618*333d2b36SAndroid Build Coastguard Worker					t.Fatalf("error when opening %s: %s", f.Name, err)
619*333d2b36SAndroid Build Coastguard Worker				}
620*333d2b36SAndroid Build Coastguard Worker
621*333d2b36SAndroid Build Coastguard Worker				crc := crc32.NewIEEE()
622*333d2b36SAndroid Build Coastguard Worker				len, err := io.Copy(crc, r)
623*333d2b36SAndroid Build Coastguard Worker				r.Close()
624*333d2b36SAndroid Build Coastguard Worker				if err != nil {
625*333d2b36SAndroid Build Coastguard Worker					t.Fatalf("error when reading %s: %s", f.Name, err)
626*333d2b36SAndroid Build Coastguard Worker				}
627*333d2b36SAndroid Build Coastguard Worker
628*333d2b36SAndroid Build Coastguard Worker				if uint64(len) != f.UncompressedSize64 {
629*333d2b36SAndroid Build Coastguard Worker					t.Errorf("incorrect length for %s, want %d got %d", f.Name, f.UncompressedSize64, len)
630*333d2b36SAndroid Build Coastguard Worker				}
631*333d2b36SAndroid Build Coastguard Worker
632*333d2b36SAndroid Build Coastguard Worker				if crc.Sum32() != f.CRC32 {
633*333d2b36SAndroid Build Coastguard Worker					t.Errorf("incorrect crc for %s, want %x got %x", f.Name, f.CRC32, crc)
634*333d2b36SAndroid Build Coastguard Worker				}
635*333d2b36SAndroid Build Coastguard Worker
636*333d2b36SAndroid Build Coastguard Worker				files = append(files, f.FileHeader)
637*333d2b36SAndroid Build Coastguard Worker			}
638*333d2b36SAndroid Build Coastguard Worker
639*333d2b36SAndroid Build Coastguard Worker			if len(files) != len(test.files) {
640*333d2b36SAndroid Build Coastguard Worker				t.Fatalf("want %d files, got %d", len(test.files), len(files))
641*333d2b36SAndroid Build Coastguard Worker			}
642*333d2b36SAndroid Build Coastguard Worker
643*333d2b36SAndroid Build Coastguard Worker			for i := range files {
644*333d2b36SAndroid Build Coastguard Worker				want := test.files[i]
645*333d2b36SAndroid Build Coastguard Worker				got := files[i]
646*333d2b36SAndroid Build Coastguard Worker
647*333d2b36SAndroid Build Coastguard Worker				if want.Name != got.Name {
648*333d2b36SAndroid Build Coastguard Worker					t.Errorf("incorrect file %d want %q got %q", i, want.Name, got.Name)
649*333d2b36SAndroid Build Coastguard Worker					continue
650*333d2b36SAndroid Build Coastguard Worker				}
651*333d2b36SAndroid Build Coastguard Worker
652*333d2b36SAndroid Build Coastguard Worker				if want.UncompressedSize64 != got.UncompressedSize64 {
653*333d2b36SAndroid Build Coastguard Worker					t.Errorf("incorrect file %s length want %v got %v", want.Name,
654*333d2b36SAndroid Build Coastguard Worker						want.UncompressedSize64, got.UncompressedSize64)
655*333d2b36SAndroid Build Coastguard Worker				}
656*333d2b36SAndroid Build Coastguard Worker
657*333d2b36SAndroid Build Coastguard Worker				if want.ExternalAttrs != got.ExternalAttrs {
658*333d2b36SAndroid Build Coastguard Worker					t.Errorf("incorrect file %s attrs want %x got %x", want.Name,
659*333d2b36SAndroid Build Coastguard Worker						want.ExternalAttrs, got.ExternalAttrs)
660*333d2b36SAndroid Build Coastguard Worker				}
661*333d2b36SAndroid Build Coastguard Worker
662*333d2b36SAndroid Build Coastguard Worker				if want.CRC32 != got.CRC32 {
663*333d2b36SAndroid Build Coastguard Worker					t.Errorf("incorrect file %s crc want %v got %v", want.Name,
664*333d2b36SAndroid Build Coastguard Worker						want.CRC32, got.CRC32)
665*333d2b36SAndroid Build Coastguard Worker				}
666*333d2b36SAndroid Build Coastguard Worker
667*333d2b36SAndroid Build Coastguard Worker				if want.Method != got.Method {
668*333d2b36SAndroid Build Coastguard Worker					t.Errorf("incorrect file %s method want %v got %v", want.Name,
669*333d2b36SAndroid Build Coastguard Worker						want.Method, got.Method)
670*333d2b36SAndroid Build Coastguard Worker				}
671*333d2b36SAndroid Build Coastguard Worker
672*333d2b36SAndroid Build Coastguard Worker				if !bytes.Equal(want.Extra, got.Extra) {
673*333d2b36SAndroid Build Coastguard Worker					t.Errorf("incorrect file %s extra want %v got %v", want.Name,
674*333d2b36SAndroid Build Coastguard Worker						want.Extra, got.Extra)
675*333d2b36SAndroid Build Coastguard Worker				}
676*333d2b36SAndroid Build Coastguard Worker			}
677*333d2b36SAndroid Build Coastguard Worker		})
678*333d2b36SAndroid Build Coastguard Worker	}
679*333d2b36SAndroid Build Coastguard Worker}
680*333d2b36SAndroid Build Coastguard Worker
681*333d2b36SAndroid Build Coastguard Workerfunc TestSrcJar(t *testing.T) {
682*333d2b36SAndroid Build Coastguard Worker	mockFs := pathtools.MockFs(map[string][]byte{
683*333d2b36SAndroid Build Coastguard Worker		"wrong_package.java":       []byte("package foo;"),
684*333d2b36SAndroid Build Coastguard Worker		"foo/correct_package.java": []byte("package foo;"),
685*333d2b36SAndroid Build Coastguard Worker		"src/no_package.java":      nil,
686*333d2b36SAndroid Build Coastguard Worker		"src2/parse_error.java":    []byte("error"),
687*333d2b36SAndroid Build Coastguard Worker	})
688*333d2b36SAndroid Build Coastguard Worker
689*333d2b36SAndroid Build Coastguard Worker	want := []string{
690*333d2b36SAndroid Build Coastguard Worker		"foo/",
691*333d2b36SAndroid Build Coastguard Worker		"foo/wrong_package.java",
692*333d2b36SAndroid Build Coastguard Worker		"foo/correct_package.java",
693*333d2b36SAndroid Build Coastguard Worker		"no_package.java",
694*333d2b36SAndroid Build Coastguard Worker		"src2/",
695*333d2b36SAndroid Build Coastguard Worker		"src2/parse_error.java",
696*333d2b36SAndroid Build Coastguard Worker	}
697*333d2b36SAndroid Build Coastguard Worker
698*333d2b36SAndroid Build Coastguard Worker	args := ZipArgs{}
699*333d2b36SAndroid Build Coastguard Worker	args.FileArgs = NewFileArgsBuilder().File("**/*.java").FileArgs()
700*333d2b36SAndroid Build Coastguard Worker
701*333d2b36SAndroid Build Coastguard Worker	args.SrcJar = true
702*333d2b36SAndroid Build Coastguard Worker	args.AddDirectoryEntriesToZip = true
703*333d2b36SAndroid Build Coastguard Worker	args.Filesystem = mockFs
704*333d2b36SAndroid Build Coastguard Worker	args.Stderr = &bytes.Buffer{}
705*333d2b36SAndroid Build Coastguard Worker
706*333d2b36SAndroid Build Coastguard Worker	buf := &bytes.Buffer{}
707*333d2b36SAndroid Build Coastguard Worker	err := zipTo(args, buf)
708*333d2b36SAndroid Build Coastguard Worker	if err != nil {
709*333d2b36SAndroid Build Coastguard Worker		t.Fatalf("got error %v", err)
710*333d2b36SAndroid Build Coastguard Worker	}
711*333d2b36SAndroid Build Coastguard Worker
712*333d2b36SAndroid Build Coastguard Worker	br := bytes.NewReader(buf.Bytes())
713*333d2b36SAndroid Build Coastguard Worker	zr, err := zip.NewReader(br, int64(br.Len()))
714*333d2b36SAndroid Build Coastguard Worker	if err != nil {
715*333d2b36SAndroid Build Coastguard Worker		t.Fatal(err)
716*333d2b36SAndroid Build Coastguard Worker	}
717*333d2b36SAndroid Build Coastguard Worker
718*333d2b36SAndroid Build Coastguard Worker	var got []string
719*333d2b36SAndroid Build Coastguard Worker	for _, f := range zr.File {
720*333d2b36SAndroid Build Coastguard Worker		r, err := f.Open()
721*333d2b36SAndroid Build Coastguard Worker		if err != nil {
722*333d2b36SAndroid Build Coastguard Worker			t.Fatalf("error when opening %s: %s", f.Name, err)
723*333d2b36SAndroid Build Coastguard Worker		}
724*333d2b36SAndroid Build Coastguard Worker
725*333d2b36SAndroid Build Coastguard Worker		crc := crc32.NewIEEE()
726*333d2b36SAndroid Build Coastguard Worker		len, err := io.Copy(crc, r)
727*333d2b36SAndroid Build Coastguard Worker		r.Close()
728*333d2b36SAndroid Build Coastguard Worker		if err != nil {
729*333d2b36SAndroid Build Coastguard Worker			t.Fatalf("error when reading %s: %s", f.Name, err)
730*333d2b36SAndroid Build Coastguard Worker		}
731*333d2b36SAndroid Build Coastguard Worker
732*333d2b36SAndroid Build Coastguard Worker		if uint64(len) != f.UncompressedSize64 {
733*333d2b36SAndroid Build Coastguard Worker			t.Errorf("incorrect length for %s, want %d got %d", f.Name, f.UncompressedSize64, len)
734*333d2b36SAndroid Build Coastguard Worker		}
735*333d2b36SAndroid Build Coastguard Worker
736*333d2b36SAndroid Build Coastguard Worker		if crc.Sum32() != f.CRC32 {
737*333d2b36SAndroid Build Coastguard Worker			t.Errorf("incorrect crc for %s, want %x got %x", f.Name, f.CRC32, crc)
738*333d2b36SAndroid Build Coastguard Worker		}
739*333d2b36SAndroid Build Coastguard Worker
740*333d2b36SAndroid Build Coastguard Worker		got = append(got, f.Name)
741*333d2b36SAndroid Build Coastguard Worker	}
742*333d2b36SAndroid Build Coastguard Worker
743*333d2b36SAndroid Build Coastguard Worker	if !reflect.DeepEqual(want, got) {
744*333d2b36SAndroid Build Coastguard Worker		t.Errorf("want files %q, got %q", want, got)
745*333d2b36SAndroid Build Coastguard Worker	}
746*333d2b36SAndroid Build Coastguard Worker}
747