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/msf/msf_file_stream.h"
16 :
17 : #include "base/path_service.h"
18 : #include "base/files/file_util.h"
19 : #include "gtest/gtest.h"
20 : #include "syzygy/core/unittest_util.h"
21 : #include "syzygy/msf/msf_constants.h"
22 : #include "syzygy/msf/msf_data.h"
23 : #include "syzygy/msf/unittest_util.h"
24 :
25 : namespace msf {
26 :
27 : namespace {
28 :
29 : class TestMsfFileStream : public MsfFileStream {
30 : public:
31 E : TestMsfFileStream(RefCountedFILE* file,
32 : size_t length,
33 : const uint32* pages,
34 : size_t page_size)
35 : : MsfFileStream(file, length, pages, page_size) {}
36 :
37 E : virtual ~TestMsfFileStream() {}
38 :
39 : using MsfFileStream::ReadBytes;
40 : using MsfFileStream::ReadFromPage;
41 : };
42 :
43 : class MsfFileStreamTest : public testing::Test {
44 : public:
45 E : virtual void SetUp() {
46 : file_ = new RefCountedFILE(base::OpenFile(
47 E : testing::GetSrcRelativePath(testing::kTestPdbFilePath), "rb"));
48 E : ASSERT_TRUE(file_.get() != NULL);
49 E : }
50 :
51 : protected:
52 : scoped_refptr<RefCountedFILE> file_;
53 : };
54 :
55 : } // namespace
56 :
57 E : TEST_F(MsfFileStreamTest, Constructor) {
58 E : size_t pages[] = {1, 2, 3};
59 : scoped_refptr<MsfFileStream> stream(
60 E : new MsfFileStream(file_.get(), 10, pages, 8));
61 E : EXPECT_EQ(10, stream->length());
62 E : }
63 :
64 E : TEST_F(MsfFileStreamTest, 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[] = {{0, 0, 3, "Mic"},
75 : {0, 0, 4, "Micr"},
76 : {0, 1, 2, "ic"},
77 : {0, 2, 2, "cr"},
78 : {1, 0, 2, "os"},
79 : {1, 1, 3, "sof"},
80 : {2, 0, 4, "t C/"},
81 E : {2, 2, 2, "C/"}};
82 :
83 E : size_t pages[] = {0, 1, 2};
84 E : size_t page_size = 4;
85 : scoped_refptr<TestMsfFileStream> stream(
86 E : new TestMsfFileStream(file_.get(), sizeof(MsfHeader), pages, page_size));
87 :
88 E : char buffer[4] = {0};
89 E : for (uint32 i = 0; i < arraysize(test_cases); ++i) {
90 E : TestCase test_case = test_cases[i];
91 : EXPECT_TRUE(stream->ReadFromPage(&buffer, test_case.page_num,
92 E : test_case.offset, test_case.count));
93 : EXPECT_EQ(0,
94 E : memcmp(buffer, test_case.expected, strlen(test_case.expected)));
95 E : }
96 E : }
97 :
98 E : TEST_F(MsfFileStreamTest, ReadBytes) {
99 : // Different sections of the MSF header magic string.
100 E : char* test_cases[] = {"Mic", "roso", "ft", " C/C+", "+ MS", "F 7.00"};
101 :
102 : // Test that we can read varying sizes of bytes from the header of the
103 : // file with varying page sizes.
104 E : char buffer[8] = {0};
105 E : for (size_t page_size = 4; page_size <= 32; page_size *= 2) {
106 E : size_t pages[] = {0, 1, 2, 3, 4, 5, 6, 7};
107 : scoped_refptr<TestMsfFileStream> stream(new TestMsfFileStream(
108 E : file_.get(), sizeof(MsfHeader), pages, page_size));
109 :
110 E : for (uint32 j = 0; j < arraysize(test_cases); ++j) {
111 E : char* test_case = test_cases[j];
112 E : size_t len = strlen(test_case);
113 E : size_t bytes_read = 0;
114 E : EXPECT_TRUE(stream->ReadBytes(&buffer, len, &bytes_read));
115 E : EXPECT_EQ(0, memcmp(buffer, test_case, len));
116 E : EXPECT_EQ(len, bytes_read);
117 E : }
118 E : }
119 E : }
120 :
121 : } // namespace msf
|