blob: ae1649447bd1c394915a220a11adf93c6184e736 [file] [log] [blame]
Dan Willemsen82218f22017-06-19 16:35:00 -07001// Copyright 2017 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package main
16
17import (
18 "bytes"
19 "fmt"
20 "reflect"
21 "testing"
22
23 "android/soong/third_party/zip"
24)
25
26var testCases = []struct {
27 name string
28
Colin Crossb1a5e9c2018-10-07 21:30:12 -070029 inputFiles []string
30 sortGlobs bool
31 sortJava bool
32 args []string
33 excludes []string
Colin Cross38247712018-10-09 10:19:54 -070034 includes []string
Colin Crossb1a5e9c2018-10-07 21:30:12 -070035 uncompresses []string
Dan Willemsen82218f22017-06-19 16:35:00 -070036
37 outputFiles []string
Colin Crossb1a5e9c2018-10-07 21:30:12 -070038 storedFiles []string
Dan Willemsen82218f22017-06-19 16:35:00 -070039 err error
40}{
41 {
42 name: "unsupported \\",
43
44 args: []string{"a\\b:b"},
45
46 err: fmt.Errorf("\\ characters are not currently supported"),
47 },
Dan Willemsen82218f22017-06-19 16:35:00 -070048 { // This is modelled after the update package build rules in build/make/core/Makefile
49 name: "filter globs",
50
51 inputFiles: []string{
52 "RADIO/a",
53 "IMAGES/system.img",
54 "IMAGES/b.txt",
55 "IMAGES/recovery.img",
56 "IMAGES/vendor.img",
57 "OTA/android-info.txt",
58 "OTA/b",
59 },
60 args: []string{"OTA/android-info.txt:android-info.txt", "IMAGES/*.img:."},
61
62 outputFiles: []string{
63 "android-info.txt",
64 "system.img",
65 "recovery.img",
66 "vendor.img",
67 },
68 },
69 {
70 name: "sorted filter globs",
71
72 inputFiles: []string{
73 "RADIO/a",
74 "IMAGES/system.img",
75 "IMAGES/b.txt",
76 "IMAGES/recovery.img",
77 "IMAGES/vendor.img",
78 "OTA/android-info.txt",
79 "OTA/b",
80 },
81 sortGlobs: true,
82 args: []string{"IMAGES/*.img:.", "OTA/android-info.txt:android-info.txt"},
83
84 outputFiles: []string{
85 "recovery.img",
86 "system.img",
87 "vendor.img",
88 "android-info.txt",
89 },
90 },
91 {
92 name: "sort all",
93
94 inputFiles: []string{
Colin Crossf3831d02017-11-22 12:53:08 -080095 "RADIO/",
Dan Willemsen82218f22017-06-19 16:35:00 -070096 "RADIO/a",
Colin Crossf3831d02017-11-22 12:53:08 -080097 "IMAGES/",
Dan Willemsen82218f22017-06-19 16:35:00 -070098 "IMAGES/system.img",
99 "IMAGES/b.txt",
100 "IMAGES/recovery.img",
101 "IMAGES/vendor.img",
Colin Crossf3831d02017-11-22 12:53:08 -0800102 "OTA/",
Dan Willemsen82218f22017-06-19 16:35:00 -0700103 "OTA/b",
104 "OTA/android-info.txt",
105 },
106 sortGlobs: true,
Colin Crossf3831d02017-11-22 12:53:08 -0800107 args: []string{"**/*"},
Dan Willemsen82218f22017-06-19 16:35:00 -0700108
109 outputFiles: []string{
110 "IMAGES/b.txt",
111 "IMAGES/recovery.img",
112 "IMAGES/system.img",
113 "IMAGES/vendor.img",
114 "OTA/android-info.txt",
115 "OTA/b",
116 "RADIO/a",
117 },
118 },
119 {
Colin Cross06382992017-06-23 14:08:42 -0700120 name: "sort all implicit",
121
122 inputFiles: []string{
Colin Crossf3831d02017-11-22 12:53:08 -0800123 "RADIO/",
Colin Cross06382992017-06-23 14:08:42 -0700124 "RADIO/a",
Colin Crossf3831d02017-11-22 12:53:08 -0800125 "IMAGES/",
Colin Cross06382992017-06-23 14:08:42 -0700126 "IMAGES/system.img",
127 "IMAGES/b.txt",
128 "IMAGES/recovery.img",
129 "IMAGES/vendor.img",
Colin Crossf3831d02017-11-22 12:53:08 -0800130 "OTA/",
Colin Cross06382992017-06-23 14:08:42 -0700131 "OTA/b",
132 "OTA/android-info.txt",
133 },
134 sortGlobs: true,
135 args: nil,
136
137 outputFiles: []string{
Colin Crossf3831d02017-11-22 12:53:08 -0800138 "IMAGES/",
Colin Cross06382992017-06-23 14:08:42 -0700139 "IMAGES/b.txt",
140 "IMAGES/recovery.img",
141 "IMAGES/system.img",
142 "IMAGES/vendor.img",
Colin Crossf3831d02017-11-22 12:53:08 -0800143 "OTA/",
Colin Cross06382992017-06-23 14:08:42 -0700144 "OTA/android-info.txt",
145 "OTA/b",
Colin Crossf3831d02017-11-22 12:53:08 -0800146 "RADIO/",
Colin Cross06382992017-06-23 14:08:42 -0700147 "RADIO/a",
148 },
149 },
150 {
Colin Cross8936b022017-06-23 13:00:17 -0700151 name: "sort jar",
152
153 inputFiles: []string{
154 "MANIFEST.MF",
155 "META-INF/MANIFEST.MF",
156 "META-INF/aaa/",
157 "META-INF/aaa/aaa",
158 "META-INF/AAA",
159 "META-INF.txt",
160 "META-INF/",
161 "AAA",
162 "aaa",
163 },
164 sortJava: true,
165 args: nil,
166
167 outputFiles: []string{
168 "META-INF/",
169 "META-INF/MANIFEST.MF",
170 "META-INF/AAA",
171 "META-INF/aaa/",
172 "META-INF/aaa/aaa",
173 "AAA",
174 "MANIFEST.MF",
175 "META-INF.txt",
176 "aaa",
177 },
178 },
179 {
Dan Willemsen82218f22017-06-19 16:35:00 -0700180 name: "double input",
181
182 inputFiles: []string{
183 "b",
184 "a",
185 },
Colin Crossf3831d02017-11-22 12:53:08 -0800186 args: []string{"a:a2", "**/*"},
Dan Willemsen82218f22017-06-19 16:35:00 -0700187
188 outputFiles: []string{
189 "a2",
190 "b",
191 "a",
192 },
193 },
Colin Crossf3831d02017-11-22 12:53:08 -0800194 {
195 name: "multiple matches",
196
197 inputFiles: []string{
198 "a/a",
199 },
200 args: []string{"a/a", "a/*"},
201
202 outputFiles: []string{
203 "a/a",
204 },
205 },
206 {
207 name: "multiple conflicting matches",
208
209 inputFiles: []string{
210 "a/a",
211 "a/b",
212 },
213 args: []string{"a/b:a/a", "a/*"},
214
215 err: fmt.Errorf(`multiple entries for "a/a" with different contents`),
216 },
217 {
218 name: "excludes",
219
220 inputFiles: []string{
221 "a/a",
222 "a/b",
223 },
224 args: nil,
225 excludes: []string{"a/a"},
226
227 outputFiles: []string{
228 "a/b",
229 },
230 },
231 {
Colin Cross38247712018-10-09 10:19:54 -0700232 name: "excludes with args",
Colin Crossf3831d02017-11-22 12:53:08 -0800233
234 inputFiles: []string{
235 "a/a",
236 "a/b",
237 },
238 args: []string{"a/*"},
239 excludes: []string{"a/a"},
240
241 outputFiles: []string{
242 "a/b",
243 },
244 },
245 {
Colin Cross38247712018-10-09 10:19:54 -0700246 name: "excludes over args",
247
248 inputFiles: []string{
249 "a/a",
250 "a/b",
251 },
252 args: []string{"a/a"},
253 excludes: []string{"a/*"},
254
255 outputFiles: nil,
256 },
257 {
258 name: "excludes with includes",
259
260 inputFiles: []string{
261 "a/a",
262 "a/b",
263 },
264 args: nil,
265 excludes: []string{"a/*"},
266 includes: []string{"a/b"},
267
268 outputFiles: []string{"a/b"},
269 },
270 {
Colin Crossf3831d02017-11-22 12:53:08 -0800271 name: "excludes with glob",
272
273 inputFiles: []string{
274 "a/a",
275 "a/b",
276 },
277 args: []string{"a/*"},
278 excludes: []string{"a/*"},
279
280 outputFiles: nil,
281 },
Colin Crossb1a5e9c2018-10-07 21:30:12 -0700282 {
283 name: "uncompress one",
284
285 inputFiles: []string{
286 "a/a",
287 "a/b",
288 },
289 uncompresses: []string{"a/a"},
290
291 outputFiles: []string{
292 "a/a",
293 "a/b",
294 },
295 storedFiles: []string{
296 "a/a",
297 },
298 },
299 {
300 name: "uncompress two",
301
302 inputFiles: []string{
303 "a/a",
304 "a/b",
305 },
306 uncompresses: []string{"a/a", "a/b"},
307
308 outputFiles: []string{
309 "a/a",
310 "a/b",
311 },
312 storedFiles: []string{
313 "a/a",
314 "a/b",
315 },
316 },
317 {
318 name: "uncompress glob",
319
320 inputFiles: []string{
321 "a/a",
322 "a/b",
323 "a/c.so",
324 "a/d.so",
325 },
326 uncompresses: []string{"a/*.so"},
327
328 outputFiles: []string{
329 "a/a",
330 "a/b",
331 "a/c.so",
332 "a/d.so",
333 },
334 storedFiles: []string{
335 "a/c.so",
336 "a/d.so",
337 },
338 },
339 {
340 name: "uncompress rename",
341
342 inputFiles: []string{
343 "a/a",
344 },
345 args: []string{"a/a:a/b"},
346 uncompresses: []string{"a/b"},
347
348 outputFiles: []string{
349 "a/b",
350 },
351 storedFiles: []string{
352 "a/b",
353 },
354 },
Dan Willemsen82218f22017-06-19 16:35:00 -0700355}
356
357func errorString(e error) string {
358 if e == nil {
359 return ""
360 }
361 return e.Error()
362}
363
364func TestZip2Zip(t *testing.T) {
365 for _, testCase := range testCases {
366 t.Run(testCase.name, func(t *testing.T) {
367 inputBuf := &bytes.Buffer{}
368 outputBuf := &bytes.Buffer{}
369
370 inputWriter := zip.NewWriter(inputBuf)
371 for _, file := range testCase.inputFiles {
372 w, err := inputWriter.Create(file)
373 if err != nil {
374 t.Fatal(err)
375 }
376 fmt.Fprintln(w, "test")
377 }
378 inputWriter.Close()
379 inputBytes := inputBuf.Bytes()
380 inputReader, err := zip.NewReader(bytes.NewReader(inputBytes), int64(len(inputBytes)))
381 if err != nil {
382 t.Fatal(err)
383 }
384
385 outputWriter := zip.NewWriter(outputBuf)
Colin Crossb1a5e9c2018-10-07 21:30:12 -0700386 err = zip2zip(inputReader, outputWriter, testCase.sortGlobs, testCase.sortJava, false,
Colin Cross38247712018-10-09 10:19:54 -0700387 testCase.args, testCase.excludes, testCase.includes, testCase.uncompresses)
Dan Willemsen82218f22017-06-19 16:35:00 -0700388 if errorString(testCase.err) != errorString(err) {
389 t.Fatalf("Unexpected error:\n got: %q\nwant: %q", errorString(err), errorString(testCase.err))
390 }
391
392 outputWriter.Close()
393 outputBytes := outputBuf.Bytes()
394 outputReader, err := zip.NewReader(bytes.NewReader(outputBytes), int64(len(outputBytes)))
395 if err != nil {
396 t.Fatal(err)
397 }
398 var outputFiles []string
Colin Crossb1a5e9c2018-10-07 21:30:12 -0700399 var storedFiles []string
Dan Willemsen82218f22017-06-19 16:35:00 -0700400 if len(outputReader.File) > 0 {
401 outputFiles = make([]string, len(outputReader.File))
402 for i, file := range outputReader.File {
403 outputFiles[i] = file.Name
Colin Crossb1a5e9c2018-10-07 21:30:12 -0700404 if file.Method == zip.Store {
405 storedFiles = append(storedFiles, file.Name)
406 }
Dan Willemsen82218f22017-06-19 16:35:00 -0700407 }
408 }
409
410 if !reflect.DeepEqual(testCase.outputFiles, outputFiles) {
Colin Crossb1a5e9c2018-10-07 21:30:12 -0700411 t.Fatalf("Output file list does not match:\nwant: %v\n got: %v", testCase.outputFiles, outputFiles)
412 }
413 if !reflect.DeepEqual(testCase.storedFiles, storedFiles) {
414 t.Fatalf("Stored file list does not match:\nwant: %v\n got: %v", testCase.storedFiles, storedFiles)
Dan Willemsen82218f22017-06-19 16:35:00 -0700415 }
416 })
417 }
418}