1 : // Copyright 2012 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/pdb/pdb_file_stream.h"
16 :
17 : #include "base/file_util.h"
18 : #include "base/path_service.h"
19 : #include "gtest/gtest.h"
20 : #include "syzygy/core/unittest_util.h"
21 : #include "syzygy/pdb/pdb_constants.h"
22 : #include "syzygy/pdb/pdb_data.h"
23 : #include "syzygy/pdb/unittest_util.h"
24 :
25 : namespace pdb {
26 :
27 : namespace {
28 :
29 : class TestPdbFileStream : public PdbFileStream {
30 : public:
31 E : TestPdbFileStream(RefCountedFILE* file,
32 : size_t length,
33 : const uint32* pages,
34 : size_t page_size)
35 : : PdbFileStream(file, length, pages, page_size) {
36 E : }
37 :
38 E : virtual ~TestPdbFileStream() { }
39 :
40 : using PdbFileStream::ReadBytes;
41 : using PdbFileStream::ReadFromPage;
42 : };
43 :
44 : class PdbFileStreamTest : public testing::Test {
45 : public:
46 E : virtual void SetUp() {
47 : file_ = new RefCountedFILE(file_util::OpenFile(testing::GetSrcRelativePath(
48 E : testing::kTestPdbFilePath), "rb"));
49 E : ASSERT_TRUE(file_.get() != NULL);
50 E : }
51 :
52 : protected:
53 : scoped_refptr<RefCountedFILE> file_;
54 : };
55 :
56 : } // namespace
57 :
58 E : TEST_F(PdbFileStreamTest, Constructor) {
59 E : size_t pages[] = {1, 2, 3};
60 E : scoped_refptr<PdbFileStream> stream(new PdbFileStream(file_, 10, pages, 8));
61 E : EXPECT_EQ(10, stream->length());
62 E : }
63 :
64 E : TEST_F(PdbFileStreamTest, ReadFromPage) {
65 : struct TestCase {
66 : uint32 page_num;
67 : size_t offset;
68 : size_t count;
69 : char* expected;
70 : };
71 :
72 : // Test calling ReadFromPage with different combinations of page number,
73 : // offset and count.
74 : TestCase test_cases[] = {
75 E : {0, 0, 3, "Mic"},
76 E : {0, 0, 4, "Micr"},
77 E : {0, 1, 2, "ic"},
78 E : {0, 2, 2, "cr"},
79 E : {1, 0, 2, "os"},
80 E : {1, 1, 3, "sof"},
81 E : {2, 0, 4, "t C/"},
82 E : {2, 2, 2, "C/"}
83 : };
84 :
85 E : size_t pages[] = {0, 1, 2};
86 E : size_t page_size = 4;
87 : scoped_refptr<TestPdbFileStream> stream(new TestPdbFileStream(
88 E : file_, sizeof(PdbHeader), pages, page_size));
89 :
90 E : char buffer[4] = {0};
91 E : for (uint32 i = 0; i < arraysize(test_cases); ++i) {
92 E : TestCase test_case = test_cases[i];
93 : EXPECT_TRUE(stream->ReadFromPage(&buffer, test_case.page_num,
94 E : test_case.offset, test_case.count));
95 : EXPECT_EQ(0,
96 E : memcmp(buffer, test_case.expected, strlen(test_case.expected)));
97 E : }
98 E : }
99 :
100 E : TEST_F(PdbFileStreamTest, ReadBytes) {
101 : // Different sections of the pdb header magic string.
102 : char* test_cases[] = {
103 E : "Mic",
104 E : "roso",
105 E : "ft",
106 E : " C/C+",
107 E : "+ MS",
108 : "F 7.00"
109 E : };
110 :
111 : // Test that we can read varying sizes of bytes from the header of the
112 : // file with varying page sizes.
113 E : char buffer[8] = {0};
114 E : for (size_t page_size = 4; page_size <= 32; page_size *= 2) {
115 E : size_t pages[] = {0, 1, 2, 3, 4, 5, 6, 7};
116 : scoped_refptr<TestPdbFileStream> stream(new TestPdbFileStream(
117 E : file_.get(), sizeof(PdbHeader), pages, page_size));
118 :
119 E : for (uint32 j = 0; j < arraysize(test_cases); ++j) {
120 E : char* test_case = test_cases[j];
121 E : size_t len = strlen(test_case);
122 E : size_t bytes_read = 0;
123 E : EXPECT_TRUE(stream->ReadBytes(&buffer, len, &bytes_read));
124 E : EXPECT_EQ(0, memcmp(buffer, test_case, len));
125 E : EXPECT_EQ(len, bytes_read);
126 E : }
127 E : }
128 E : }
129 :
130 : } // namespace pdb
|