diff options
Diffstat (limited to 'libs/androidfw/tests/BackupData_test.cpp')
-rw-r--r-- | libs/androidfw/tests/BackupData_test.cpp | 438 |
1 files changed, 438 insertions, 0 deletions
diff --git a/libs/androidfw/tests/BackupData_test.cpp b/libs/androidfw/tests/BackupData_test.cpp new file mode 100644 index 0000000..17f91ca --- /dev/null +++ b/libs/androidfw/tests/BackupData_test.cpp @@ -0,0 +1,438 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "ObbFile_test" +#include <androidfw/BackupHelpers.h> +#include <utils/Log.h> +#include <utils/String8.h> + +#include <gtest/gtest.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> + +namespace android { + +#define TEST_FILENAME "/test.bd" + +// keys of different lengths to test padding +#define KEY1 "key1" +#define KEY2 "key2a" +#define KEY3 "key3bc" +#define KEY4 "key4def" + +// payloads of different lengths to test padding +#define DATA1 "abcdefg" +#define DATA2 "hijklmnopq" +#define DATA3 "rstuvwxyz" +// KEY4 is only ever deleted + +class BackupDataTest : public testing::Test { +protected: + char* m_external_storage; + char* m_filename; + String8 mKey1; + String8 mKey2; + String8 mKey3; + String8 mKey4; + + virtual void SetUp() { + m_external_storage = getenv("EXTERNAL_STORAGE"); + + const int totalLen = strlen(m_external_storage) + strlen(TEST_FILENAME) + 1; + m_filename = new char[totalLen]; + snprintf(m_filename, totalLen, "%s%s", m_external_storage, TEST_FILENAME); + + ::unlink(m_filename); + int fd = ::open(m_filename, O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + if (fd < 0) { + FAIL() << "Couldn't create " << m_filename << " for writing"; + } + mKey1 = String8(KEY1); + mKey2 = String8(KEY2); + mKey3 = String8(KEY3); + mKey4 = String8(KEY4); + } + + virtual void TearDown() { + } +}; + +TEST_F(BackupDataTest, WriteAndReadSingle) { + int fd = ::open(m_filename, O_WRONLY); + BackupDataWriter* writer = new BackupDataWriter(fd); + + EXPECT_EQ(NO_ERROR, writer->WriteEntityHeader(mKey1, sizeof(DATA1))) + << "WriteEntityHeader returned an error"; + EXPECT_EQ(NO_ERROR, writer->WriteEntityData(DATA1, sizeof(DATA1))) + << "WriteEntityData returned an error"; + + ::close(fd); + fd = ::open(m_filename, O_RDONLY); + BackupDataReader* reader = new BackupDataReader(fd); + EXPECT_EQ(NO_ERROR, reader->Status()) + << "Reader ctor failed"; + + bool done; + int type; + reader->ReadNextHeader(&done, &type); + EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type) + << "wrong type from ReadNextHeader"; + + String8 key; + size_t dataSize; + EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize)) + << "ReadEntityHeader returned an error"; + EXPECT_EQ(mKey1, key) + << "wrong key from ReadEntityHeader"; + EXPECT_EQ(sizeof(DATA1), dataSize) + << "wrong size from ReadEntityHeader"; + + char* dataBytes = new char[dataSize]; + EXPECT_EQ((int) dataSize, reader->ReadEntityData(dataBytes, dataSize)) + << "ReadEntityData returned an error"; + for (unsigned int i = 0; i < sizeof(DATA1); i++) { + EXPECT_EQ(DATA1[i], dataBytes[i]) + << "data character " << i << " should be equal"; + } + delete dataBytes; + delete writer; + delete reader; +} + +TEST_F(BackupDataTest, WriteAndReadMultiple) { + int fd = ::open(m_filename, O_WRONLY); + BackupDataWriter* writer = new BackupDataWriter(fd); + writer->WriteEntityHeader(mKey1, sizeof(DATA1)); + writer->WriteEntityData(DATA1, sizeof(DATA1)); + writer->WriteEntityHeader(mKey2, sizeof(DATA2)); + writer->WriteEntityData(DATA2, sizeof(DATA2)); + + ::close(fd); + fd = ::open(m_filename, O_RDONLY); + BackupDataReader* reader = new BackupDataReader(fd); + + bool done; + int type; + String8 key; + size_t dataSize; + char* dataBytes; + // read first entity + reader->ReadNextHeader(&done, &type); + reader->ReadEntityHeader(&key, &dataSize); + dataBytes = new char[dataSize]; + reader->ReadEntityData(dataBytes, dataSize); + delete dataBytes; + + // read and verify second entity + reader->ReadNextHeader(&done, &type); + EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type) + << "wrong type from ReadNextHeader"; + + EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize)) + << "ReadEntityHeader returned an error on second entity"; + EXPECT_EQ(mKey2, key) + << "wrong key from ReadEntityHeader on second entity"; + EXPECT_EQ(sizeof(DATA2), dataSize) + << "wrong size from ReadEntityHeader on second entity"; + + dataBytes = new char[dataSize]; + EXPECT_EQ((int)dataSize, reader->ReadEntityData(dataBytes, dataSize)) + << "ReadEntityData returned an error on second entity"; + for (unsigned int i = 0; i < sizeof(DATA2); i++) { + EXPECT_EQ(DATA2[i], dataBytes[i]) + << "data character " << i << " should be equal"; + } + delete dataBytes; + delete writer; + delete reader; +} + +TEST_F(BackupDataTest, SkipEntity) { + int fd = ::open(m_filename, O_WRONLY); + BackupDataWriter* writer = new BackupDataWriter(fd); + writer->WriteEntityHeader(mKey1, sizeof(DATA1)); + writer->WriteEntityData(DATA1, sizeof(DATA1)); + writer->WriteEntityHeader(mKey2, sizeof(DATA2)); + writer->WriteEntityData(DATA2, sizeof(DATA2)); + writer->WriteEntityHeader(mKey3, sizeof(DATA3)); + writer->WriteEntityData(DATA3, sizeof(DATA3)); + + ::close(fd); + fd = ::open(m_filename, O_RDONLY); + BackupDataReader* reader = new BackupDataReader(fd); + + bool done; + int type; + String8 key; + size_t dataSize; + char* dataBytes; + // read first entity + reader->ReadNextHeader(&done, &type); + reader->ReadEntityHeader(&key, &dataSize); + dataBytes = new char[dataSize]; + reader->ReadEntityData(dataBytes, dataSize); + delete dataBytes; + + // skip second entity + reader->ReadNextHeader(&done, &type); + reader->ReadEntityHeader(&key, &dataSize); + reader->SkipEntityData(); + + // read and verify third entity + reader->ReadNextHeader(&done, &type); + EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type) + << "wrong type from ReadNextHeader after skip"; + + EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize)) + << "ReadEntityHeader returned an error on third entity"; + EXPECT_EQ(mKey3, key) + << "wrong key from ReadEntityHeader on third entity"; + EXPECT_EQ(sizeof(DATA3), dataSize) + << "wrong size from ReadEntityHeader on third entity"; + + dataBytes = new char[dataSize]; + EXPECT_EQ((int) dataSize, reader->ReadEntityData(dataBytes, dataSize)) + << "ReadEntityData returned an error on third entity"; + for (unsigned int i = 0; i < sizeof(DATA3); i++) { + EXPECT_EQ(DATA3[i], dataBytes[i]) + << "data character " << i << " should be equal"; + } + delete dataBytes; + delete writer; + delete reader; +} + +TEST_F(BackupDataTest, DeleteEntity) { + int fd = ::open(m_filename, O_WRONLY); + BackupDataWriter* writer = new BackupDataWriter(fd); + writer->WriteEntityHeader(mKey1, sizeof(DATA1)); + writer->WriteEntityData(DATA1, sizeof(DATA1)); + writer->WriteEntityHeader(mKey2, -1); + + ::close(fd); + fd = ::open(m_filename, O_RDONLY); + BackupDataReader* reader = new BackupDataReader(fd); + + bool done; + int type; + String8 key; + size_t dataSize; + char* dataBytes; + // read first entity + reader->ReadNextHeader(&done, &type); + reader->ReadEntityHeader(&key, &dataSize); + dataBytes = new char[dataSize]; + reader->ReadEntityData(dataBytes, dataSize); + delete dataBytes; + + // read and verify deletion + reader->ReadNextHeader(&done, &type); + EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type) + << "wrong type from ReadNextHeader on deletion"; + + EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize)) + << "ReadEntityHeader returned an error on second entity"; + EXPECT_EQ(mKey2, key) + << "wrong key from ReadEntityHeader on second entity"; + EXPECT_EQ(-1, (int) dataSize) + << "not recognizing deletion on second entity"; + + delete writer; + delete reader; +} + +TEST_F(BackupDataTest, EneityAfterDelete) { + int fd = ::open(m_filename, O_WRONLY); + BackupDataWriter* writer = new BackupDataWriter(fd); + writer->WriteEntityHeader(mKey1, sizeof(DATA1)); + writer->WriteEntityData(DATA1, sizeof(DATA1)); + writer->WriteEntityHeader(mKey2, -1); + writer->WriteEntityHeader(mKey3, sizeof(DATA3)); + writer->WriteEntityData(DATA3, sizeof(DATA3)); + + ::close(fd); + fd = ::open(m_filename, O_RDONLY); + BackupDataReader* reader = new BackupDataReader(fd); + + bool done; + int type; + String8 key; + size_t dataSize; + char* dataBytes; + // read first entity + reader->ReadNextHeader(&done, &type); + reader->ReadEntityHeader(&key, &dataSize); + dataBytes = new char[dataSize]; + reader->ReadEntityData(dataBytes, dataSize); + delete dataBytes; + + // read and verify deletion + reader->ReadNextHeader(&done, &type); + EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type) + << "wrong type from ReadNextHeader on deletion"; + + EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize)) + << "ReadEntityHeader returned an error on second entity"; + EXPECT_EQ(mKey2, key) + << "wrong key from ReadEntityHeader on second entity"; + EXPECT_EQ(-1, (int)dataSize) + << "not recognizing deletion on second entity"; + + // read and verify third entity + reader->ReadNextHeader(&done, &type); + EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type) + << "wrong type from ReadNextHeader after deletion"; + + EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize)) + << "ReadEntityHeader returned an error on third entity"; + EXPECT_EQ(mKey3, key) + << "wrong key from ReadEntityHeader on third entity"; + EXPECT_EQ(sizeof(DATA3), dataSize) + << "wrong size from ReadEntityHeader on third entity"; + + dataBytes = new char[dataSize]; + EXPECT_EQ((int) dataSize, reader->ReadEntityData(dataBytes, dataSize)) + << "ReadEntityData returned an error on third entity"; + for (unsigned int i = 0; i < sizeof(DATA3); i++) { + EXPECT_EQ(DATA3[i], dataBytes[i]) + << "data character " << i << " should be equal"; + } + delete dataBytes; + delete writer; + delete reader; +} + +TEST_F(BackupDataTest, OnlyDeleteEntities) { + int fd = ::open(m_filename, O_WRONLY); + BackupDataWriter* writer = new BackupDataWriter(fd); + writer->WriteEntityHeader(mKey1, -1); + writer->WriteEntityHeader(mKey2, -1); + writer->WriteEntityHeader(mKey3, -1); + writer->WriteEntityHeader(mKey4, -1); + + ::close(fd); + fd = ::open(m_filename, O_RDONLY); + BackupDataReader* reader = new BackupDataReader(fd); + + bool done; + int type; + String8 key; + size_t dataSize; + // read and verify first deletion + reader->ReadNextHeader(&done, &type); + EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type) + << "wrong type from ReadNextHeader first deletion"; + + EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize)) + << "ReadEntityHeader returned an error on first entity"; + EXPECT_EQ(mKey1, key) + << "wrong key from ReadEntityHeader on first entity"; + EXPECT_EQ(-1, (int) dataSize) + << "not recognizing deletion on first entity"; + + // read and verify second deletion + reader->ReadNextHeader(&done, &type); + EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type) + << "wrong type from ReadNextHeader second deletion"; + + EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize)) + << "ReadEntityHeader returned an error on second entity"; + EXPECT_EQ(mKey2, key) + << "wrong key from ReadEntityHeader on second entity"; + EXPECT_EQ(-1, (int) dataSize) + << "not recognizing deletion on second entity"; + + // read and verify third deletion + reader->ReadNextHeader(&done, &type); + EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type) + << "wrong type from ReadNextHeader third deletion"; + + EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize)) + << "ReadEntityHeader returned an error on third entity"; + EXPECT_EQ(mKey3, key) + << "wrong key from ReadEntityHeader on third entity"; + EXPECT_EQ(-1, (int) dataSize) + << "not recognizing deletion on third entity"; + + // read and verify fourth deletion + reader->ReadNextHeader(&done, &type); + EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type) + << "wrong type from ReadNextHeader fourth deletion"; + + EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize)) + << "ReadEntityHeader returned an error on fourth entity"; + EXPECT_EQ(mKey4, key) + << "wrong key from ReadEntityHeader on fourth entity"; + EXPECT_EQ(-1, (int) dataSize) + << "not recognizing deletion on fourth entity"; + + delete writer; + delete reader; +} + +TEST_F(BackupDataTest, ReadDeletedEntityData) { + int fd = ::open(m_filename, O_WRONLY); + BackupDataWriter* writer = new BackupDataWriter(fd); + writer->WriteEntityHeader(mKey1, -1); + writer->WriteEntityHeader(mKey2, -1); + + ::close(fd); + fd = ::open(m_filename, O_RDONLY); + BackupDataReader* reader = new BackupDataReader(fd); + + bool done; + int type; + String8 key; + size_t dataSize; + // read and verify first deletion + reader->ReadNextHeader(&done, &type); + EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type) + << "wrong type from ReadNextHeader first deletion"; + + EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize)) + << "ReadEntityHeader returned an error on first entity"; + EXPECT_EQ(mKey1, key) + << "wrong key from ReadEntityHeader on first entity"; + EXPECT_EQ(-1, (int) dataSize) + << "not recognizing deletion on first entity"; + + // erroneously try to read first entity data + char* dataBytes = new char[10]; + dataBytes[0] = 'A'; + EXPECT_EQ(NO_ERROR, reader->ReadEntityData(dataBytes, dataSize)); + // expect dataBytes to be unmodofied + EXPECT_EQ('A', dataBytes[0]); + + // read and verify second deletion + reader->ReadNextHeader(&done, &type); + EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type) + << "wrong type from ReadNextHeader second deletion"; + + EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize)) + << "ReadEntityHeader returned an error on second entity"; + EXPECT_EQ(mKey2, key) + << "wrong key from ReadEntityHeader on second entity"; + EXPECT_EQ(-1, (int) dataSize) + << "not recognizing deletion on second entity"; + + delete writer; + delete reader; +} + +} |