blob: e032fe6919c2cfcd9b25a7d5a1c607121e9d308a [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
34 uncompresses []string
Dan Willemsen82218f22017-06-19 16:35:00 -070035
36 outputFiles []string
Colin Crossb1a5e9c2018-10-07 21:30:12 -070037 storedFiles []string
Dan Willemsen82218f22017-06-19 16:35:00 -070038 err error
39}{
40 {
41 name: "unsupported \\",
42
43 args: []string{"a\\b:b"},
44
45 err: fmt.Errorf("\\ characters are not currently supported"),
46 },
Dan Willemsen82218f22017-06-19 16:35:00 -070047 { // This is modelled after the update package build rules in build/make/core/Makefile
48 name: "filter globs",
49
50 inputFiles: []string{
51 "RADIO/a",
52 "IMAGES/system.img",
53 "IMAGES/b.txt",
54 "IMAGES/recovery.img",
55 "IMAGES/vendor.img",
56 "OTA/android-info.txt",
57 "OTA/b",
58 },
59 args: []string{"OTA/android-info.txt:android-info.txt", "IMAGES/*.img:."},
60
61 outputFiles: []string{
62 "android-info.txt",
63 "system.img",
64 "recovery.img",
65 "vendor.img",
66 },
67 },
68 {
69 name: "sorted filter globs",
70
71 inputFiles: []string{
72 "RADIO/a",
73 "IMAGES/system.img",
74 "IMAGES/b.txt",
75 "IMAGES/recovery.img",
76 "IMAGES/vendor.img",
77 "OTA/android-info.txt",
78 "OTA/b",
79 },
80 sortGlobs: true,
81 args: []string{"IMAGES/*.img:.", "OTA/android-info.txt:android-info.txt"},
82
83 outputFiles: []string{
84 "recovery.img",
85 "system.img",
86 "vendor.img",
87 "android-info.txt",
88 },
89 },
90 {
91 name: "sort all",
92
93 inputFiles: []string{
Colin Crossf3831d02017-11-22 12:53:08 -080094 "RADIO/",
Dan Willemsen82218f22017-06-19 16:35:00 -070095 "RADIO/a",
Colin Crossf3831d02017-11-22 12:53:08 -080096 "IMAGES/",
Dan Willemsen82218f22017-06-19 16:35:00 -070097 "IMAGES/system.img",
98 "IMAGES/b.txt",
99 "IMAGES/recovery.img",
100 "IMAGES/vendor.img",
Colin Crossf3831d02017-11-22 12:53:08 -0800101 "OTA/",
Dan Willemsen82218f22017-06-19 16:35:00 -0700102 "OTA/b",
103 "OTA/android-info.txt",
104 },
105 sortGlobs: true,
Colin Crossf3831d02017-11-22 12:53:08 -0800106 args: []string{"**/*"},
Dan Willemsen82218f22017-06-19 16:35:00 -0700107
108 outputFiles: []string{
109 "IMAGES/b.txt",
110 "IMAGES/recovery.img",
111 "IMAGES/system.img",
112 "IMAGES/vendor.img",
113 "OTA/android-info.txt",
114 "OTA/b",
115 "RADIO/a",
116 },
117 },
118 {
Colin Cross06382992017-06-23 14:08:42 -0700119 name: "sort all implicit",
120
121 inputFiles: []string{
Colin Crossf3831d02017-11-22 12:53:08 -0800122 "RADIO/",
Colin Cross06382992017-06-23 14:08:42 -0700123 "RADIO/a",
Colin Crossf3831d02017-11-22 12:53:08 -0800124 "IMAGES/",
Colin Cross06382992017-06-23 14:08:42 -0700125 "IMAGES/system.img",
126 "IMAGES/b.txt",
127 "IMAGES/recovery.img",
128 "IMAGES/vendor.img",
Colin Crossf3831d02017-11-22 12:53:08 -0800129 "OTA/",
Colin Cross06382992017-06-23 14:08:42 -0700130 "OTA/b",
131 "OTA/android-info.txt",
132 },
133 sortGlobs: true,
134 args: nil,
135
136 outputFiles: []string{
Colin Crossf3831d02017-11-22 12:53:08 -0800137 "IMAGES/",
Colin Cross06382992017-06-23 14:08:42 -0700138 "IMAGES/b.txt",
139 "IMAGES/recovery.img",
140 "IMAGES/system.img",
141 "IMAGES/vendor.img",
Colin Crossf3831d02017-11-22 12:53:08 -0800142 "OTA/",
Colin Cross06382992017-06-23 14:08:42 -0700143 "OTA/android-info.txt",
144 "OTA/b",
Colin Crossf3831d02017-11-22 12:53:08 -0800145 "RADIO/",
Colin Cross06382992017-06-23 14:08:42 -0700146 "RADIO/a",
147 },
148 },
149 {
Colin Cross8936b022017-06-23 13:00:17 -0700150 name: "sort jar",
151
152 inputFiles: []string{
153 "MANIFEST.MF",
154 "META-INF/MANIFEST.MF",
155 "META-INF/aaa/",
156 "META-INF/aaa/aaa",
157 "META-INF/AAA",
158 "META-INF.txt",
159 "META-INF/",
160 "AAA",
161 "aaa",
162 },
163 sortJava: true,
164 args: nil,
165
166 outputFiles: []string{
167 "META-INF/",
168 "META-INF/MANIFEST.MF",
169 "META-INF/AAA",
170 "META-INF/aaa/",
171 "META-INF/aaa/aaa",
172 "AAA",
173 "MANIFEST.MF",
174 "META-INF.txt",
175 "aaa",
176 },
177 },
178 {
Dan Willemsen82218f22017-06-19 16:35:00 -0700179 name: "double input",
180
181 inputFiles: []string{
182 "b",
183 "a",
184 },
Colin Crossf3831d02017-11-22 12:53:08 -0800185 args: []string{"a:a2", "**/*"},
Dan Willemsen82218f22017-06-19 16:35:00 -0700186
187 outputFiles: []string{
188 "a2",
189 "b",
190 "a",
191 },
192 },
Colin Crossf3831d02017-11-22 12:53:08 -0800193 {
194 name: "multiple matches",
195
196 inputFiles: []string{
197 "a/a",
198 },
199 args: []string{"a/a", "a/*"},
200
201 outputFiles: []string{
202 "a/a",
203 },
204 },
205 {
206 name: "multiple conflicting matches",
207
208 inputFiles: []string{
209 "a/a",
210 "a/b",
211 },
212 args: []string{"a/b:a/a", "a/*"},
213
214 err: fmt.Errorf(`multiple entries for "a/a" with different contents`),
215 },
216 {
217 name: "excludes",
218
219 inputFiles: []string{
220 "a/a",
221 "a/b",
222 },
223 args: nil,
224 excludes: []string{"a/a"},
225
226 outputFiles: []string{
227 "a/b",
228 },
229 },
230 {
231 name: "excludes with include",
232
233 inputFiles: []string{
234 "a/a",
235 "a/b",
236 },
237 args: []string{"a/*"},
238 excludes: []string{"a/a"},
239
240 outputFiles: []string{
241 "a/b",
242 },
243 },
244 {
245 name: "excludes with glob",
246
247 inputFiles: []string{
248 "a/a",
249 "a/b",
250 },
251 args: []string{"a/*"},
252 excludes: []string{"a/*"},
253
254 outputFiles: nil,
255 },
Colin Crossb1a5e9c2018-10-07 21:30:12 -0700256 {
257 name: "uncompress one",
258
259 inputFiles: []string{
260 "a/a",
261 "a/b",
262 },
263 uncompresses: []string{"a/a"},
264
265 outputFiles: []string{
266 "a/a",
267 "a/b",
268 },
269 storedFiles: []string{
270 "a/a",
271 },
272 },
273 {
274 name: "uncompress two",
275
276 inputFiles: []string{
277 "a/a",
278 "a/b",
279 },
280 uncompresses: []string{"a/a", "a/b"},
281
282 outputFiles: []string{
283 "a/a",
284 "a/b",
285 },
286 storedFiles: []string{
287 "a/a",
288 "a/b",
289 },
290 },
291 {
292 name: "uncompress glob",
293
294 inputFiles: []string{
295 "a/a",
296 "a/b",
297 "a/c.so",
298 "a/d.so",
299 },
300 uncompresses: []string{"a/*.so"},
301
302 outputFiles: []string{
303 "a/a",
304 "a/b",
305 "a/c.so",
306 "a/d.so",
307 },
308 storedFiles: []string{
309 "a/c.so",
310 "a/d.so",
311 },
312 },
313 {
314 name: "uncompress rename",
315
316 inputFiles: []string{
317 "a/a",
318 },
319 args: []string{"a/a:a/b"},
320 uncompresses: []string{"a/b"},
321
322 outputFiles: []string{
323 "a/b",
324 },
325 storedFiles: []string{
326 "a/b",
327 },
328 },
Dan Willemsen82218f22017-06-19 16:35:00 -0700329}
330
331func errorString(e error) string {
332 if e == nil {
333 return ""
334 }
335 return e.Error()
336}
337
338func TestZip2Zip(t *testing.T) {
339 for _, testCase := range testCases {
340 t.Run(testCase.name, func(t *testing.T) {
341 inputBuf := &bytes.Buffer{}
342 outputBuf := &bytes.Buffer{}
343
344 inputWriter := zip.NewWriter(inputBuf)
345 for _, file := range testCase.inputFiles {
346 w, err := inputWriter.Create(file)
347 if err != nil {
348 t.Fatal(err)
349 }
350 fmt.Fprintln(w, "test")
351 }
352 inputWriter.Close()
353 inputBytes := inputBuf.Bytes()
354 inputReader, err := zip.NewReader(bytes.NewReader(inputBytes), int64(len(inputBytes)))
355 if err != nil {
356 t.Fatal(err)
357 }
358
359 outputWriter := zip.NewWriter(outputBuf)
Colin Crossb1a5e9c2018-10-07 21:30:12 -0700360 err = zip2zip(inputReader, outputWriter, testCase.sortGlobs, testCase.sortJava, false,
361 testCase.args, testCase.excludes, testCase.uncompresses)
Dan Willemsen82218f22017-06-19 16:35:00 -0700362 if errorString(testCase.err) != errorString(err) {
363 t.Fatalf("Unexpected error:\n got: %q\nwant: %q", errorString(err), errorString(testCase.err))
364 }
365
366 outputWriter.Close()
367 outputBytes := outputBuf.Bytes()
368 outputReader, err := zip.NewReader(bytes.NewReader(outputBytes), int64(len(outputBytes)))
369 if err != nil {
370 t.Fatal(err)
371 }
372 var outputFiles []string
Colin Crossb1a5e9c2018-10-07 21:30:12 -0700373 var storedFiles []string
Dan Willemsen82218f22017-06-19 16:35:00 -0700374 if len(outputReader.File) > 0 {
375 outputFiles = make([]string, len(outputReader.File))
376 for i, file := range outputReader.File {
377 outputFiles[i] = file.Name
Colin Crossb1a5e9c2018-10-07 21:30:12 -0700378 if file.Method == zip.Store {
379 storedFiles = append(storedFiles, file.Name)
380 }
Dan Willemsen82218f22017-06-19 16:35:00 -0700381 }
382 }
383
384 if !reflect.DeepEqual(testCase.outputFiles, outputFiles) {
Colin Crossb1a5e9c2018-10-07 21:30:12 -0700385 t.Fatalf("Output file list does not match:\nwant: %v\n got: %v", testCase.outputFiles, outputFiles)
386 }
387 if !reflect.DeepEqual(testCase.storedFiles, storedFiles) {
388 t.Fatalf("Stored file list does not match:\nwant: %v\n got: %v", testCase.storedFiles, storedFiles)
Dan Willemsen82218f22017-06-19 16:35:00 -0700389 }
390 })
391 }
392}