1fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren/* 2fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren * Copyright (C) 2013 The Android Open Source Project 3fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren * 4fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren * Licensed under the Apache License, Version 2.0 (the "License"); 5fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren * you may not use this file except in compliance with the License. 6fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren * You may obtain a copy of the License at 7fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren * 8fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren * http://www.apache.org/licenses/LICENSE-2.0 9fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren * 10fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren * Unless required by applicable law or agreed to in writing, software 11fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren * distributed under the License is distributed on an "AS IS" BASIS, 12fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren * See the License for the specific language governing permissions and 14fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren * limitations under the License. 15fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren */ 16fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 17fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenpackage android.app.backup; 18fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 19fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport android.app.backup.BackupDataInput; 20fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport android.app.backup.BackupDataOutput; 21fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport android.content.res.AssetFileDescriptor; 22fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport android.content.res.AssetManager; 23fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport android.os.Bundle; 24fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport android.os.Environment; 25fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport android.os.ParcelFileDescriptor; 26fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport android.test.AndroidTestCase; 27fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport android.test.InstrumentationTestCase; 28fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport android.util.Base64; 29fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport android.util.Log; 30fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport org.json.JSONObject; 31fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 32fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport java.io.BufferedReader; 33fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport java.io.File; 34fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport java.io.FileInputStream; 35fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport java.io.FileNotFoundException; 36fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport java.io.FileOutputStream; 37fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport java.io.FileReader; 38fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport java.io.IOException; 39fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport java.io.InputStream; 40fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport java.io.InputStreamReader; 41fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport java.lang.Exception; 42fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenimport java.nio.ByteBuffer; 43fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 44fd5f566db84722f9cf54085d8a378e9398ef260dChris Wrenpublic class BackupDataTest extends AndroidTestCase { 45fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private static final String KEY1 = "key1"; 46fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private static final String KEY2 = "key2a"; 47fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private static final String KEY3 = "key3bc"; 48fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private static final String KEY4 = "key4dad"; // variable key lengths to test padding 49fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private static final String[] KEYS = {KEY1, KEY2, KEY3, KEY4}; 50fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 51fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private static final String DATA1 = "abcdef"; 52fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private static final String DATA2 = "abcdefg"; 53fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private static final String DATA3 = "abcdefgh"; 54fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private static final String DATA4 = "abcdeffhi"; //variable data lengths to test padding 55fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private static final String[] DATA = {DATA1, DATA2, DATA3, DATA4}; 56fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private static final String TAG = "BackupDataTest"; 57fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 58fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private File mFile; 59fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private ParcelFileDescriptor mDataFile; 60fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private File mDirectory; 61fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private Bundle mStatusBundle; 62fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private AssetManager mAssets; 63fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 64fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren @Override 65fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren protected void setUp() throws Exception { 66fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren super.setUp(); 67fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren mDirectory = new File(Environment.getExternalStorageDirectory(), "test_data"); 68fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren mDirectory.mkdirs(); 69fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren mAssets = mContext.getAssets(); 70fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 71fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 72fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren @Override 73fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren protected void tearDown() throws Exception { 74fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren super.tearDown(); 75fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren if (mDataFile != null) { 76fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren mDataFile.close(); 77fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 78fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 79fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 80fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren public void testSingle() throws IOException { 81fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren mFile = new File(mDirectory, "backup_mixed_sinlge.dat"); 82fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren openForWriting(); 83fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren BackupDataOutput bdo = new BackupDataOutput(mDataFile.getFileDescriptor()); 84fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 85fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren writeEntity(bdo, KEY1, DATA1.getBytes()); 86fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 87fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren mDataFile.close(); 88fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren openForReading(); 89fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 90fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren BackupDataInput bdi = new BackupDataInput(mDataFile.getFileDescriptor()); 91fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren int count = 0; 92fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren while (bdi.readNextHeader()) { 93fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren readAndVerifyEntity(bdi, KEY1, DATA1.getBytes()); 94fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren count++; 95fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 96fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertEquals("only one entity in this stream", 1, count); 97fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 98fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 99fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren public void testMultiple() throws IOException { 100fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren mFile = new File(mDirectory, "backup_multiple_test.dat"); 101fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren openForWriting(); 102fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren BackupDataOutput bdo = new BackupDataOutput(mDataFile.getFileDescriptor()); 103fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 104fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren for(int i = 0; i < KEYS.length; i++) { 105fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren writeEntity(bdo, KEYS[i], DATA[i].getBytes()); 106fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 107fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 108fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren mDataFile.close(); 109fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren openForReading(); 110fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 111fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren BackupDataInput bdi = new BackupDataInput(mDataFile.getFileDescriptor()); 112fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren int count = 0; 113fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren while (bdi.readNextHeader()) { 114fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren readAndVerifyEntity(bdi, KEYS[count], DATA[count].getBytes()); 115fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren count++; 116fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 117fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertEquals("four entities in this stream", KEYS.length, count); 118fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 119fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 120fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren public void testDelete() throws IOException { 121fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren mFile = new File(mDirectory, "backup_delete_test.dat"); 122fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren openForWriting(); 123fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren BackupDataOutput bdo = new BackupDataOutput(mDataFile.getFileDescriptor()); 124fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 125fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren for(int i = 0; i < KEYS.length; i++) { 126fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren deleteEntity(bdo, KEYS[i]); 127fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 128fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 129fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren mDataFile.close(); 130fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren openForReading(); 131fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 132fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren BackupDataInput bdi = new BackupDataInput(mDataFile.getFileDescriptor()); 133fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren int count = 0; 134fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren while (bdi.readNextHeader()) { 135fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren readAndVerifyDeletedEntity(bdi, KEYS[count]); 136fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren count++; 137fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 138fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertEquals("four deletes in this stream", KEYS.length, count); 139fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 140fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 141fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren public void testMixed() throws IOException { 142fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren mFile = new File(mDirectory, "backup_mixed_test.dat"); 143fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren openForWriting(); 144fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 145fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren BackupDataOutput bdo = new BackupDataOutput(mDataFile.getFileDescriptor()); 146fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 147fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren int i = 0; 148fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren deleteEntity(bdo, KEYS[i]); i++; 149fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren writeEntity(bdo, KEYS[i], DATA[i].getBytes()); i++; 150fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren writeEntity(bdo, KEYS[i], DATA[i].getBytes()); i++; 151fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren deleteEntity(bdo, KEYS[i]); i++; 152fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 153fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren mDataFile.close(); 154fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren openForReading(); 155fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 156fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren BackupDataInput bdi = new BackupDataInput(mDataFile.getFileDescriptor()); 157fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren int out = 0; 158fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertTrue(bdi.readNextHeader()); 159fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren readAndVerifyDeletedEntity(bdi, KEYS[out]); out++; 160fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertTrue(bdi.readNextHeader()); 161fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren readAndVerifyEntity(bdi, KEYS[out], DATA[out].getBytes()); out++; 162fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertTrue(bdi.readNextHeader()); 163fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren readAndVerifyEntity(bdi, KEYS[out], DATA[out].getBytes()); out++; 164fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertTrue(bdi.readNextHeader()); 165fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren readAndVerifyDeletedEntity(bdi, KEYS[out]); out++; 166fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertFalse("four items in this stream", 167fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren bdi.readNextHeader()); 168fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 169fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 170fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren public void testReadMockData() throws IOException { 171fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren copyAssetToFile("backup_mock.dat", "backup_read_mock_test.dat"); 172fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 173fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren openForReading(); 174fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren BackupDataInput bdi = new BackupDataInput(mDataFile.getFileDescriptor()); 175fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren BufferedReader truth = new BufferedReader(new InputStreamReader( 176fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren mAssets.openFd("backup_mock.gld").createInputStream())); 177fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren while( bdi.readNextHeader()) { 178fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren String[] expected = truth.readLine().split(":"); 179fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren byte[] expectedBytes = null; 180fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren if (expected.length > 1) { 181fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren expectedBytes = Base64.decode(expected[1], Base64.DEFAULT); 182fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 183fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren String key = bdi.getKey(); 184fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren int dataSize = bdi.getDataSize(); 185fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 186fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertEquals("wrong key", expected[0], key); 187fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertEquals("wrong length for key " + key, 188fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren (expectedBytes == null ? -1: expectedBytes.length), dataSize); 189fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren if (dataSize != -1) { 190fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren byte[] buffer = new byte[dataSize]; 191fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren bdi.readEntityData(buffer, 0, dataSize); 192fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertEquals("wrong data for key " + key, expected[1], 193fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP)); 194fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 195fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 196fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertNull("there are unused entries in the golden file", truth.readLine()); 197fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 198fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 199fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren public void testReadRealData() throws IOException { 200fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren copyAssetToFile("backup_real.dat", "backup_read_real_test.dat"); 201fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 202fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren openForReading(); 203fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren BackupDataInput bdi = new BackupDataInput(mDataFile.getFileDescriptor()); 204fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren BufferedReader truth = new BufferedReader(new InputStreamReader( 205fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren mAssets.openFd("backup_real.gld").createInputStream())); 206fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 207fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren while(bdi.readNextHeader()) { 208fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren String[] expected = truth.readLine().split(":"); 209fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren byte[] expectedBytes = null; 210fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren if (expected.length > 1) { 211fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren expectedBytes = Base64.decode(expected[1], Base64.DEFAULT); 212fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 213fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren String key = bdi.getKey(); 214fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren int dataSize = bdi.getDataSize(); 215fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 216fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertEquals("wrong key", expected[0], key); 217fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertEquals("wrong length for key " + key, 218fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren (expectedBytes == null ? -1: expectedBytes.length), dataSize); 219fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren if (dataSize != -1) { 220fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren byte[] buffer = new byte[dataSize]; 221fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren bdi.readEntityData(buffer, 0, dataSize); 222fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertEquals("wrong data for key " + key, expected[1], 223fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP)); 224fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 225fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 226fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertNull("there are unused entries in the golden file", truth.readLine()); 227fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 228fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 229fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private void copyAssetToFile(String source, String destination) throws IOException { 230fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren mFile = new File(mDirectory, destination); 231fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren openForWriting(); 232fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren FileInputStream fileInputStream = mAssets.openFd(source).createInputStream(); 233fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren FileOutputStream fileOutputStream = new FileOutputStream(mDataFile.getFileDescriptor()); 234fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren byte[] copybuffer = new byte[1024]; 235fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren int numBytes = fileInputStream.read(copybuffer); 236fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren fileOutputStream.write(copybuffer, 0, numBytes); 237fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren fileOutputStream.close(); 238fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 239fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 240fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private void openForWriting() throws FileNotFoundException { 241fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren mDataFile = ParcelFileDescriptor.open(mFile, 242fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren ParcelFileDescriptor.MODE_WRITE_ONLY | 243fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren ParcelFileDescriptor.MODE_CREATE | 244fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren ParcelFileDescriptor.MODE_TRUNCATE); // Make an empty file if necessary 245fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 246fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 247fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private void openForReading() throws FileNotFoundException { 248fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren mDataFile = ParcelFileDescriptor.open(mFile, 249fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren ParcelFileDescriptor.MODE_READ_ONLY | 250fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren ParcelFileDescriptor.MODE_CREATE); // Make an empty file if necessary 251fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 252fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 253fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private void writeEntity(BackupDataOutput bdo, String key, byte[] data) throws IOException { 254fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren int status = bdo.writeEntityHeader(key, data.length); 255fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren // documentation says "number of bytes written" but that's not what we get: 256fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertEquals(0, status); 257fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 258fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren status = bdo.writeEntityData(data, data.length); 259fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren // documentation says "number of bytes written" but that's not what we get: 260fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertEquals(0, status); 261fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 262fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 263fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private void deleteEntity(BackupDataOutput bdo, String key) throws IOException { 264fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren int status = bdo.writeEntityHeader(key, -1); 265fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren // documentation says "number of bytes written" but that's not what we get: 266fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertEquals(0, status); 267fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 268fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren 269fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private void readAndVerifyEntity(BackupDataInput bdi, String expectedKey, byte[] expectedData) 270fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren throws IOException { 271fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertEquals("Key mismatch", 272fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren expectedKey, bdi.getKey()); 273fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertEquals("data size mismatch", 274fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren expectedData.length, bdi.getDataSize()); 275fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren byte[] data = new byte[bdi.getDataSize()]; 276fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren bdi.readEntityData(data, 0, bdi.getDataSize()); 277fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertEquals("payload size is wrong", 278fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren expectedData.length, data.length); 279fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren for (int i = 0; i < data.length; i++) { 280fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertEquals("payload mismatch", 281fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren expectedData[i], data[i]); 282fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 283fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 284fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren private void readAndVerifyDeletedEntity(BackupDataInput bdi, String expectedKey) 285fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren throws IOException { 286fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertEquals("Key mismatch", 287fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren expectedKey, bdi.getKey()); 288fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren assertEquals("deletion mis-reported", 289fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren -1, bdi.getDataSize()); 290fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren } 291fd5f566db84722f9cf54085d8a378e9398ef260dChris Wren} 292