diff options
Diffstat (limited to 'tests/component/applypatch_test.cpp')
-rw-r--r-- | tests/component/applypatch_test.cpp | 264 |
1 files changed, 138 insertions, 126 deletions
diff --git a/tests/component/applypatch_test.cpp b/tests/component/applypatch_test.cpp index 908a9f5f5..e09c1e7ba 100644 --- a/tests/component/applypatch_test.cpp +++ b/tests/component/applypatch_test.cpp @@ -23,102 +23,98 @@ #include <sys/types.h> #include <time.h> +#include <memory> #include <string> +#include <vector> #include <android-base/file.h> #include <android-base/stringprintf.h> #include <android-base/test_utils.h> +#include <openssl/sha.h> #include "applypatch/applypatch.h" #include "common/test_constants.h" -#include "openssl/sha.h" #include "print_sha1.h" static const std::string DATA_PATH = getenv("ANDROID_DATA"); static const std::string TESTDATA_PATH = "/recovery/testdata"; -static const std::string WORK_FS = "/data"; -static std::string sha1sum(const std::string& fname) { - uint8_t digest[SHA_DIGEST_LENGTH]; +static void sha1sum(const std::string& fname, std::string* sha1) { + ASSERT_NE(nullptr, sha1); + std::string data; - android::base::ReadFileToString(fname, &data); + ASSERT_TRUE(android::base::ReadFileToString(fname, &data)); - SHA1((const uint8_t*)data.c_str(), data.size(), digest); - return print_sha1(digest); + uint8_t digest[SHA_DIGEST_LENGTH]; + SHA1(reinterpret_cast<const uint8_t*>(data.c_str()), data.size(), digest); + *sha1 = print_sha1(digest); } static void mangle_file(const std::string& fname) { - FILE* fh = fopen(&fname[0], "w"); - int r; - for (int i=0; i < 1024; i++) { - r = rand(); - fwrite(&r, sizeof(short), 1, fh); + std::string content; + content.reserve(1024); + for (size_t i = 0; i < 1024; i++) { + content[i] = rand() % 256; } - fclose(fh); + ASSERT_TRUE(android::base::WriteStringToFile(content, fname)); } -static bool file_cmp(std::string& f1, std::string& f2) { +static bool file_cmp(const std::string& f1, const std::string& f2) { std::string c1; - std::string c2; android::base::ReadFileToString(f1, &c1); + std::string c2; android::base::ReadFileToString(f2, &c2); return c1 == c2; } static std::string from_testdata_base(const std::string& fname) { - return android::base::StringPrintf("%s%s%s/%s", - &DATA_PATH[0], - &NATIVE_TEST_PATH[0], - &TESTDATA_PATH[0], - &fname[0]); + return DATA_PATH + NATIVE_TEST_PATH + TESTDATA_PATH + "/" + fname; } class ApplyPatchTest : public ::testing::Test { - public: - static void SetUpTestCase() { - // set up files - old_file = from_testdata_base("old.file"); - new_file = from_testdata_base("new.file"); - patch_file = from_testdata_base("patch.bsdiff"); - rand_file = "/cache/applypatch_test_rand.file"; - cache_file = "/cache/saved.file"; - - // write stuff to rand_file - android::base::WriteStringToFile("hello", rand_file); - - // set up SHA constants - old_sha1 = sha1sum(old_file); - new_sha1 = sha1sum(new_file); - srand(time(NULL)); - bad_sha1_a = android::base::StringPrintf("%040x", rand()); - bad_sha1_b = android::base::StringPrintf("%040x", rand()); - - struct stat st; - stat(&new_file[0], &st); - new_size = st.st_size; - } - - static std::string old_file; - static std::string new_file; - static std::string rand_file; - static std::string cache_file; - static std::string patch_file; - - static std::string old_sha1; - static std::string new_sha1; - static std::string bad_sha1_a; - static std::string bad_sha1_b; - - static size_t new_size; + public: + static void SetUpTestCase() { + // set up files + old_file = from_testdata_base("old.file"); + new_file = from_testdata_base("new.file"); + patch_file = from_testdata_base("patch.bsdiff"); + rand_file = "/cache/applypatch_test_rand.file"; + cache_file = "/cache/saved.file"; + + // write stuff to rand_file + ASSERT_TRUE(android::base::WriteStringToFile("hello", rand_file)); + + // set up SHA constants + sha1sum(old_file, &old_sha1); + sha1sum(new_file, &new_sha1); + srand(time(NULL)); + bad_sha1_a = android::base::StringPrintf("%040x", rand()); + bad_sha1_b = android::base::StringPrintf("%040x", rand()); + + struct stat st; + stat(&new_file[0], &st); + new_size = st.st_size; + } + + static std::string old_file; + static std::string new_file; + static std::string rand_file; + static std::string cache_file; + static std::string patch_file; + + static std::string old_sha1; + static std::string new_sha1; + static std::string bad_sha1_a; + static std::string bad_sha1_b; + + static size_t new_size; }; std::string ApplyPatchTest::old_file; std::string ApplyPatchTest::new_file; -static void cp(std::string src, std::string tgt) { - std::string cmd = android::base::StringPrintf("cp %s %s", - &src[0], - &tgt[0]); +static void cp(const std::string& src, const std::string& tgt) { + std::string cmd = "cp " + src + " " + tgt; system(&cmd[0]); } @@ -131,59 +127,55 @@ static void restore_old() { } class ApplyPatchCacheTest : public ApplyPatchTest { - public: - virtual void SetUp() { - backup_old(); - } - - virtual void TearDown() { - restore_old(); - } + public: + virtual void SetUp() { + backup_old(); + } + + virtual void TearDown() { + restore_old(); + } }; class ApplyPatchFullTest : public ApplyPatchCacheTest { - public: - static void SetUpTestCase() { - ApplyPatchTest::SetUpTestCase(); - unsigned long free_kb = FreeSpaceForFile(&WORK_FS[0]); - ASSERT_GE(free_kb * 1024, new_size * 3 / 2); - output_f = new TemporaryFile(); - output_loc = std::string(output_f->path); - - struct FileContents fc; - - ASSERT_EQ(0, LoadFileContents(&rand_file[0], &fc)); - Value* patch1 = new Value(VAL_BLOB, std::string(fc.data.begin(), fc.data.end())); - patches.push_back(patch1); - - ASSERT_EQ(0, LoadFileContents(&patch_file[0], &fc)); - Value* patch2 = new Value(VAL_BLOB, std::string(fc.data.begin(), fc.data.end())); - patches.push_back(patch2); - } - static void TearDownTestCase() { - delete output_f; - for (auto it = patches.begin(); it != patches.end(); ++it) { - delete *it; - } - patches.clear(); - } - - static std::vector<Value*> patches; - static TemporaryFile* output_f; - static std::string output_loc; + public: + static void SetUpTestCase() { + ApplyPatchTest::SetUpTestCase(); + + output_f = new TemporaryFile(); + output_loc = std::string(output_f->path); + + struct FileContents fc; + + ASSERT_EQ(0, LoadFileContents(&rand_file[0], &fc)); + patches.push_back( + std::make_unique<Value>(VAL_BLOB, std::string(fc.data.begin(), fc.data.end()))); + + ASSERT_EQ(0, LoadFileContents(&patch_file[0], &fc)); + patches.push_back( + std::make_unique<Value>(VAL_BLOB, std::string(fc.data.begin(), fc.data.end()))); + } + + static void TearDownTestCase() { + delete output_f; + } + + static std::vector<std::unique_ptr<Value>> patches; + static TemporaryFile* output_f; + static std::string output_loc; }; class ApplyPatchDoubleCacheTest : public ApplyPatchFullTest { - public: - virtual void SetUp() { - ApplyPatchCacheTest::SetUp(); - cp(cache_file, "/cache/reallysaved.file"); - } - - virtual void TearDown() { - cp("/cache/reallysaved.file", cache_file); - ApplyPatchCacheTest::TearDown(); - } + public: + virtual void SetUp() { + ApplyPatchCacheTest::SetUp(); + cp(cache_file, "/cache/reallysaved.file"); + } + + virtual void TearDown() { + cp("/cache/reallysaved.file", cache_file); + ApplyPatchCacheTest::TearDown(); + } }; std::string ApplyPatchTest::rand_file; @@ -196,7 +188,7 @@ std::string ApplyPatchTest::bad_sha1_b; size_t ApplyPatchTest::new_size; -std::vector<Value*> ApplyPatchFullTest::patches; +std::vector<std::unique_ptr<Value>> ApplyPatchFullTest::patches; TemporaryFile* ApplyPatchFullTest::output_f; std::string ApplyPatchFullTest::output_loc; @@ -287,7 +279,7 @@ TEST_F(ApplyPatchFullTest, ApplyInPlace) { &new_sha1[0], new_size, sha1s, - patches.data(), + patches, nullptr); ASSERT_EQ(0, ap_result); ASSERT_TRUE(file_cmp(old_file, new_file)); @@ -297,7 +289,7 @@ TEST_F(ApplyPatchFullTest, ApplyInPlace) { &new_sha1[0], new_size, sha1s, - patches.data(), + patches, nullptr); ASSERT_EQ(0, ap_result); ASSERT_TRUE(file_cmp(old_file, new_file)); @@ -308,75 +300,95 @@ TEST_F(ApplyPatchFullTest, ApplyInNewLocation) { bad_sha1_a, old_sha1 }; - int ap_result = applypatch(&old_file[0], + // Apply bsdiff patch to new location. + ASSERT_EQ(0, applypatch(&old_file[0], &output_loc[0], &new_sha1[0], new_size, sha1s, - patches.data(), - nullptr); - ASSERT_EQ(0, ap_result); + patches, + nullptr)); ASSERT_TRUE(file_cmp(output_loc, new_file)); - ap_result = applypatch(&old_file[0], + + // Reapply to the same location. + ASSERT_EQ(0, applypatch(&old_file[0], &output_loc[0], &new_sha1[0], new_size, sha1s, - patches.data(), - nullptr); - ASSERT_EQ(0, ap_result); + patches, + nullptr)); ASSERT_TRUE(file_cmp(output_loc, new_file)); } TEST_F(ApplyPatchFullTest, ApplyCorruptedInNewLocation) { - mangle_file(old_file); std::vector<std::string> sha1s = { bad_sha1_a, old_sha1 }; + // Apply bsdiff patch to new location with corrupted source. + mangle_file(old_file); int ap_result = applypatch(&old_file[0], &output_loc[0], &new_sha1[0], new_size, sha1s, - patches.data(), + patches, nullptr); ASSERT_EQ(0, ap_result); ASSERT_TRUE(file_cmp(output_loc, new_file)); + + // Reapply bsdiff patch to new location with corrupted source. ap_result = applypatch(&old_file[0], &output_loc[0], &new_sha1[0], new_size, sha1s, - patches.data(), + patches, nullptr); ASSERT_EQ(0, ap_result); ASSERT_TRUE(file_cmp(output_loc, new_file)); } TEST_F(ApplyPatchDoubleCacheTest, ApplyDoubleCorruptedInNewLocation) { - mangle_file(old_file); - mangle_file(cache_file); - std::vector<std::string> sha1s = { bad_sha1_a, old_sha1 }; + + // Apply bsdiff patch to new location with corrupted source and copy (no new file). + // Expected to fail. + mangle_file(old_file); + mangle_file(cache_file); int ap_result = applypatch(&old_file[0], &output_loc[0], &new_sha1[0], new_size, sha1s, - patches.data(), + patches, + nullptr); + ASSERT_NE(0, ap_result); + ASSERT_FALSE(file_cmp(output_loc, new_file)); + + // Expected to fail again on retry. + ap_result = applypatch(&old_file[0], + &output_loc[0], + &new_sha1[0], + new_size, + sha1s, + patches, nullptr); ASSERT_NE(0, ap_result); ASSERT_FALSE(file_cmp(output_loc, new_file)); + + // Expected to fail with incorrect new file. + mangle_file(output_loc); ap_result = applypatch(&old_file[0], &output_loc[0], &new_sha1[0], new_size, sha1s, - patches.data(), + patches, nullptr); ASSERT_NE(0, ap_result); ASSERT_FALSE(file_cmp(output_loc, new_file)); |