Home | History | Annotate | Download | only in zip
      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