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