1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.tools.build.apkzlib.zip; 18 19 import static org.junit.Assert.assertArrayEquals; 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertNotNull; 22 import static org.junit.Assert.assertTrue; 23 24 import java.io.ByteArrayInputStream; 25 import java.io.File; 26 import javax.annotation.Nullable; 27 import org.junit.After; 28 import org.junit.Before; 29 import org.junit.Rule; 30 import org.junit.Test; 31 import org.junit.rules.TemporaryFolder; 32 33 public class ZFileSortTest { 34 @Rule 35 public TemporaryFolder mTemporaryFolder = new TemporaryFolder(); 36 private File mFile; 37 private ZFile mZFile; 38 private StoredEntry mMaryEntry; 39 private long mMaryOffset; 40 private StoredEntry mAndrewEntry; 41 private long mAndrewOffset; 42 private StoredEntry mBethEntry; 43 private long mBethOffset; 44 private StoredEntry mPeterEntry; 45 private long mPeterOffset; 46 47 @Before 48 public final void before() throws Exception { 49 mFile = new File(mTemporaryFolder.getRoot(), "a.zip"); 50 setupZFile(null); 51 } 52 53 @After 54 public final void after() throws Exception { 55 mZFile.close(); 56 } 57 58 /** 59 * Recreates the zip file, if one already exist. 60 * 61 * @param options the options for the file, may be {@code null} in which case the default 62 * options will be used 63 * @throws Exception failed to re-create the file 64 */ 65 private void setupZFile(@Nullable ZFileOptions options) throws Exception { 66 if (mZFile != null) { 67 mZFile.close(); 68 } 69 70 if (mFile.exists()) { 71 assertTrue(mFile.delete()); 72 } 73 74 if (options == null) { 75 options = new ZFileOptions(); 76 } 77 78 mZFile = new ZFile(mFile, options); 79 80 mZFile.add("Mary.xml", new ByteArrayInputStream(new byte[] { 1, 2, 3 })); 81 mZFile.add("Andrew.txt", new ByteArrayInputStream(new byte[] { 4, 5 })); 82 mZFile.add("Beth.png", new ByteArrayInputStream(new byte[] { 6, 7, 8, 9 })); 83 mZFile.add("Peter.html", new ByteArrayInputStream(new byte[] { 10 })); 84 mZFile.finishAllBackgroundTasks(); 85 } 86 87 private void readEntries() throws Exception { 88 mMaryEntry = mZFile.get("Mary.xml"); 89 assertNotNull(mMaryEntry); 90 mMaryOffset = mMaryEntry.getCentralDirectoryHeader().getOffset(); 91 assertArrayEquals(new byte[] { 1, 2, 3 }, mMaryEntry.read()); 92 93 mAndrewEntry = mZFile.get("Andrew.txt"); 94 assertNotNull(mAndrewEntry); 95 mAndrewOffset = mAndrewEntry.getCentralDirectoryHeader().getOffset(); 96 assertArrayEquals(new byte[] { 4, 5 }, mAndrewEntry.read()); 97 98 mBethEntry = mZFile.get("Beth.png"); 99 assertNotNull(mBethEntry); 100 mBethOffset = mBethEntry.getCentralDirectoryHeader().getOffset(); 101 assertArrayEquals(new byte[] { 6, 7, 8, 9 }, mBethEntry.read()); 102 103 mPeterEntry = mZFile.get("Peter.html"); 104 assertNotNull(mPeterEntry); 105 mPeterOffset = mPeterEntry.getCentralDirectoryHeader().getOffset(); 106 assertArrayEquals(new byte[] { 10 }, mPeterEntry.read()); 107 } 108 109 @Test 110 public void noSort() throws Exception { 111 readEntries(); 112 113 assertEquals(-1, mMaryOffset); 114 assertEquals(-1, mAndrewOffset); 115 assertEquals(-1, mBethOffset); 116 assertEquals(-1, mPeterOffset); 117 118 mZFile.update(); 119 120 readEntries(); 121 122 assertTrue(mMaryOffset >= 0); 123 assertTrue(mMaryOffset < mAndrewOffset); 124 assertTrue(mAndrewOffset < mBethOffset); 125 assertTrue(mBethOffset < mPeterOffset); 126 } 127 128 @Test 129 public void sortFilesBeforeUpdate() throws Exception { 130 readEntries(); 131 mZFile.sortZipContents(); 132 133 mZFile.update(); 134 135 readEntries(); 136 137 assertTrue(mAndrewOffset >= 0); 138 assertTrue(mBethOffset > mAndrewOffset); 139 assertTrue(mMaryOffset > mBethOffset); 140 assertTrue(mPeterOffset > mMaryOffset); 141 } 142 143 @Test 144 public void autoSort() throws Exception { 145 ZFileOptions options = new ZFileOptions(); 146 options.setAutoSortFiles(true); 147 setupZFile(options); 148 149 readEntries(); 150 151 mZFile.update(); 152 153 readEntries(); 154 155 assertTrue(mAndrewOffset >= 0); 156 assertTrue(mBethOffset > mAndrewOffset); 157 assertTrue(mMaryOffset > mBethOffset); 158 assertTrue(mPeterOffset > mMaryOffset); 159 } 160 161 @Test 162 public void sortFilesAfterUpdate() throws Exception { 163 readEntries(); 164 165 mZFile.update(); 166 167 mZFile.sortZipContents(); 168 169 readEntries(); 170 171 assertEquals(-1, mMaryOffset); 172 assertEquals(-1, mAndrewOffset); 173 assertEquals(-1, mBethOffset); 174 assertEquals(-1, mPeterOffset); 175 176 mZFile.update(); 177 178 readEntries(); 179 180 assertTrue(mAndrewOffset >= 0); 181 assertTrue(mBethOffset > mAndrewOffset); 182 assertTrue(mMaryOffset > mBethOffset); 183 assertTrue(mPeterOffset > mMaryOffset); 184 } 185 186 @Test 187 public void sortFilesWithAlignment() throws Exception { 188 mZFile.close(); 189 190 ZFileOptions options = new ZFileOptions(); 191 options.setAlignmentRule(AlignmentRules.constantForSuffix(".xml", 1024)); 192 mZFile = new ZFile(mFile, options); 193 194 mZFile.sortZipContents(); 195 mZFile.update(); 196 197 readEntries(); 198 assertTrue(mAndrewOffset >= 0); 199 assertTrue(mBethOffset > mAndrewOffset); 200 assertTrue(mPeterOffset > mBethOffset); 201 assertTrue(mMaryOffset > mPeterOffset); 202 } 203 204 @Test 205 public void sortFilesOnClosedFile() throws Exception { 206 mZFile.close(); 207 mZFile = new ZFile(mFile); 208 mZFile.sortZipContents(); 209 mZFile.update(); 210 211 readEntries(); 212 213 assertTrue(mAndrewOffset >= 0); 214 assertTrue(mBethOffset > mAndrewOffset); 215 assertTrue(mMaryOffset > mBethOffset); 216 assertTrue(mPeterOffset > mMaryOffset); 217 } 218 } 219