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