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 
29 namespace 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 
45 class BackupDataTest : public testing::Test {
46 protected:
47     char* m_external_storage;
48     String8 mFilename;
49     String8 mKey1;
50     String8 mKey2;
51     String8 mKey3;
52     String8 mKey4;
53 
SetUp()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 
TearDown()70     virtual void TearDown() {
71     }
72 };
73 
TEST_F(BackupDataTest,WriteAndReadSingle)74 TEST_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 
TEST_F(BackupDataTest,WriteAndReadMultiple)116 TEST_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 
TEST_F(BackupDataTest,SkipEntity)164 TEST_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 
TEST_F(BackupDataTest,DeleteEntity)219 TEST_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 
TEST_F(BackupDataTest,EneityAfterDelete)258 TEST_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 
TEST_F(BackupDataTest,OnlyDeleteEntities)319 TEST_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 
TEST_F(BackupDataTest,ReadDeletedEntityData)387 TEST_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