| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 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 "base/bind.h" | |
| 6 #include "base/command_line.h" | |
| 7 #include "base/files/file_path.h" | |
| 8 #include "chrome/browser/extensions/api/cast_channel/cast_channel_api.h" | |
| 9 #include "chrome/browser/extensions/api/cast_channel/cast_socket.h" | |
| 10 #include "chrome/browser/extensions/extension_apitest.h" | |
| 11 #include "chrome/browser/extensions/extension_service.h" | |
| 12 #include "chrome/common/extensions/api/cast_channel.h" | |
| 13 #include "content/public/browser/browser_thread.h" | |
| 14 #include "extensions/common/switches.h" | |
| 15 #include "net/base/capturing_net_log.h" | |
| 16 #include "net/base/completion_callback.h" | |
| 17 #include "net/base/net_errors.h" | |
| 18 #include "testing/gmock/include/gmock/gmock.h" | |
| 19 #include "testing/gmock_mutant.h" | |
| 20 | |
| 21 namespace cast_channel = extensions::api::cast_channel; | |
| 22 using cast_channel::CastSocket; | |
| 23 using cast_channel::ChannelError; | |
| 24 using cast_channel::MessageInfo; | |
| 25 using cast_channel::ReadyState; | |
| 26 | |
| 27 using ::testing::_; | |
| 28 using ::testing::A; | |
| 29 using ::testing::DoAll; | |
| 30 using ::testing::Invoke; | |
| 31 using ::testing::InSequence; | |
| 32 using ::testing::Return; | |
| 33 | |
| 34 namespace { | |
| 35 | |
| 36 const char kTestExtensionId[] = "ddchlicdkolnonkihahngkmmmjnjlkkf"; | |
| 37 | |
| 38 static void FillMessageInfo(MessageInfo* message_info, | |
| 39 const std::string& message) { | |
| 40 message_info->namespace_ = "foo"; | |
| 41 message_info->source_id = "src"; | |
| 42 message_info->destination_id = "dest"; | |
| 43 message_info->data.reset(new base::StringValue(message)); | |
| 44 } | |
| 45 | |
| 46 ACTION_TEMPLATE(InvokeCompletionCallback, | |
| 47 HAS_1_TEMPLATE_PARAMS(int, k), | |
| 48 AND_1_VALUE_PARAMS(result)) { | |
| 49 ::std::tr1::get<k>(args).Run(result); | |
| 50 } | |
| 51 | |
| 52 ACTION_P2(InvokeDelegateOnError, api_test, api) { | |
| 53 api_test->CallOnError(api); | |
| 54 } | |
| 55 | |
| 56 class MockCastSocket : public CastSocket { | |
| 57 public: | |
| 58 explicit MockCastSocket(CastSocket::Delegate* delegate, | |
| 59 net::IPEndPoint ip_endpoint, | |
| 60 net::NetLog* net_log) | |
| 61 : CastSocket(kTestExtensionId, ip_endpoint, | |
| 62 cast_channel::CHANNEL_AUTH_TYPE_SSL, delegate, net_log) {} | |
| 63 virtual ~MockCastSocket() {} | |
| 64 | |
| 65 virtual bool CalledOnValidThread() const OVERRIDE { | |
| 66 // Always return true in testing. | |
| 67 return true; | |
| 68 } | |
| 69 | |
| 70 MOCK_METHOD1(Connect, void(const net::CompletionCallback& callback)); | |
| 71 MOCK_METHOD2(SendMessage, void(const MessageInfo& message, | |
| 72 const net::CompletionCallback& callback)); | |
| 73 MOCK_METHOD1(Close, void(const net::CompletionCallback& callback)); | |
| 74 MOCK_CONST_METHOD0(ready_state, cast_channel::ReadyState()); | |
| 75 MOCK_CONST_METHOD0(error_state, cast_channel::ChannelError()); | |
| 76 }; | |
| 77 | |
| 78 } // namespace | |
| 79 | |
| 80 class CastChannelAPITest : public ExtensionApiTest { | |
| 81 public: | |
| 82 CastChannelAPITest() {} | |
| 83 | |
| 84 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { | |
| 85 ExtensionApiTest::SetUpCommandLine(command_line); | |
| 86 command_line->AppendSwitchASCII( | |
| 87 extensions::switches::kWhitelistedExtensionID, | |
| 88 kTestExtensionId); | |
| 89 } | |
| 90 | |
| 91 void SetUpMockCastSocket() { | |
| 92 extensions::CastChannelAPI* api = GetApi(); | |
| 93 net::IPAddressNumber ip_number; | |
| 94 net::ParseIPLiteralToNumber("192.168.1.1", &ip_number); | |
| 95 net::IPEndPoint ip_endpoint(ip_number, 8009); | |
| 96 mock_cast_socket_ = new MockCastSocket(api, ip_endpoint, | |
| 97 &capturing_net_log_); | |
| 98 // Transfers ownership of the socket. | |
| 99 api->SetSocketForTest( | |
| 100 make_scoped_ptr<CastSocket>(mock_cast_socket_).Pass()); | |
| 101 | |
| 102 // Set expectations on error_state(). | |
| 103 EXPECT_CALL(*mock_cast_socket_, error_state()) | |
| 104 .WillRepeatedly(Return(cast_channel::CHANNEL_ERROR_NONE)); | |
| 105 } | |
| 106 | |
| 107 extensions::CastChannelAPI* GetApi() { | |
| 108 return extensions::CastChannelAPI::Get(profile()); | |
| 109 } | |
| 110 | |
| 111 void CallOnError(extensions::CastChannelAPI* api) { | |
| 112 api->OnError(mock_cast_socket_, | |
| 113 cast_channel::CHANNEL_ERROR_CONNECT_ERROR); | |
| 114 } | |
| 115 | |
| 116 protected: | |
| 117 void CallOnMessage(const std::string& message) { | |
| 118 content::BrowserThread::PostTask( | |
| 119 content::BrowserThread::IO, | |
| 120 FROM_HERE, | |
| 121 base::Bind(&CastChannelAPITest::DoCallOnMessage, this, | |
| 122 GetApi(), mock_cast_socket_, message)); | |
| 123 } | |
| 124 | |
| 125 void DoCallOnMessage(extensions::CastChannelAPI* api, | |
| 126 MockCastSocket* cast_socket, | |
| 127 const std::string& message) { | |
| 128 MessageInfo message_info; | |
| 129 FillMessageInfo(&message_info, message); | |
| 130 api->OnMessage(cast_socket, message_info); | |
| 131 } | |
| 132 | |
| 133 MockCastSocket* mock_cast_socket_; | |
| 134 net::CapturingNetLog capturing_net_log_; | |
| 135 }; | |
| 136 | |
| 137 // TODO(munjal): Win Dbg has a workaround that makes RunExtensionSubtest | |
| 138 // always return true without actually running the test. Remove when fixed. | |
| 139 #if defined(OS_WIN) && !defined(NDEBUG) | |
| 140 #define MAYBE_TestOpenSendClose DISABLED_TestOpenSendClose | |
| 141 #else | |
| 142 #define MAYBE_TestOpenSendClose TestOpenSendClose | |
| 143 #endif | |
| 144 // Test loading extension, opening a channel with ConnectInfo, adding a | |
| 145 // listener, writing, reading, and closing. | |
| 146 IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestOpenSendClose) { | |
| 147 SetUpMockCastSocket(); | |
| 148 | |
| 149 { | |
| 150 InSequence dummy; | |
| 151 EXPECT_CALL(*mock_cast_socket_, Connect(_)) | |
| 152 .WillOnce(InvokeCompletionCallback<0>(net::OK)); | |
| 153 EXPECT_CALL(*mock_cast_socket_, ready_state()) | |
| 154 .WillOnce(Return(cast_channel::READY_STATE_OPEN)); | |
| 155 EXPECT_CALL(*mock_cast_socket_, SendMessage(A<const MessageInfo&>(), _)) | |
| 156 .WillOnce(InvokeCompletionCallback<1>(net::OK)); | |
| 157 EXPECT_CALL(*mock_cast_socket_, ready_state()) | |
| 158 .WillOnce(Return(cast_channel::READY_STATE_OPEN)); | |
| 159 EXPECT_CALL(*mock_cast_socket_, Close(_)) | |
| 160 .WillOnce(InvokeCompletionCallback<0>(net::OK)); | |
| 161 EXPECT_CALL(*mock_cast_socket_, ready_state()) | |
| 162 .WillOnce(Return(cast_channel::READY_STATE_CLOSED)); | |
| 163 } | |
| 164 | |
| 165 EXPECT_TRUE(RunExtensionSubtest("cast_channel/api", | |
| 166 "test_open_send_close.html")); | |
| 167 } | |
| 168 | |
| 169 // TODO(munjal): Win Dbg has a workaround that makes RunExtensionSubtest | |
| 170 // always return true without actually running the test. Remove when fixed. | |
| 171 #if defined(OS_WIN) && !defined(NDEBUG) | |
| 172 #define MAYBE_TestOpenSendCloseWithUrl DISABLED_TestOpenSendCloseWithUrl | |
| 173 #else | |
| 174 #define MAYBE_TestOpenSendCloseWithUrl TestOpenSendCloseWithUrl | |
| 175 #endif | |
| 176 // Test loading extension, opening a channel with a URL, adding a listener, | |
| 177 // writing, reading, and closing. | |
| 178 IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestOpenSendCloseWithUrl) { | |
| 179 SetUpMockCastSocket(); | |
| 180 | |
| 181 { | |
| 182 InSequence dummy; | |
| 183 EXPECT_CALL(*mock_cast_socket_, Connect(_)) | |
| 184 .WillOnce(InvokeCompletionCallback<0>(net::OK)); | |
| 185 EXPECT_CALL(*mock_cast_socket_, ready_state()) | |
| 186 .WillOnce(Return(cast_channel::READY_STATE_OPEN)); | |
| 187 EXPECT_CALL(*mock_cast_socket_, SendMessage(A<const MessageInfo&>(), _)) | |
| 188 .WillOnce(InvokeCompletionCallback<1>(net::OK)); | |
| 189 EXPECT_CALL(*mock_cast_socket_, ready_state()) | |
| 190 .WillOnce(Return(cast_channel::READY_STATE_OPEN)); | |
| 191 EXPECT_CALL(*mock_cast_socket_, Close(_)) | |
| 192 .WillOnce(InvokeCompletionCallback<0>(net::OK)); | |
| 193 EXPECT_CALL(*mock_cast_socket_, ready_state()) | |
| 194 .WillOnce(Return(cast_channel::READY_STATE_CLOSED)); | |
| 195 } | |
| 196 | |
| 197 EXPECT_TRUE(RunExtensionSubtest("cast_channel/api", | |
| 198 "test_open_send_close_url.html")); | |
| 199 } | |
| 200 | |
| 201 // TODO(munjal): Win Dbg has a workaround that makes RunExtensionSubtest | |
| 202 // always return true without actually running the test. Remove when fixed. | |
| 203 #if defined(OS_WIN) && !defined(NDEBUG) | |
| 204 #define MAYBE_TestOpenReceiveClose DISABLED_TestOpenReceiveClose | |
| 205 #else | |
| 206 #define MAYBE_TestOpenReceiveClose TestOpenReceiveClose | |
| 207 #endif | |
| 208 // Test loading extension, opening a channel, adding a listener, | |
| 209 // writing, reading, and closing. | |
| 210 IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestOpenReceiveClose) { | |
| 211 SetUpMockCastSocket(); | |
| 212 | |
| 213 { | |
| 214 InSequence dummy; | |
| 215 EXPECT_CALL(*mock_cast_socket_, Connect(_)) | |
| 216 .WillOnce(InvokeCompletionCallback<0>(net::OK)); | |
| 217 EXPECT_CALL(*mock_cast_socket_, ready_state()) | |
| 218 .Times(3) | |
| 219 .WillRepeatedly(Return(cast_channel::READY_STATE_OPEN)); | |
| 220 EXPECT_CALL(*mock_cast_socket_, Close(_)) | |
| 221 .WillOnce(InvokeCompletionCallback<0>(net::OK)); | |
| 222 EXPECT_CALL(*mock_cast_socket_, ready_state()) | |
| 223 .WillOnce(Return(cast_channel::READY_STATE_CLOSED)); | |
| 224 } | |
| 225 | |
| 226 EXPECT_TRUE(RunExtensionSubtest("cast_channel/api", | |
| 227 "test_open_receive_close.html")); | |
| 228 | |
| 229 ResultCatcher catcher; | |
| 230 CallOnMessage("some-message"); | |
| 231 CallOnMessage("some-message"); | |
| 232 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); | |
| 233 } | |
| 234 | |
| 235 // TODO(munjal): Win Dbg has a workaround that makes RunExtensionSubtest | |
| 236 // always return true without actually running the test. Remove when fixed. | |
| 237 // Flaky on mac: crbug.com/393969 | |
| 238 #if (defined(OS_WIN) && !defined(NDEBUG)) || defined(OS_MACOSX) | |
| 239 #define MAYBE_TestOpenError DISABLED_TestOpenError | |
| 240 #else | |
| 241 #define MAYBE_TestOpenError TestOpenError | |
| 242 #endif | |
| 243 // Test the case when socket open results in an error. | |
| 244 IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestOpenError) { | |
| 245 SetUpMockCastSocket(); | |
| 246 | |
| 247 EXPECT_CALL(*mock_cast_socket_, Connect(_)) | |
| 248 .WillOnce(DoAll( | |
| 249 InvokeDelegateOnError(this, GetApi()), | |
| 250 InvokeCompletionCallback<0>(net::ERR_FAILED))); | |
| 251 EXPECT_CALL(*mock_cast_socket_, ready_state()) | |
| 252 .WillRepeatedly(Return(cast_channel::READY_STATE_CLOSED)); | |
| 253 EXPECT_CALL(*mock_cast_socket_, Close(_)); | |
| 254 | |
| 255 EXPECT_TRUE(RunExtensionSubtest("cast_channel/api", | |
| 256 "test_open_error.html")); | |
| 257 | |
| 258 ResultCatcher catcher; | |
| 259 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); | |
| 260 } | |
| 261 | |
| OLD | NEW |