blob: 40fa36fa670197c7c13f4d68d3785c78becf3dcc [file] [log] [blame]
// Copyright 2012 Google Inc. All Rights Reserved.
//
// 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.
#include "syzygy/zap_timestamp/zap_timestamp.h"
#include "base/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "gtest/gtest.h"
#include "syzygy/core/unittest_util.h"
namespace zap_timestamp {
namespace {
// We don't bother with having specific data for the 'Coverage' case.
#define TEST_DATA_PREFIX_0 L"syzygy\\zap_timestamp\\test_data\\"
#ifdef NDEBUG
#define TEST_DATA_PREFIX_1 L"Release\\"
#else
#define TEST_DATA_PREFIX_1 L"Debug\\"
#endif
#define TEST_DATA_PREFIX TEST_DATA_PREFIX_0 TEST_DATA_PREFIX_1
struct RawPePdbPathPair {
const wchar_t* pe_path;
const wchar_t* pdb_path;
};
RawPePdbPathPair kRawTestPaths[] = {
{ TEST_DATA_PREFIX L"copy0\\test_dll.dll",
TEST_DATA_PREFIX L"copy0\\test_dll.pdb" },
{ TEST_DATA_PREFIX L"copy1\\test_dll.dll",
TEST_DATA_PREFIX L"copy1\\test_dll.pdb" },
{ TEST_DATA_PREFIX L"copy2\\test_dll.dll",
TEST_DATA_PREFIX L"copy2\\test_dll.pdb" } };
struct PePdbPathPair {
base::FilePath pe_path;
base::FilePath pdb_path;
};
class ZapTimestampTest : public testing::Test {
public:
virtual void SetUp() OVERRIDE {
testing::Test::SetUp();
temp_dir_.CreateUniqueTempDir();
// Get the full test data paths.
for (size_t i = 0; i < arraysize(kRawTestPaths); ++i) {
PePdbPathPair pair;
pair.pe_path = testing::GetSrcRelativePath(kRawTestPaths[i].pe_path);
pair.pdb_path = testing::GetSrcRelativePath(kRawTestPaths[i].pdb_path);
test_paths_.push_back(pair);
}
temp_pe_path_ = temp_dir_.path().Append(L"test_dll.dll");
temp_pdb_path_ = temp_dir_.path().Append(L"test_dll.pdb");
}
void CopyTestData(const base::FilePath& pe_path,
const base::FilePath& pdb_path) {
ASSERT_TRUE(base::CopyFile(pe_path, temp_pe_path_));
ASSERT_TRUE(base::CopyFile(pdb_path, temp_pdb_path_));
}
void CopyTestData(size_t index) {
ASSERT_GT(test_paths_.size(), index);
ASSERT_NO_FATAL_FAILURE(CopyTestData(
test_paths_[index].pe_path, test_paths_[index].pdb_path));
}
base::ScopedTempDir temp_dir_;
std::vector<PePdbPathPair> test_paths_;
base::FilePath temp_pe_path_;
base::FilePath temp_pdb_path_;
};
} // namespace
TEST_F(ZapTimestampTest, InitFailsForNonExistentPath) {
ZapTimestamp zap;
EXPECT_FALSE(zap.Init(base::FilePath(L"nonexistent_pe_file.dll")));
}
TEST_F(ZapTimestampTest, InitFailsForMismatchedPeAndPdb) {
ASSERT_NO_FATAL_FAILURE(CopyTestData(
test_paths_[0].pe_path, test_paths_[1].pdb_path));
ZapTimestamp zap;
EXPECT_FALSE(zap.Init(temp_pe_path_));
}
TEST_F(ZapTimestampTest, InitFailsWithMissingPdb) {
ASSERT_NO_FATAL_FAILURE(CopyTestData(0));
ASSERT_TRUE(base::DeleteFile(temp_pdb_path_, false));
ZapTimestamp zap;
EXPECT_FALSE(zap.Init(temp_pe_path_));
}
TEST_F(ZapTimestampTest, InitAutoFindPdb) {
ASSERT_NO_FATAL_FAILURE(CopyTestData(0));
ZapTimestamp zap;
EXPECT_TRUE(zap.Init(temp_pe_path_));
EXPECT_EQ(temp_pdb_path_, zap.pdb_path());
}
TEST_F(ZapTimestampTest, InitExplicitPdb) {
ASSERT_NO_FATAL_FAILURE(CopyTestData(0));
ZapTimestamp zap;
EXPECT_TRUE(zap.Init(temp_pe_path_, temp_pdb_path_));
}
TEST_F(ZapTimestampTest, IsIdempotent) {
// Zap the first set of the PE and PDB files.
ASSERT_NO_FATAL_FAILURE(CopyTestData(0));
ZapTimestamp zap0;
EXPECT_TRUE(zap0.Init(temp_pe_path_));
EXPECT_EQ(temp_pdb_path_, zap0.pdb_path());
EXPECT_TRUE(zap0.Zap(true, true));
// Make a copy of the singly zapped files.
base::FilePath pe_path_0 = temp_dir_.path().Append(L"test_dll_0.dll");
base::FilePath pdb_path_0 = temp_dir_.path().Append(L"test_dll_0.pdb");
ASSERT_TRUE(base::CopyFile(temp_pe_path_, pe_path_0));
ASSERT_TRUE(base::CopyFile(temp_pdb_path_, pdb_path_0));
// Zap them again.
ZapTimestamp zap1;
EXPECT_TRUE(zap1.Init(temp_pe_path_));
EXPECT_EQ(temp_pdb_path_, zap1.pdb_path());
EXPECT_TRUE(zap1.Zap(true, true));
// The singly and doubly zapped files should be the same.
EXPECT_TRUE(base::ContentsEqual(temp_pe_path_, pe_path_0));
EXPECT_TRUE(base::ContentsEqual(temp_pdb_path_, pdb_path_0));
}
TEST_F(ZapTimestampTest, Succeeds) {
// Zap the first set of the PE and PDB files.
ASSERT_NO_FATAL_FAILURE(CopyTestData(0));
ZapTimestamp zap0;
EXPECT_TRUE(zap0.Init(temp_pe_path_));
EXPECT_EQ(temp_pdb_path_, zap0.pdb_path());
EXPECT_TRUE(zap0.Zap(true, true));
// Rename and move the PE and PDB file.
base::FilePath pe_path_0 = temp_dir_.path().Append(L"test_dll_0.dll");
base::FilePath pdb_path_0 = temp_dir_.path().Append(L"test_dll_0.pdb");
ASSERT_TRUE(base::Move(temp_pe_path_, pe_path_0));
ASSERT_TRUE(base::Move(temp_pdb_path_, pdb_path_0));
// Zap the second set of the PE and PDB files.
ASSERT_NO_FATAL_FAILURE(CopyTestData(1));
ZapTimestamp zap1;
EXPECT_TRUE(zap1.Init(temp_pe_path_, temp_pdb_path_));
EXPECT_TRUE(zap1.Zap(true, true));
// Rename and move the PE and PDB file.
base::FilePath pe_path_1 = temp_dir_.path().Append(L"test_dll_1.dll");
base::FilePath pdb_path_1 = temp_dir_.path().Append(L"test_dll_1.pdb");
ASSERT_TRUE(base::Move(temp_pe_path_, pe_path_1));
ASSERT_TRUE(base::Move(temp_pdb_path_, pdb_path_1));
// Zap the third set of the PE and PDB files.
ASSERT_NO_FATAL_FAILURE(CopyTestData(2));
ZapTimestamp zap2;
EXPECT_TRUE(zap2.Init(temp_pe_path_, temp_pdb_path_));
EXPECT_TRUE(zap2.Zap(true, true));
// The sets of zapped files should match.
EXPECT_TRUE(base::ContentsEqual(temp_pe_path_, pe_path_0));
EXPECT_TRUE(base::ContentsEqual(temp_pe_path_, pe_path_1));
EXPECT_TRUE(base::ContentsEqual(temp_pdb_path_, pdb_path_0));
EXPECT_TRUE(base::ContentsEqual(temp_pdb_path_, pdb_path_1));
}
} // namespace zap_timestamp