1/*
2 * Copyright (C) 2010 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#define LOG_TAG "ObbFile_test"
18#include <androidfw/BackupHelpers.h>
19#include <utils/Log.h>
20#include <utils/String8.h>
21
22#include <gtest/gtest.h>
23
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <fcntl.h>
27#include <string.h>
28
29namespace android {
30
31#define TEST_FILENAME "/test.bd"
32
33// keys of different lengths to test padding
34#define KEY1 "key1"
35#define KEY2 "key2a"
36#define KEY3 "key3bc"
37#define KEY4 "key4def"
38
39// payloads of different lengths to test padding
40#define DATA1 "abcdefg"
41#define DATA2 "hijklmnopq"
42#define DATA3 "rstuvwxyz"
43// KEY4 is only ever deleted
44
45class BackupDataTest : public testing::Test {
46protected:
47    char* m_external_storage;
48    String8 mFilename;
49    String8 mKey1;
50    String8 mKey2;
51    String8 mKey3;
52    String8 mKey4;
53
54    virtual void SetUp() {
55        m_external_storage = getenv("EXTERNAL_STORAGE");
56        mFilename.append(m_external_storage);
57        mFilename.append(TEST_FILENAME);
58
59        ::unlink(mFilename.string());
60        int fd = ::open(mFilename.string(), O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
61        if (fd < 0) {
62            FAIL() << "Couldn't create " << mFilename.string() << " for writing";
63        }
64        mKey1 = String8(KEY1);
65        mKey2 = String8(KEY2);
66        mKey3 = String8(KEY3);
67        mKey4 = String8(KEY4);
68   }
69
70    virtual void TearDown() {
71    }
72};
73
74TEST_F(BackupDataTest, WriteAndReadSingle) {
75  int fd = ::open(mFilename.string(), O_WRONLY);
76  BackupDataWriter* writer = new BackupDataWriter(fd);
77
78  EXPECT_EQ(NO_ERROR, writer->WriteEntityHeader(mKey1, sizeof(DATA1)))
79          << "WriteEntityHeader returned an error";
80  EXPECT_EQ(NO_ERROR, writer->WriteEntityData(DATA1, sizeof(DATA1)))
81          << "WriteEntityData returned an error";
82
83  ::close(fd);
84  fd = ::open(mFilename.string(), O_RDONLY);
85  BackupDataReader* reader = new BackupDataReader(fd);
86  EXPECT_EQ(NO_ERROR, reader->Status())
87          << "Reader ctor failed";
88
89  bool done;
90  int type;
91  reader->ReadNextHeader(&done, &type);
92  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
93          << "wrong type from ReadNextHeader";
94
95  String8 key;
96  size_t dataSize;
97  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
98          << "ReadEntityHeader returned an error";
99  EXPECT_EQ(mKey1, key)
100          << "wrong key from ReadEntityHeader";
101  EXPECT_EQ(sizeof(DATA1), dataSize)
102          << "wrong size from ReadEntityHeader";
103
104  char* dataBytes = new char[dataSize];
105  EXPECT_EQ((int) dataSize, reader->ReadEntityData(dataBytes, dataSize))
106          << "ReadEntityData returned an error";
107  for (unsigned int i = 0; i < sizeof(DATA1); i++) {
108    EXPECT_EQ(DATA1[i], dataBytes[i])
109             << "data character " << i << " should be equal";
110  }
111  delete[] dataBytes;
112  delete writer;
113  delete reader;
114}
115
116TEST_F(BackupDataTest, WriteAndReadMultiple) {
117  int fd = ::open(mFilename.string(), O_WRONLY);
118  BackupDataWriter* writer = new BackupDataWriter(fd);
119  writer->WriteEntityHeader(mKey1, sizeof(DATA1));
120  writer->WriteEntityData(DATA1, sizeof(DATA1));
121  writer->WriteEntityHeader(mKey2, sizeof(DATA2));
122  writer->WriteEntityData(DATA2, sizeof(DATA2));
123
124  ::close(fd);
125  fd = ::open(mFilename.string(), O_RDONLY);
126  BackupDataReader* reader = new BackupDataReader(fd);
127
128  bool done;
129  int type;
130  String8 key;
131  size_t dataSize;
132  char* dataBytes;
133  // read first entity
134  reader->ReadNextHeader(&done, &type);
135  reader->ReadEntityHeader(&key, &dataSize);
136  dataBytes = new char[dataSize];
137  reader->ReadEntityData(dataBytes, dataSize);
138  delete dataBytes;
139
140  // read and verify second entity
141  reader->ReadNextHeader(&done, &type);
142  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
143          << "wrong type from ReadNextHeader";
144
145  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
146          << "ReadEntityHeader returned an error on second entity";
147  EXPECT_EQ(mKey2, key)
148          << "wrong key from ReadEntityHeader on second entity";
149  EXPECT_EQ(sizeof(DATA2), dataSize)
150          << "wrong size from ReadEntityHeader on second entity";
151
152  dataBytes = new char[dataSize];
153  EXPECT_EQ((int)dataSize, reader->ReadEntityData(dataBytes, dataSize))
154          << "ReadEntityData returned an error on second entity";
155  for (unsigned int i = 0; i < sizeof(DATA2); i++) {
156    EXPECT_EQ(DATA2[i], dataBytes[i])
157             << "data character " << i << " should be equal";
158  }
159  delete dataBytes;
160  delete writer;
161  delete reader;
162}
163
164TEST_F(BackupDataTest, SkipEntity) {
165  int fd = ::open(mFilename.string(), O_WRONLY);
166  BackupDataWriter* writer = new BackupDataWriter(fd);
167  writer->WriteEntityHeader(mKey1, sizeof(DATA1));
168  writer->WriteEntityData(DATA1, sizeof(DATA1));
169  writer->WriteEntityHeader(mKey2, sizeof(DATA2));
170  writer->WriteEntityData(DATA2, sizeof(DATA2));
171  writer->WriteEntityHeader(mKey3, sizeof(DATA3));
172  writer->WriteEntityData(DATA3, sizeof(DATA3));
173
174  ::close(fd);
175  fd = ::open(mFilename.string(), O_RDONLY);
176  BackupDataReader* reader = new BackupDataReader(fd);
177
178  bool done;
179  int type;
180  String8 key;
181  size_t dataSize;
182  char* dataBytes;
183  // read first entity
184  reader->ReadNextHeader(&done, &type);
185  reader->ReadEntityHeader(&key, &dataSize);
186  dataBytes = new char[dataSize];
187  reader->ReadEntityData(dataBytes, dataSize);
188  delete dataBytes;
189
190  // skip second entity
191  reader->ReadNextHeader(&done, &type);
192  reader->ReadEntityHeader(&key, &dataSize);
193  reader->SkipEntityData();
194
195  // read and verify third entity
196  reader->ReadNextHeader(&done, &type);
197  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
198          << "wrong type from ReadNextHeader after skip";
199
200  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
201          << "ReadEntityHeader returned an error on third entity";
202  EXPECT_EQ(mKey3, key)
203          << "wrong key from ReadEntityHeader on third entity";
204  EXPECT_EQ(sizeof(DATA3), dataSize)
205          << "wrong size from ReadEntityHeader on third entity";
206
207  dataBytes = new char[dataSize];
208  EXPECT_EQ((int) dataSize, reader->ReadEntityData(dataBytes, dataSize))
209          << "ReadEntityData returned an error on third entity";
210  for (unsigned int i = 0; i < sizeof(DATA3); i++) {
211    EXPECT_EQ(DATA3[i], dataBytes[i])
212             << "data character " << i << " should be equal";
213  }
214  delete dataBytes;
215  delete writer;
216  delete reader;
217}
218
219TEST_F(BackupDataTest, DeleteEntity) {
220  int fd = ::open(mFilename.string(), O_WRONLY);
221  BackupDataWriter* writer = new BackupDataWriter(fd);
222  writer->WriteEntityHeader(mKey1, sizeof(DATA1));
223  writer->WriteEntityData(DATA1, sizeof(DATA1));
224  writer->WriteEntityHeader(mKey2, -1);
225
226  ::close(fd);
227  fd = ::open(mFilename.string(), O_RDONLY);
228  BackupDataReader* reader = new BackupDataReader(fd);
229
230  bool done;
231  int type;
232  String8 key;
233  size_t dataSize;
234  char* dataBytes;
235  // read first entity
236  reader->ReadNextHeader(&done, &type);
237  reader->ReadEntityHeader(&key, &dataSize);
238  dataBytes = new char[dataSize];
239  reader->ReadEntityData(dataBytes, dataSize);
240  delete dataBytes;
241
242  // read and verify deletion
243  reader->ReadNextHeader(&done, &type);
244  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
245          << "wrong type from ReadNextHeader on deletion";
246
247  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
248          << "ReadEntityHeader returned an error on second entity";
249  EXPECT_EQ(mKey2, key)
250          << "wrong key from ReadEntityHeader on second entity";
251  EXPECT_EQ(-1, (int) dataSize)
252          << "not recognizing deletion on second entity";
253
254  delete writer;
255  delete reader;
256}
257
258TEST_F(BackupDataTest, EneityAfterDelete) {
259  int fd = ::open(mFilename.string(), O_WRONLY);
260  BackupDataWriter* writer = new BackupDataWriter(fd);
261  writer->WriteEntityHeader(mKey1, sizeof(DATA1));
262  writer->WriteEntityData(DATA1, sizeof(DATA1));
263  writer->WriteEntityHeader(mKey2, -1);
264  writer->WriteEntityHeader(mKey3, sizeof(DATA3));
265  writer->WriteEntityData(DATA3, sizeof(DATA3));
266
267  ::close(fd);
268  fd = ::open(mFilename.string(), O_RDONLY);
269  BackupDataReader* reader = new BackupDataReader(fd);
270
271  bool done;
272  int type;
273  String8 key;
274  size_t dataSize;
275  char* dataBytes;
276  // read first entity
277  reader->ReadNextHeader(&done, &type);
278  reader->ReadEntityHeader(&key, &dataSize);
279  dataBytes = new char[dataSize];
280  reader->ReadEntityData(dataBytes, dataSize);
281  delete dataBytes;
282
283  // read and verify deletion
284  reader->ReadNextHeader(&done, &type);
285  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
286          << "wrong type from ReadNextHeader on deletion";
287
288  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
289          << "ReadEntityHeader returned an error on second entity";
290  EXPECT_EQ(mKey2, key)
291          << "wrong key from ReadEntityHeader on second entity";
292  EXPECT_EQ(-1, (int)dataSize)
293          << "not recognizing deletion on second entity";
294
295  // read and verify third entity
296  reader->ReadNextHeader(&done, &type);
297  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
298          << "wrong type from ReadNextHeader after deletion";
299
300  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
301          << "ReadEntityHeader returned an error on third entity";
302  EXPECT_EQ(mKey3, key)
303          << "wrong key from ReadEntityHeader on third entity";
304  EXPECT_EQ(sizeof(DATA3), dataSize)
305          << "wrong size from ReadEntityHeader on third entity";
306
307  dataBytes = new char[dataSize];
308  EXPECT_EQ((int) dataSize, reader->ReadEntityData(dataBytes, dataSize))
309          << "ReadEntityData returned an error on third entity";
310  for (unsigned int i = 0; i < sizeof(DATA3); i++) {
311    EXPECT_EQ(DATA3[i], dataBytes[i])
312             << "data character " << i << " should be equal";
313  }
314  delete dataBytes;
315  delete writer;
316  delete reader;
317}
318
319TEST_F(BackupDataTest, OnlyDeleteEntities) {
320  int fd = ::open(mFilename.string(), O_WRONLY);
321  BackupDataWriter* writer = new BackupDataWriter(fd);
322  writer->WriteEntityHeader(mKey1, -1);
323  writer->WriteEntityHeader(mKey2, -1);
324  writer->WriteEntityHeader(mKey3, -1);
325  writer->WriteEntityHeader(mKey4, -1);
326
327  ::close(fd);
328  fd = ::open(mFilename.string(), O_RDONLY);
329  BackupDataReader* reader = new BackupDataReader(fd);
330
331  bool done;
332  int type;
333  String8 key;
334  size_t dataSize;
335  // read and verify first deletion
336  reader->ReadNextHeader(&done, &type);
337  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
338          << "wrong type from ReadNextHeader first deletion";
339
340  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
341          << "ReadEntityHeader returned an error on first entity";
342  EXPECT_EQ(mKey1, key)
343          << "wrong key from ReadEntityHeader on first entity";
344  EXPECT_EQ(-1, (int) dataSize)
345          << "not recognizing deletion on first entity";
346
347  // read and verify second deletion
348  reader->ReadNextHeader(&done, &type);
349  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
350          << "wrong type from ReadNextHeader second deletion";
351
352  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
353          << "ReadEntityHeader returned an error on second entity";
354  EXPECT_EQ(mKey2, key)
355          << "wrong key from ReadEntityHeader on second entity";
356  EXPECT_EQ(-1, (int) dataSize)
357          << "not recognizing deletion on second entity";
358
359  // read and verify third deletion
360  reader->ReadNextHeader(&done, &type);
361  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
362          << "wrong type from ReadNextHeader third deletion";
363
364  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
365          << "ReadEntityHeader returned an error on third entity";
366  EXPECT_EQ(mKey3, key)
367          << "wrong key from ReadEntityHeader on third entity";
368  EXPECT_EQ(-1, (int) dataSize)
369          << "not recognizing deletion on third entity";
370
371  // read and verify fourth deletion
372  reader->ReadNextHeader(&done, &type);
373  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
374          << "wrong type from ReadNextHeader fourth deletion";
375
376  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
377          << "ReadEntityHeader returned an error on fourth entity";
378  EXPECT_EQ(mKey4, key)
379          << "wrong key from ReadEntityHeader on fourth entity";
380  EXPECT_EQ(-1, (int) dataSize)
381          << "not recognizing deletion on fourth entity";
382
383  delete writer;
384  delete reader;
385}
386
387TEST_F(BackupDataTest, ReadDeletedEntityData) {
388  int fd = ::open(mFilename.string(), O_WRONLY);
389  BackupDataWriter* writer = new BackupDataWriter(fd);
390  writer->WriteEntityHeader(mKey1, -1);
391  writer->WriteEntityHeader(mKey2, -1);
392
393  ::close(fd);
394  fd = ::open(mFilename.string(), O_RDONLY);
395  BackupDataReader* reader = new BackupDataReader(fd);
396
397  bool done;
398  int type;
399  String8 key;
400  size_t dataSize;
401  // read and verify first deletion
402  reader->ReadNextHeader(&done, &type);
403  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
404          << "wrong type from ReadNextHeader first deletion";
405
406  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
407          << "ReadEntityHeader returned an error on first entity";
408  EXPECT_EQ(mKey1, key)
409          << "wrong key from ReadEntityHeader on first entity";
410  EXPECT_EQ(-1, (int) dataSize)
411          << "not recognizing deletion on first entity";
412
413  // erroneously try to read first entity data
414  char* dataBytes = new char[10];
415  dataBytes[0] = 'A';
416  EXPECT_EQ(NO_ERROR, reader->ReadEntityData(dataBytes, dataSize));
417  // expect dataBytes to be unmodofied
418  EXPECT_EQ('A', dataBytes[0]);
419
420  // read and verify second deletion
421  reader->ReadNextHeader(&done, &type);
422  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
423          << "wrong type from ReadNextHeader second deletion";
424
425  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
426          << "ReadEntityHeader returned an error on second entity";
427  EXPECT_EQ(mKey2, key)
428          << "wrong key from ReadEntityHeader on second entity";
429  EXPECT_EQ(-1, (int) dataSize)
430          << "not recognizing deletion on second entity";
431
432  delete[] dataBytes;
433  delete writer;
434  delete reader;
435}
436
437}
438