OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include <atlbase.h> | |
6 #include <atlcom.h> | |
7 | |
8 #include "base/file_util.h" | |
9 #include "base/path_service.h" | |
10 #include "base/win/scoped_comptr.h" | |
11 #include "chrome_frame/test/chrome_frame_test_utils.h" | |
12 #include "chrome_frame/test/urlmon_moniker_tests.h" | |
13 #include "chrome_frame/urlmon_bind_status_callback.h" | |
14 | |
15 using chrome_frame_test::ScopedVirtualizeHklmAndHkcu; | |
16 using testing::Return; | |
17 using testing::Eq; | |
18 | |
19 class MonikerPatchTest : public testing::Test { | |
20 protected: | |
21 MonikerPatchTest() { | |
22 } | |
23 | |
24 virtual void SetUp() { | |
25 DeleteAllSingletons(); | |
26 PathService::Get(base::DIR_SOURCE_ROOT, &test_file_path_); | |
27 test_file_path_ = test_file_path_.Append(FILE_PATH_LITERAL("chrome_frame")) | |
28 .Append(FILE_PATH_LITERAL("test")) | |
29 .Append(FILE_PATH_LITERAL("data")); | |
30 } | |
31 | |
32 bool ReadFileAsString(const wchar_t* file_name, std::string* file_contents) { | |
33 EXPECT_TRUE(file_name); | |
34 base::FilePath file_path = test_file_path_.Append(file_name); | |
35 return base::ReadFileToString(file_path, file_contents); | |
36 } | |
37 | |
38 static bool StringToStream(const std::string& data, IStream** ret) { | |
39 EXPECT_TRUE(!data.empty()); | |
40 | |
41 base::win::ScopedComPtr<IStream> stream; | |
42 HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, stream.Receive()); | |
43 EXPECT_HRESULT_SUCCEEDED(hr); | |
44 if (FAILED(hr)) { | |
45 return false; | |
46 } | |
47 | |
48 DWORD written = 0; | |
49 hr = stream->Write(data.c_str(), data.size(), &written); | |
50 EXPECT_HRESULT_SUCCEEDED(hr); | |
51 EXPECT_EQ(data.size(), written); | |
52 | |
53 bool result = false; | |
54 if (SUCCEEDED(hr)) { | |
55 RewindStream(stream); | |
56 *ret = stream.Detach(); | |
57 result = true; | |
58 } | |
59 | |
60 return result; | |
61 } | |
62 | |
63 base::FilePath test_file_path_; | |
64 ScopedVirtualizeHklmAndHkcu virtualized_registry_; | |
65 }; | |
66 | |
67 // Tests the CacheStream class by writing content into a stream object | |
68 // and verify that reading that stream back | |
69 TEST_F(MonikerPatchTest, CacheStream) { | |
70 const char data[] = "ReadStreamCacheTest"; | |
71 char ret[2 * sizeof(data)] = {0}; | |
72 DWORD read = 0; | |
73 | |
74 // Test 1: empty stream reads nothing | |
75 CComObjectStackEx<CacheStream> cache_stream1; | |
76 EXPECT_EQ(S_FALSE, cache_stream1.Read(ret, sizeof(ret), &read)); | |
77 EXPECT_EQ(0, read); | |
78 | |
79 // Test 2: Read from initialized cache | |
80 CComObjectStackEx<CacheStream> cache_stream2; | |
81 cache_stream2.Initialize(data, sizeof(data), false); | |
82 EXPECT_HRESULT_SUCCEEDED(cache_stream2.Read(ret, sizeof(ret), &read)); | |
83 EXPECT_EQ(sizeof(data), read); | |
84 EXPECT_EQ(std::string(data), std::string(ret)); | |
85 | |
86 read = 0; | |
87 EXPECT_EQ(E_PENDING, cache_stream2.Read(ret, sizeof(ret), &read)); | |
88 EXPECT_EQ(0, read); | |
89 } | |
90 | |
91 ACTION_P3(ReadStream, buffer, size, ret) { | |
92 EXPECT_EQ(TYMED_ISTREAM, arg3->tymed); | |
93 *ret = arg3->pstm->Read(buffer, *size, size); | |
94 } | |
95 | |
96 // Tests the implementation of BSCBFeedData to feed data to the | |
97 // specified IBindStatusCallback | |
98 TEST_F(MonikerPatchTest, BSCBFeedData) { | |
99 CComObjectStackEx<MockBindStatusCallbackImpl> mock; | |
100 const char data[] = "ReadStreamCacheTest"; | |
101 const DWORD size = sizeof(data); | |
102 const CLIPFORMAT cf = 0xd0d0; | |
103 const DWORD flags = BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION; | |
104 const DWORD kArbitraryreadSize = 0xdeadbabe; | |
105 | |
106 char read_buffer1[size] = {0}, read_buffer2[size] = {0}; | |
107 DWORD read_size1 = size, read_size2 = kArbitraryreadSize; | |
108 HRESULT ret1 = E_FAIL, ret2 = E_FAIL; | |
109 | |
110 EXPECT_CALL(mock, OnDataAvailable(flags, size, | |
111 testing::Field(&FORMATETC::cfFormat, cf), | |
112 testing::Field(&STGMEDIUM::tymed, TYMED_ISTREAM))) | |
113 .WillOnce(testing::DoAll( | |
114 ReadStream(read_buffer1, &read_size1, &ret1), | |
115 ReadStream(read_buffer2, &read_size2, &ret2), | |
116 Return(S_OK))); | |
117 | |
118 EXPECT_HRESULT_SUCCEEDED(CacheStream::BSCBFeedData(&mock, data, size, cf, | |
119 flags, false)); | |
120 | |
121 EXPECT_HRESULT_SUCCEEDED(ret1); | |
122 EXPECT_STREQ(data, read_buffer1); | |
123 EXPECT_EQ(size, read_size1); | |
124 | |
125 EXPECT_EQ(E_PENDING, ret2); | |
126 EXPECT_STREQ("", read_buffer2); | |
127 EXPECT_EQ(kArbitraryreadSize, read_size2); | |
128 } | |
129 | |
130 const wchar_t kSmallHtmlMetaTag[] = L"sub_frame1.html"; | |
131 const wchar_t kSmallHtmlNoMetaTag[] = L"host_browser.html"; | |
132 | |
133 // Test various aspects of the SniffData class | |
134 TEST_F(MonikerPatchTest, SniffDataMetaTag) { | |
135 std::string small_html_meta_tag, small_html_no_meta_tag; | |
136 ASSERT_TRUE(ReadFileAsString(kSmallHtmlMetaTag, &small_html_meta_tag)); | |
137 ASSERT_TRUE(ReadFileAsString(kSmallHtmlNoMetaTag, &small_html_no_meta_tag)); | |
138 | |
139 base::win::ScopedComPtr<IStream> stream_with_meta, stream_no_meta; | |
140 ASSERT_TRUE(StringToStream(small_html_meta_tag, stream_with_meta.Receive())); | |
141 ASSERT_TRUE(StringToStream(small_html_no_meta_tag, | |
142 stream_no_meta.Receive())); | |
143 | |
144 // Initialize 2 sniffers 1 with meta tag and 1 without. | |
145 SniffData sniffer1, sniffer2; | |
146 EXPECT_HRESULT_SUCCEEDED(sniffer1.InitializeCache(std::wstring())); | |
147 EXPECT_HRESULT_SUCCEEDED(sniffer2.InitializeCache(std::wstring())); | |
148 EXPECT_HRESULT_SUCCEEDED(sniffer1.ReadIntoCache(stream_with_meta, true)); | |
149 EXPECT_HRESULT_SUCCEEDED(sniffer2.ReadIntoCache(stream_no_meta, true)); | |
150 | |
151 // Verify renderer type and size read. | |
152 EXPECT_TRUE(sniffer1.is_chrome()); | |
153 EXPECT_EQ(SniffData::OTHER, sniffer2.renderer_type()); | |
154 EXPECT_EQ(small_html_meta_tag.size(), sniffer1.size()); | |
155 EXPECT_EQ(small_html_no_meta_tag.size(), sniffer2.size()); | |
156 } | |
157 | |
158 // Now test how the data is fed back the the bind status callback. | |
159 // case 1: callback reads data in 1 read | |
160 TEST_F(MonikerPatchTest, SniffDataPlayback1) { | |
161 std::string small_html_meta_tag; | |
162 base::win::ScopedComPtr<IStream> stream_with_meta; | |
163 SniffData sniffer; | |
164 | |
165 EXPECT_HRESULT_SUCCEEDED(sniffer.InitializeCache(std::wstring())); | |
166 ASSERT_TRUE(ReadFileAsString(kSmallHtmlMetaTag, &small_html_meta_tag)); | |
167 ASSERT_TRUE(StringToStream(small_html_meta_tag, stream_with_meta.Receive())); | |
168 EXPECT_HRESULT_SUCCEEDED(sniffer.ReadIntoCache(stream_with_meta, true)); | |
169 | |
170 CComObjectStackEx<MockBindStatusCallbackImpl> mock; | |
171 const CLIPFORMAT cf = 0xd0d0; | |
172 const DWORD flags = BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION; | |
173 const DWORD data_size = small_html_meta_tag.size(); | |
174 | |
175 DWORD read_size1 = data_size * 2; | |
176 scoped_ptr<char[]> read_buffer1(new char[read_size1]); | |
177 ZeroMemory(read_buffer1.get(), read_size1); | |
178 | |
179 char read_buffer2[10] = {0}; | |
180 DWORD read_size2 = sizeof(read_buffer2); | |
181 HRESULT ret1 = E_FAIL, ret2 = E_FAIL; | |
182 | |
183 EXPECT_CALL(mock, OnDataAvailable(flags, data_size, | |
184 testing::Field(&FORMATETC::cfFormat, cf), | |
185 testing::Field(&STGMEDIUM::tymed, TYMED_ISTREAM))) | |
186 .WillOnce(testing::DoAll( | |
187 ReadStream(read_buffer1.get(), &read_size1, &ret1), | |
188 ReadStream(read_buffer2, &read_size2, &ret2), | |
189 Return(S_OK))); | |
190 | |
191 EXPECT_HRESULT_SUCCEEDED(sniffer.DrainCache(&mock, flags, cf)); | |
192 | |
193 EXPECT_HRESULT_SUCCEEDED(ret1); | |
194 EXPECT_EQ(small_html_meta_tag, read_buffer1.get()); | |
195 EXPECT_EQ(data_size, read_size1); | |
196 | |
197 EXPECT_EQ(S_FALSE, ret2); | |
198 EXPECT_STREQ("", read_buffer2); | |
199 EXPECT_EQ(sizeof(read_buffer2), read_size2); | |
200 } | |
201 | |
202 // case 2: callback reads data in 2 reads. | |
203 TEST_F(MonikerPatchTest, SniffDataPlayback2) { | |
204 std::string small_html_meta_tag; | |
205 base::win::ScopedComPtr<IStream> stream_with_meta; | |
206 SniffData sniffer; | |
207 | |
208 EXPECT_HRESULT_SUCCEEDED(sniffer.InitializeCache(std::wstring())); | |
209 ASSERT_TRUE(ReadFileAsString(kSmallHtmlMetaTag, &small_html_meta_tag)); | |
210 ASSERT_TRUE(StringToStream(small_html_meta_tag, stream_with_meta.Receive())); | |
211 EXPECT_HRESULT_SUCCEEDED(sniffer.ReadIntoCache(stream_with_meta, true)); | |
212 | |
213 CComObjectStackEx<MockBindStatusCallbackImpl> mock; | |
214 const CLIPFORMAT cf = 0xd0d0; | |
215 const DWORD flags = BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION; | |
216 const DWORD data_size = small_html_meta_tag.size(); | |
217 | |
218 DWORD read_size1 = data_size / 2; // First read is half the data. | |
219 DWORD read_size2 = data_size; // Second read, try to read past data. | |
220 scoped_ptr<char[]> read_buffer1(new char[read_size1]); | |
221 scoped_ptr<char[]> read_buffer2(new char[read_size2]); | |
222 ZeroMemory(read_buffer1.get(), read_size1); | |
223 ZeroMemory(read_buffer2.get(), read_size2); | |
224 | |
225 char read_buffer3[10] = {0}; | |
226 DWORD read_size3 = sizeof(read_buffer3); | |
227 HRESULT ret1 = E_FAIL, ret2 = E_FAIL, ret3 = E_FAIL; | |
228 | |
229 EXPECT_CALL(mock, OnDataAvailable(flags, data_size, | |
230 testing::Field(&FORMATETC::cfFormat, cf), | |
231 testing::Field(&STGMEDIUM::tymed, TYMED_ISTREAM))) | |
232 .WillOnce(testing::DoAll( | |
233 ReadStream(read_buffer1.get(), &read_size1, &ret1), | |
234 ReadStream(read_buffer2.get(), &read_size2, &ret2), | |
235 ReadStream(read_buffer3, &read_size3, &ret3), | |
236 Return(S_OK))); | |
237 | |
238 EXPECT_HRESULT_SUCCEEDED(sniffer.DrainCache(&mock, flags, cf)); | |
239 | |
240 EXPECT_HRESULT_SUCCEEDED(ret1); | |
241 EXPECT_HRESULT_SUCCEEDED(ret2); | |
242 EXPECT_EQ(data_size/2, read_size1); | |
243 EXPECT_EQ(data_size - read_size1, read_size2); | |
244 | |
245 std::string data_read; | |
246 data_read.append(read_buffer1.get(), read_size1); | |
247 data_read.append(read_buffer2.get(), read_size2); | |
248 EXPECT_EQ(small_html_meta_tag, data_read); | |
249 | |
250 EXPECT_EQ(S_FALSE, ret3); | |
251 EXPECT_STREQ("", read_buffer3); | |
252 EXPECT_EQ(sizeof(read_buffer3), read_size3); | |
253 } | |
OLD | NEW |