| 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 |