1 : // Copyright 2014 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/ar/ar_transform.h"
16 :
17 : #include "base/bind.h"
18 : #include "gmock/gmock.h"
19 : #include "gtest/gtest.h"
20 : #include "syzygy/ar/ar_reader.h"
21 : #include "syzygy/ar/unittest_util.h"
22 : #include "syzygy/core/unittest_util.h"
23 :
24 : namespace ar {
25 :
26 : namespace {
27 :
28 : using testing::_;
29 : using testing::Invoke;
30 : using testing::Return;
31 :
32 : // Test fixture.
33 : class LenientArTransformTest : public testing::Test {
34 : public:
35 : LenientArTransformTest()
36 : : in_memory_callback_(base::Bind(
37 : &LenientArTransformTest::InMemoryCallback,
38 : base::Unretained(this))),
39 : on_disk_callback_(base::Bind(
40 : &LenientArTransformTest::OnDiskCallback,
41 : base::Unretained(this))),
42 E : on_disk_adapter_(on_disk_callback_) {
43 E : }
44 :
45 E : virtual void SetUp() override {
46 E : input_archive_ = testing::GetSrcRelativePath(testing::kArchiveFile);
47 E : ASSERT_TRUE(base::CreateNewTempDirectory(L"ArTransformTest",
48 : &temp_dir_));
49 E : output_archive_ = temp_dir_.Append(L"output.lib");
50 E : }
51 :
52 E : virtual void TearDown() override {
53 E : ASSERT_TRUE(base::DeleteFile(temp_dir_, true));
54 E : }
55 :
56 : MOCK_METHOD3(InMemoryCallback, bool(ParsedArFileHeader*,
57 : DataBuffer*,
58 E : bool*));
59 :
60 : MOCK_METHOD4(OnDiskCallback, bool(const base::FilePath&,
61 : const base::FilePath&,
62 : ParsedArFileHeader*,
63 E : bool*));
64 :
65 : bool InMemoryCallbackDeleteFile(ParsedArFileHeader* header,
66 : DataBuffer* contents,
67 : bool* remove) {
68 : *remove = true;
69 : return true;
70 : }
71 :
72 : bool OnDiskCallbackDeleteFile(const base::FilePath& input_path,
73 : const base::FilePath& output_path,
74 : ParsedArFileHeader* header,
75 E : bool* remove) {
76 E : *remove = true;
77 E : return true;
78 E : }
79 :
80 : bool OnDiskCallbackCopyFile(const base::FilePath& input_path,
81 : const base::FilePath& output_path,
82 : ParsedArFileHeader* header,
83 E : bool* remove) {
84 E : if (!base::CopyFile(input_path, output_path))
85 i : return false;
86 E : return true;
87 E : }
88 :
89 : base::FilePath input_archive_;
90 : base::FilePath output_archive_;
91 : base::FilePath temp_dir_;
92 :
93 : ArTransform::TransformFileCallback in_memory_callback_;
94 : OnDiskArTransformAdapter::TransformFileOnDiskCallback on_disk_callback_;
95 : OnDiskArTransformAdapter on_disk_adapter_;
96 : };
97 : typedef testing::StrictMock<LenientArTransformTest> ArTransformTest;
98 :
99 : } // namespace
100 :
101 E : TEST_F(ArTransformTest, TransformFailsBadInput) {
102 E : base::FilePath bad_path(L"this_should_never_exist.lib");
103 E : ArTransform tx;
104 E : tx.set_input_archive(bad_path);
105 E : tx.set_output_archive(output_archive_);
106 E : tx.set_callback(in_memory_callback_);
107 E : EXPECT_FALSE(tx.Transform());
108 E : }
109 :
110 E : TEST_F(ArTransformTest, TransformFailsInMemoryCallbackFails) {
111 E : ArTransform tx;
112 E : tx.set_input_archive(input_archive_);
113 E : tx.set_output_archive(output_archive_);
114 E : tx.set_callback(in_memory_callback_);
115 :
116 : EXPECT_CALL(*this, InMemoryCallback(_, _, _))
117 E : .Times(1).WillOnce(Return(false));
118 :
119 E : EXPECT_FALSE(tx.Transform());
120 E : EXPECT_FALSE(base::PathExists(output_archive_));
121 E : }
122 :
123 E : TEST_F(ArTransformTest, TransformIdentityInMemory) {
124 E : ArTransform tx;
125 E : tx.set_input_archive(input_archive_);
126 E : tx.set_output_archive(output_archive_);
127 E : tx.set_callback(in_memory_callback_);
128 :
129 : EXPECT_CALL(*this, InMemoryCallback(_, _, _))
130 E : .Times(testing::kArchiveFileCount).WillRepeatedly(Return(true));
131 :
132 E : EXPECT_TRUE(tx.Transform());
133 E : EXPECT_TRUE(base::PathExists(output_archive_));
134 :
135 E : ArReader reader;
136 E : EXPECT_TRUE(reader.Init(output_archive_));
137 E : EXPECT_EQ(testing::kArchiveFileCount, reader.offsets().size());
138 E : }
139 :
140 E : TEST_F(ArTransformTest, TransformFailsOnDiskCallbackFails) {
141 E : ArTransform tx;
142 E : tx.set_input_archive(input_archive_);
143 E : tx.set_output_archive(output_archive_);
144 E : tx.set_callback(on_disk_adapter_.outer_callback());
145 :
146 : EXPECT_CALL(*this, OnDiskCallback(_, _, _, _))
147 E : .Times(1).WillRepeatedly(Return(true));
148 :
149 E : EXPECT_FALSE(tx.Transform());
150 E : EXPECT_FALSE(base::PathExists(output_archive_));
151 E : }
152 :
153 E : TEST_F(ArTransformTest, TransformIdentityOnDiskFailsNoOutputFile) {
154 E : ArTransform tx;
155 E : tx.set_input_archive(input_archive_);
156 E : tx.set_output_archive(output_archive_);
157 E : tx.set_callback(on_disk_adapter_.outer_callback());
158 :
159 : EXPECT_CALL(*this, OnDiskCallback(_, _, _, _))
160 E : .Times(1).WillOnce(Return(true));
161 :
162 E : EXPECT_FALSE(tx.Transform());
163 E : EXPECT_FALSE(base::PathExists(output_archive_));
164 E : }
165 :
166 E : TEST_F(ArTransformTest, TransformIdentityOnDisk) {
167 E : ArTransform tx;
168 E : tx.set_input_archive(input_archive_);
169 E : tx.set_output_archive(output_archive_);
170 E : tx.set_callback(on_disk_adapter_.outer_callback());
171 :
172 : EXPECT_CALL(*this, OnDiskCallback(_, _, _, _))
173 : .Times(testing::kArchiveFileCount)
174 E : .WillRepeatedly(Invoke(this, &ArTransformTest::OnDiskCallbackCopyFile));
175 :
176 E : EXPECT_TRUE(tx.Transform());
177 E : EXPECT_TRUE(base::PathExists(output_archive_));
178 :
179 E : ArReader reader;
180 E : EXPECT_TRUE(reader.Init(output_archive_));
181 E : EXPECT_EQ(testing::kArchiveFileCount, reader.offsets().size());
182 E : }
183 :
184 E : TEST_F(ArTransformTest, TransformIdentityOnDiskEraseFile) {
185 E : ArTransform tx;
186 E : tx.set_input_archive(input_archive_);
187 E : tx.set_output_archive(output_archive_);
188 E : tx.set_callback(on_disk_adapter_.outer_callback());
189 :
190 : // Copy all of the files over except for the second one.
191 : EXPECT_CALL(*this, OnDiskCallback(_, _, _, _))
192 : .Times(testing::kArchiveFileCount)
193 : .WillOnce(Invoke(this, &ArTransformTest::OnDiskCallbackCopyFile))
194 : .WillOnce(Invoke(this, &ArTransformTest::OnDiskCallbackDeleteFile))
195 E : .WillRepeatedly(Invoke(this, &ArTransformTest::OnDiskCallbackCopyFile));
196 :
197 E : EXPECT_TRUE(tx.Transform());
198 E : EXPECT_TRUE(base::PathExists(output_archive_));
199 :
200 E : ArReader reader;
201 E : EXPECT_TRUE(reader.Init(output_archive_));
202 E : EXPECT_EQ(testing::kArchiveFileCount - 1, reader.offsets().size());
203 E : }
204 :
205 : } // namespace ar
|