Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2017 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.apksig.util;
     18 
     19 import static org.junit.Assert.assertEquals;
     20 
     21 import java.io.Closeable;
     22 import java.io.File;
     23 import java.io.IOException;
     24 import java.io.RandomAccessFile;
     25 import java.nio.charset.StandardCharsets;
     26 import java.nio.file.Files;
     27 import org.junit.Test;
     28 import org.junit.runner.RunWith;
     29 import org.junit.runners.JUnit4;
     30 
     31 /**
     32  * Tests for the {@link DataSource} returned by
     33  * {@link DataSources#asDataSource(java.io.RandomAccessFile)}.
     34  */
     35 @RunWith(JUnit4.class)
     36 public class DataSourceFromRAFTest extends DataSourceTestBase {
     37 
     38     @Test
     39     public void testFileSizeChangesVisible() throws Exception {
     40         try (CloseableWithDataSource c = createDataSource("abcdefg")) {
     41             DataSource ds = c.getDataSource();
     42             DataSource slice = ds.slice(3, 2);
     43             File f = ((TmpFileCloseable) c.getCloseable()).getFile();
     44             assertGetByteBufferEquals("abcdefg", ds, 0, (int) ds.size());
     45             assertGetByteBufferEquals("de", slice, 0, (int) slice.size());
     46             assertFeedEquals("cdefg", ds, 2, 5);
     47             assertFeedEquals("e", slice, 1, 1);
     48             assertCopyToEquals("cdefg", ds, 2, 5);
     49             assertCopyToEquals("e", slice, 1, 1);
     50             assertSliceEquals("cdefg", ds, 2, 5);
     51             assertSliceEquals("e", slice, 1, 1);
     52             try (RandomAccessFile raf = new RandomAccessFile(f, "rw")) {
     53                 raf.seek(7);
     54                 raf.write("hijkl".getBytes(StandardCharsets.UTF_8));
     55             }
     56 
     57             assertEquals(12, ds.size());
     58             assertGetByteBufferEquals("abcdefghijkl", ds, 0, (int) ds.size());
     59             assertGetByteBufferEquals("de", slice, 0, (int) slice.size());
     60             assertFeedEquals("cdefg", ds, 2, 5);
     61             assertFeedEquals("fgh", ds, 5, 3);
     62             assertCopyToEquals("fgh", ds, 5, 3);
     63             assertSliceEquals("fgh", ds, 5, 3);
     64         }
     65     }
     66 
     67     @Override
     68     protected CloseableWithDataSource createDataSource(byte[] contents) throws IOException {
     69         File tmp = File.createTempFile(DataSourceFromRAFTest.class.getSimpleName(), ".bin");
     70         RandomAccessFile f = null;
     71         try {
     72             Files.write(tmp.toPath(), contents);
     73             f = new RandomAccessFile(tmp, "r");
     74         } finally {
     75             if (f == null) {
     76                 tmp.delete();
     77             }
     78         }
     79 
     80         return CloseableWithDataSource.of(
     81                 DataSources.asDataSource(f),
     82                 new TmpFileCloseable(tmp, f));
     83     }
     84 
     85     /**
     86      * {@link Closeable} which closes the delegate {@code Closeable} and deletes the provided file.
     87      */
     88     static class TmpFileCloseable implements Closeable {
     89         private final File mFile;
     90         private final Closeable mDelegate;
     91 
     92         TmpFileCloseable(File file, Closeable closeable) {
     93             mFile = file;
     94             mDelegate = closeable;
     95         }
     96 
     97         File getFile() {
     98             return mFile;
     99         }
    100 
    101         @Override
    102         public void close() throws IOException {
    103             try {
    104                 if (mDelegate != null) {
    105                     mDelegate.close();
    106                 }
    107             } finally {
    108                 if (mFile != null) {
    109                     mFile.delete();
    110                 }
    111             }
    112         }
    113     }
    114 }
    115