Index: remoting/protocol/jingle_session_unittest.cc |
diff --git a/remoting/protocol/jingle_session_unittest.cc b/remoting/protocol/jingle_session_unittest.cc |
index 72fbb8b89637df148cac57af70b2de6edb18132e..8ca7dcf133b483635e76a7104672928ef9c9af19 100644 |
--- a/remoting/protocol/jingle_session_unittest.cc |
+++ b/remoting/protocol/jingle_session_unittest.cc |
@@ -3,31 +3,21 @@ |
// found in the LICENSE file. |
#include "base/bind.h" |
-#include "base/file_path.h" |
-#include "base/file_util.h" |
#include "base/message_loop_proxy.h" |
-#include "base/path_service.h" |
#include "base/time.h" |
-#include "base/test/test_timeouts.h" |
-#include "crypto/nss_util.h" |
-#include "crypto/rsa_private_key.h" |
-#include "net/base/completion_callback.h" |
-#include "net/base/io_buffer.h" |
-#include "net/base/net_errors.h" |
#include "net/socket/socket.h" |
#include "net/socket/stream_socket.h" |
#include "remoting/base/constants.h" |
-#include "remoting/protocol/auth_util.h" |
#include "remoting/protocol/authenticator.h" |
#include "remoting/protocol/channel_authenticator.h" |
+#include "remoting/protocol/connection_tester.h" |
+#include "remoting/protocol/fake_authenticator.h" |
#include "remoting/protocol/jingle_session.h" |
#include "remoting/protocol/jingle_session_manager.h" |
-#include "remoting/protocol/v1_authenticator.h" |
#include "remoting/jingle_glue/jingle_thread.h" |
#include "remoting/jingle_glue/fake_signal_strategy.h" |
#include "testing/gmock/include/gmock/gmock.h" |
#include "testing/gtest/include/gtest/gtest.h" |
-#include "third_party/libjingle/source/talk/p2p/client/basicportallocator.h" |
using testing::_; |
using testing::AtMost; |
@@ -36,6 +26,7 @@ using testing::DoAll; |
using testing::InSequence; |
using testing::Invoke; |
using testing::InvokeWithoutArgs; |
+using testing::Mock; |
using testing::Return; |
using testing::SaveArg; |
using testing::SetArgumentPointee; |
@@ -43,14 +34,6 @@ using testing::WithArg; |
namespace remoting { |
namespace protocol { |
-class JingleSessionTest; |
-} // namespace protocol |
-} // namespace remoting |
- |
-DISABLE_RUNNABLE_METHOD_REFCOUNT(remoting::protocol::JingleSessionTest); |
- |
-namespace remoting { |
-namespace protocol { |
namespace { |
@@ -58,41 +41,20 @@ namespace { |
// between messages (about 1 second for 100 messages). |
const int kMessageSize = 1024; |
const int kMessages = 100; |
-const int kTestDataSize = kMessages * kMessageSize; |
const int kUdpWriteDelayMs = 10; |
const char kChannelName[] = "test_channel"; |
const char kHostJid[] = "host1@gmail.com/123"; |
const char kClientJid[] = "host2@gmail.com/321"; |
-const char kTestHostPublicKey[] = |
- "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3nk/8ILc0JBqHgOS0UCOIl4m" |
- "0GUd2FIiZ/6Fc9D/iiyUgli+FIY5dwsrSoNJ87sYGifVDh8a5fdZNV5y58CcrapI5fJI" |
- "FpXviSW4g8d/t1gcZkoz1ppmjzbgXm6ckw9Td0yRD0cHu732Ijs+eo8wT0pt4KiHkbyR" |
- "iAvjrvkNDlfiEk7tiY7YzD9zTi3146GX6KLz5GQAd/3I8I5QW3ftF1s/m93AHuc383GZ" |
- "A78Oi+IbcJf/jJUZO119VNnRKGiPsf5GZIoHyXX8O5OUQk5soKdQPeK1FwWkeZu6fuXl" |
- "QoU12I6podD6xMFa/PA/xefMwcpmuWTRhcso9bp10zVFGQIDAQAB"; |
- |
-const char kTestSharedSecret[] = "1234-1234-5678"; |
-const char kTestSharedSecretBad[] = "0000-0000-0001"; |
- |
void QuitCurrentThread() { |
MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
} |
-void OnTimeoutTerminateThread(bool* timeout) { |
- *timeout = true; |
+ACTION(QuitThread) { |
QuitCurrentThread(); |
} |
-bool RunMessageLoopWithTimeout(int timeout_ms) { |
- bool timeout = false; |
- MessageLoop::current()->PostDelayedTask( |
- FROM_HERE, base::Bind(&OnTimeoutTerminateThread, &timeout), timeout_ms); |
- MessageLoop::current()->Run(); |
- return !timeout; |
-} |
- |
ACTION_P(QuitThreadOnCounter, counter) { |
(*counter)--; |
EXPECT_GE(*counter, 0); |
@@ -113,122 +75,14 @@ class MockSessionCallback { |
MOCK_METHOD1(OnStateChange, void(Session::State)); |
}; |
-class FakeChannelAuthenticator : public ChannelAuthenticator { |
+class MockStreamChannelCallback { |
public: |
- FakeChannelAuthenticator(bool accept) |
- : accept_(accept) { |
- } |
- virtual ~FakeChannelAuthenticator() {} |
- |
- virtual void SecureAndAuthenticate( |
- net::StreamSocket* socket, const DoneCallback& done_callback) OVERRIDE { |
- if (accept_) { |
- done_callback.Run(net::OK, socket); |
- } else { |
- delete socket; |
- done_callback.Run(net::ERR_FAILED, NULL); |
- } |
- } |
- |
- private: |
- bool accept_; |
- |
- DISALLOW_COPY_AND_ASSIGN(FakeChannelAuthenticator); |
+ MOCK_METHOD1(OnDone, void(net::StreamSocket* socket)); |
}; |
-class FakeClientAuthenticator : public Authenticator { |
+class MockDatagramChannelCallback { |
public: |
- FakeClientAuthenticator(bool accept, bool accept_channel) |
- : accept_(accept), |
- accept_channel_(accept_channel), |
- state_(MESSAGE_READY) { |
- } |
- virtual ~FakeClientAuthenticator() {} |
- |
- virtual State state() const OVERRIDE { |
- return state_; |
- } |
- |
- virtual void ProcessMessage(const buzz::XmlElement* message) OVERRIDE { |
- EXPECT_EQ(WAITING_MESSAGE, state_); |
- state_ = accept_ ? ACCEPTED : REJECTED; |
- } |
- |
- virtual buzz::XmlElement* GetNextMessage() OVERRIDE { |
- EXPECT_EQ(MESSAGE_READY, state_); |
- state_ = WAITING_MESSAGE; |
- return new buzz::XmlElement( |
- buzz::QName(kChromotingXmlNamespace, "authentication")); |
- } |
- |
- virtual ChannelAuthenticator* CreateChannelAuthenticator() const OVERRIDE { |
- return new FakeChannelAuthenticator(accept_channel_); |
- } |
- |
- protected: |
- bool accept_; |
- bool accept_channel_; |
- State state_; |
- |
- DISALLOW_COPY_AND_ASSIGN(FakeClientAuthenticator); |
-}; |
- |
-class FakeHostAuthenticator : public Authenticator { |
- public: |
- FakeHostAuthenticator(bool accept, bool accept_channel) |
- : accept_(accept), |
- accept_channel_(accept_channel), |
- state_(WAITING_MESSAGE) { |
- } |
- virtual ~FakeHostAuthenticator() {} |
- |
- virtual State state() const OVERRIDE { |
- return state_; |
- } |
- |
- virtual void ProcessMessage(const buzz::XmlElement* message) OVERRIDE { |
- EXPECT_EQ(WAITING_MESSAGE, state_); |
- state_ = MESSAGE_READY; |
- } |
- |
- virtual buzz::XmlElement* GetNextMessage() OVERRIDE { |
- EXPECT_EQ(MESSAGE_READY, state_); |
- state_ = accept_ ? ACCEPTED : REJECTED; |
- return new buzz::XmlElement( |
- buzz::QName(kChromotingXmlNamespace, "authentication")); |
- } |
- |
- virtual ChannelAuthenticator* CreateChannelAuthenticator() const OVERRIDE { |
- return new FakeChannelAuthenticator(accept_channel_); |
- } |
- |
- protected: |
- bool accept_; |
- bool accept_channel_; |
- State state_; |
- |
- DISALLOW_COPY_AND_ASSIGN(FakeHostAuthenticator); |
-}; |
- |
-class FakeHostAuthenticatorFactory : public AuthenticatorFactory { |
- public: |
- FakeHostAuthenticatorFactory(bool accept, bool accept_channel) |
- : accept_(accept), |
- accept_channel_(accept_channel) { |
- } |
- virtual ~FakeHostAuthenticatorFactory() {} |
- |
- virtual Authenticator* CreateAuthenticator( |
- const std::string& remote_jid, |
- const buzz::XmlElement* first_message) OVERRIDE { |
- return new FakeHostAuthenticator(accept_, accept_channel_); |
- } |
- |
- private: |
- bool accept_; |
- bool accept_channel_; |
- |
- DISALLOW_COPY_AND_ASSIGN(FakeHostAuthenticatorFactory); |
+ MOCK_METHOD1(OnDone, void(net::Socket* socket)); |
}; |
} // namespace |
@@ -260,38 +114,14 @@ class JingleSessionTest : public testing::Test { |
} |
void CloseSessions() { |
- if (host_session_.get()) { |
- host_session_->Close(); |
- host_session_.reset(); |
- } |
- if (client_session_.get()) { |
- client_session_->Close(); |
- client_session_.reset(); |
- } |
+ host_socket_.reset(); |
+ client_socket_.reset(); |
+ host_session_.reset(); |
+ client_session_.reset(); |
} |
- void CreateServerPair(bool use_fake_auth) { |
- FilePath certs_dir; |
- PathService::Get(base::DIR_SOURCE_ROOT, &certs_dir); |
- certs_dir = certs_dir.AppendASCII("net"); |
- certs_dir = certs_dir.AppendASCII("data"); |
- certs_dir = certs_dir.AppendASCII("ssl"); |
- certs_dir = certs_dir.AppendASCII("certificates"); |
- |
- FilePath cert_path = certs_dir.AppendASCII("unittest.selfsigned.der"); |
- std::string cert_der; |
- ASSERT_TRUE(file_util::ReadFileToString(cert_path, &cert_der)); |
- |
- FilePath key_path = certs_dir.AppendASCII("unittest.key.bin"); |
- std::string key_string; |
- ASSERT_TRUE(file_util::ReadFileToString(key_path, &key_string)); |
- std::vector<uint8> key_vector( |
- reinterpret_cast<const uint8*>(key_string.data()), |
- reinterpret_cast<const uint8*>(key_string.data() + |
- key_string.length())); |
- scoped_ptr<crypto::RSAPrivateKey> private_key( |
- crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_vector)); |
- |
+ void CreateServerPair(int auth_round_trips, |
+ FakeAuthenticator::Action auth_action) { |
host_signal_strategy_.reset(new FakeSignalStrategy(kHostJid)); |
client_signal_strategy_.reset(new FakeSignalStrategy(kClientJid)); |
FakeSignalStrategy::Connect(host_signal_strategy_.get(), |
@@ -304,14 +134,8 @@ class JingleSessionTest : public testing::Test { |
host_server_->Init( |
kHostJid, host_signal_strategy_.get(), &host_server_listener_, false); |
- if (use_fake_auth) { |
- host_server_->set_authenticator_factory( |
- new FakeHostAuthenticatorFactory(true, false)); |
- } else { |
- host_server_->set_authenticator_factory( |
- new V1HostAuthenticatorFactory( |
- cert_der, private_key.get(), kTestSharedSecret)); |
- } |
+ host_server_->set_authenticator_factory( |
+ new FakeHostAuthenticatorFactory(auth_round_trips, auth_action, true)); |
EXPECT_CALL(client_server_listener_, OnSessionManagerInitialized()) |
.Times(1); |
@@ -335,9 +159,9 @@ class JingleSessionTest : public testing::Test { |
client_signal_strategy_.reset(); |
} |
- bool InitiateConnection(bool use_fake_auth) { |
- int not_connected_peers = 2; |
- |
+ void InitiateConnection(int auth_round_trips, |
+ FakeAuthenticator::Action auth_action, |
+ bool expect_fail) { |
EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _)) |
.WillOnce(DoAll( |
WithArg<0>(Invoke( |
@@ -347,17 +171,18 @@ class JingleSessionTest : public testing::Test { |
{ |
InSequence dummy; |
- EXPECT_CALL(host_connection_callback_, |
- OnStateChange(Session::CONNECTED)) |
- .Times(1); |
- EXPECT_CALL(host_connection_callback_, |
- OnStateChange(Session::AUTHENTICATED)) |
- .Times(1) |
- .WillOnce(QuitThreadOnCounter(¬_connected_peers)); |
- // Expect that the connection will be closed eventually. |
- EXPECT_CALL(host_connection_callback_, |
- OnStateChange(Session::CLOSED)) |
- .Times(AtMost(1)); |
+ if (expect_fail) { |
+ EXPECT_CALL(host_connection_callback_, |
+ OnStateChange(Session::FAILED)) |
+ .Times(1); |
+ } else { |
+ EXPECT_CALL(host_connection_callback_, |
+ OnStateChange(Session::CONNECTED)) |
+ .Times(1); |
+ EXPECT_CALL(host_connection_callback_, |
+ OnStateChange(Session::AUTHENTICATED)) |
+ .Times(1); |
+ } |
} |
{ |
@@ -366,32 +191,76 @@ class JingleSessionTest : public testing::Test { |
EXPECT_CALL(client_connection_callback_, |
OnStateChange(Session::CONNECTING)) |
.Times(1); |
- EXPECT_CALL(client_connection_callback_, |
- OnStateChange(Session::CONNECTED)) |
- .Times(1); |
- EXPECT_CALL(client_connection_callback_, |
- OnStateChange(Session::AUTHENTICATED)) |
- .Times(1) |
- .WillOnce(QuitThreadOnCounter(¬_connected_peers)); |
- // Expect that the connection will be closed eventually. |
- EXPECT_CALL(client_connection_callback_, |
- OnStateChange(Session::CLOSED)) |
- .Times(AtMost(1)); |
+ if (expect_fail) { |
+ EXPECT_CALL(client_connection_callback_, |
+ OnStateChange(Session::FAILED)) |
+ .Times(1); |
+ } else { |
+ EXPECT_CALL(client_connection_callback_, |
+ OnStateChange(Session::CONNECTED)) |
+ .Times(1); |
+ EXPECT_CALL(client_connection_callback_, |
+ OnStateChange(Session::AUTHENTICATED)) |
+ .Times(1); |
+ } |
} |
- Authenticator* authenticator; |
- if (use_fake_auth) { |
- authenticator = new FakeClientAuthenticator(true, true); |
- } else { |
- authenticator = new V1ClientAuthenticator(kClientJid, kTestSharedSecret); |
- } |
+ Authenticator* authenticator = new FakeAuthenticator( |
+ FakeAuthenticator::CLIENT, auth_round_trips, auth_action, true); |
+ |
client_session_.reset(client_server_->Connect( |
kHostJid, authenticator, |
CandidateSessionConfig::CreateDefault(), |
base::Bind(&MockSessionCallback::OnStateChange, |
base::Unretained(&client_connection_callback_)))); |
- return RunMessageLoopWithTimeout(TestTimeouts::action_max_timeout_ms()); |
+ message_loop_.RunAllPending(); |
+ |
+ Mock::VerifyAndClearExpectations(&host_connection_callback_); |
+ Mock::VerifyAndClearExpectations(&client_connection_callback_); |
+ |
+ if (!expect_fail) { |
+ // Expect that the connection will be closed eventually. |
+ EXPECT_CALL(host_connection_callback_, |
+ OnStateChange(Session::CLOSED)) |
+ .Times(AtMost(1)); |
+ } |
+ |
+ if (!expect_fail) { |
+ // Expect that the connection will be closed eventually. |
+ EXPECT_CALL(client_connection_callback_, |
+ OnStateChange(Session::CLOSED)) |
+ .Times(AtMost(1)); |
+ } |
+ } |
+ |
+ void CreateChannel() { |
+ MockStreamChannelCallback client_callback; |
+ MockStreamChannelCallback host_callback; |
+ |
+ client_session_->CreateStreamChannel(kChannelName, base::Bind( |
+ &MockStreamChannelCallback::OnDone, |
+ base::Unretained(&host_callback))); |
+ host_session_->CreateStreamChannel(kChannelName, base::Bind( |
+ &MockStreamChannelCallback::OnDone, |
+ base::Unretained(&client_callback))); |
+ |
+ int counter = 2; |
+ net::StreamSocket* client_socket = NULL; |
+ net::StreamSocket* host_socket = NULL; |
+ EXPECT_CALL(client_callback, OnDone(_)) |
+ .WillOnce(DoAll(SaveArg<0>(&client_socket), |
+ QuitThreadOnCounter(&counter))); |
+ EXPECT_CALL(host_callback, OnDone(_)) |
+ .WillOnce(DoAll(SaveArg<0>(&host_socket), |
+ QuitThreadOnCounter(&counter))); |
+ message_loop_.Run(); |
+ |
+ ASSERT_TRUE(client_socket != NULL); |
+ ASSERT_TRUE(host_socket != NULL); |
+ |
+ client_socket_.reset(client_socket); |
+ host_socket_.reset(host_socket); |
} |
static void DoNothing() { } |
@@ -410,385 +279,20 @@ class JingleSessionTest : public testing::Test { |
MockSessionCallback host_connection_callback_; |
scoped_ptr<Session> client_session_; |
MockSessionCallback client_connection_callback_; |
-}; |
-class ChannelTesterBase : public base::RefCountedThreadSafe<ChannelTesterBase> { |
- public: |
- ChannelTesterBase(Session* host_session, |
- Session* client_session) |
- : host_session_(host_session), |
- client_session_(client_session), |
- done_(false) { |
- } |
- |
- virtual ~ChannelTesterBase() { } |
- |
- void Start() { |
- MessageLoop::current()->PostTask( |
- FROM_HERE, base::Bind(&ChannelTesterBase::DoStart, this)); |
- } |
- |
- bool WaitFinished() { |
- return RunMessageLoopWithTimeout(TestTimeouts::action_max_timeout_ms()); |
- } |
- |
- virtual void CheckResults() = 0; |
- |
- protected: |
- void DoStart() { |
- InitChannels(); |
- } |
- |
- virtual void InitChannels() = 0; |
- |
- void Done() { |
- done_ = true; |
- MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&QuitCurrentThread)); |
- } |
- |
- virtual void InitBuffers() = 0; |
- virtual void DoWrite() = 0; |
- virtual void DoRead() = 0; |
- |
- Session* host_session_; |
- Session* client_session_; |
- scoped_ptr<net::Socket> sockets_[2]; |
- bool done_; |
-}; |
- |
-class TCPChannelTester : public ChannelTesterBase { |
- public: |
- TCPChannelTester(Session* host_session, |
- Session* client_session, |
- int message_size, |
- int message_count) |
- : ChannelTesterBase(host_session, client_session), |
- write_errors_(0), |
- read_errors_(0), |
- message_size_(message_size), |
- message_count_(message_count), |
- test_data_size_(message_size * message_count) { |
- } |
- |
- virtual ~TCPChannelTester() { } |
- |
- virtual bool did_initialization_fail() { |
- return !sockets_[0].get() || !sockets_[1].get(); |
- } |
- |
- virtual void CheckResults() { |
- ASSERT_FALSE(did_initialization_fail()); |
- |
- EXPECT_EQ(0, write_errors_); |
- EXPECT_EQ(0, read_errors_); |
- |
- ASSERT_EQ(test_data_size_, input_buffer_->offset()); |
- |
- output_buffer_->SetOffset(0); |
- ASSERT_EQ(test_data_size_, output_buffer_->size()); |
- |
- EXPECT_EQ(0, memcmp(output_buffer_->data(), |
- input_buffer_->StartOfBuffer(), test_data_size_)); |
- } |
- |
- protected: |
- virtual void InitChannels() OVERRIDE { |
- host_session_->CreateStreamChannel( |
- kChannelName, |
- base::Bind(&TCPChannelTester::OnChannelReady, |
- base::Unretained(this), 0)); |
- client_session_->CreateStreamChannel( |
- kChannelName, |
- base::Bind(&TCPChannelTester::OnChannelReady, |
- base::Unretained(this), 1)); |
- } |
- |
- void OnChannelReady(int id, net::StreamSocket* socket) { |
- if (!socket) { |
- host_session_->CancelChannelCreation(kChannelName); |
- client_session_->CancelChannelCreation(kChannelName); |
- Done(); |
- return; |
- } |
- |
- DCHECK(id >= 0 && id < 2); |
- sockets_[id].reset(socket); |
- |
- if (sockets_[0].get() && sockets_[1].get()) { |
- InitBuffers(); |
- DoRead(); |
- DoWrite(); |
- } |
- } |
- |
- virtual void InitBuffers() { |
- output_buffer_ = new net::DrainableIOBuffer( |
- new net::IOBuffer(test_data_size_), test_data_size_); |
- memset(output_buffer_->data(), 123, test_data_size_); |
- |
- input_buffer_ = new net::GrowableIOBuffer(); |
- } |
- |
- virtual void DoWrite() { |
- int result = 1; |
- while (result > 0) { |
- if (output_buffer_->BytesRemaining() == 0) |
- break; |
- int bytes_to_write = std::min(output_buffer_->BytesRemaining(), |
- message_size_); |
- result = sockets_[0]->Write(output_buffer_, bytes_to_write, |
- base::Bind(&TCPChannelTester::OnWritten, |
- base::Unretained(this))); |
- HandleWriteResult(result); |
- }; |
- } |
- |
- void OnWritten(int result) { |
- HandleWriteResult(result); |
- DoWrite(); |
- } |
- |
- void HandleWriteResult(int result) { |
- if (result <= 0 && result != net::ERR_IO_PENDING) { |
- LOG(ERROR) << "Received error " << result << " when trying to write"; |
- write_errors_++; |
- Done(); |
- } else if (result > 0) { |
- output_buffer_->DidConsume(result); |
- } |
- } |
- |
- virtual void DoRead() { |
- int result = 1; |
- while (result > 0) { |
- input_buffer_->SetCapacity(input_buffer_->offset() + message_size_); |
- result = sockets_[1]->Read(input_buffer_, message_size_, |
- base::Bind(&TCPChannelTester::OnRead, |
- base::Unretained(this))); |
- HandleReadResult(result); |
- }; |
- } |
- |
- void OnRead(int result) { |
- HandleReadResult(result); |
- if (!done_) |
- DoRead(); // Don't try to read again when we are done reading. |
- } |
- |
- void HandleReadResult(int result) { |
- if (result <= 0 && result != net::ERR_IO_PENDING) { |
- if (!done_) { |
- LOG(ERROR) << "Received error " << result << " when trying to read"; |
- read_errors_++; |
- Done(); |
- } |
- } else if (result > 0) { |
- // Allocate memory for the next read. |
- input_buffer_->set_offset(input_buffer_->offset() + result); |
- if (input_buffer_->offset() == test_data_size_) |
- Done(); |
- } |
- } |
- |
- scoped_refptr<net::DrainableIOBuffer> output_buffer_; |
- scoped_refptr<net::GrowableIOBuffer> input_buffer_; |
- |
- int write_errors_; |
- int read_errors_; |
- int message_size_; |
- int message_count_; |
- int test_data_size_; |
-}; |
- |
-class ChannelSpeedTester : public TCPChannelTester { |
- public: |
- ChannelSpeedTester(Session* host_session, |
- Session* client_session, |
- int message_size) |
- : TCPChannelTester(host_session, client_session, message_size, 1) { |
- CHECK(message_size >= 8); |
- } |
- |
- virtual ~ChannelSpeedTester() { } |
- |
- virtual void CheckResults() { |
- } |
- |
- base::TimeDelta GetElapsedTime() { |
- return base::Time::Now() - start_time_; |
- } |
- |
- protected: |
- virtual void InitBuffers() { |
- TCPChannelTester::InitBuffers(); |
- |
- start_time_ = base::Time::Now(); |
- } |
- |
- base::Time start_time_; |
-}; |
- |
-class UDPChannelTester : public ChannelTesterBase { |
- public: |
- UDPChannelTester(Session* host_session, |
- Session* client_session) |
- : ChannelTesterBase(host_session, client_session), |
- write_errors_(0), |
- read_errors_(0), |
- packets_sent_(0), |
- packets_received_(0), |
- broken_packets_(0) { |
- } |
- |
- virtual ~UDPChannelTester() { } |
- |
- virtual void CheckResults() { |
- EXPECT_EQ(0, write_errors_); |
- EXPECT_EQ(0, read_errors_); |
- |
- EXPECT_EQ(0, broken_packets_); |
- |
- // Verify that we've received at least one packet. |
- EXPECT_GT(packets_received_, 0); |
- LOG(INFO) << "Received " << packets_received_ << " packets out of " |
- << kMessages; |
- } |
- |
- protected: |
- virtual void InitChannels() OVERRIDE { |
- host_session_->CreateDatagramChannel( |
- kChannelName, |
- base::Bind(&UDPChannelTester::OnChannelReady, |
- base::Unretained(this), 0)); |
- client_session_->CreateDatagramChannel( |
- kChannelName, |
- base::Bind(&UDPChannelTester::OnChannelReady, |
- base::Unretained(this), 1)); |
- } |
- |
- void OnChannelReady(int id, net::Socket* socket) { |
- ASSERT_TRUE(socket); |
- if (!socket) { |
- Done(); |
- return; |
- } |
- |
- DCHECK(id >= 0 && id < 2); |
- sockets_[id].reset(socket); |
- |
- if (sockets_[0].get() && sockets_[1].get()) { |
- InitBuffers(); |
- DoRead(); |
- DoWrite(); |
- } |
- } |
- |
- |
- virtual void InitBuffers() { |
- } |
- |
- virtual void DoWrite() { |
- if (packets_sent_ >= kMessages) { |
- Done(); |
- return; |
- } |
- |
- scoped_refptr<net::IOBuffer> packet(new net::IOBuffer(kMessageSize)); |
- memset(packet->data(), 123, kMessageSize); |
- sent_packets_[packets_sent_] = packet; |
- // Put index of this packet in the beginning of the packet body. |
- memcpy(packet->data(), &packets_sent_, sizeof(packets_sent_)); |
- |
- int result = sockets_[0]->Write(packet, kMessageSize, |
- base::Bind(&UDPChannelTester::OnWritten, |
- base::Unretained(this))); |
- HandleWriteResult(result); |
- } |
- |
- void OnWritten(int result) { |
- HandleWriteResult(result); |
- } |
- |
- void HandleWriteResult(int result) { |
- if (result <= 0 && result != net::ERR_IO_PENDING) { |
- LOG(ERROR) << "Received error " << result << " when trying to write"; |
- write_errors_++; |
- Done(); |
- } else if (result > 0) { |
- EXPECT_EQ(kMessageSize, result); |
- packets_sent_++; |
- MessageLoop::current()->PostDelayedTask( |
- FROM_HERE, base::Bind(&UDPChannelTester::DoWrite, this), |
- kUdpWriteDelayMs); |
- } |
- } |
- |
- virtual void DoRead() { |
- int result = 1; |
- while (result > 0) { |
- int kReadSize = kMessageSize * 2; |
- read_buffer_ = new net::IOBuffer(kReadSize); |
- |
- result = sockets_[1]->Read(read_buffer_, kReadSize, |
- base::Bind(&UDPChannelTester::OnRead, |
- base::Unretained(this))); |
- HandleReadResult(result); |
- }; |
- } |
- |
- void OnRead(int result) { |
- HandleReadResult(result); |
- DoRead(); |
- } |
- |
- void HandleReadResult(int result) { |
- if (result <= 0 && result != net::ERR_IO_PENDING) { |
- // Error will be received after the socket is closed. |
- if (!done_) { |
- LOG(ERROR) << "Received error " << result << " when trying to read"; |
- read_errors_++; |
- Done(); |
- } |
- } else if (result > 0) { |
- packets_received_++; |
- if (kMessageSize != result) { |
- // Invalid packet size; |
- broken_packets_++; |
- } else { |
- // Validate packet body. |
- int packet_id; |
- memcpy(&packet_id, read_buffer_->data(), sizeof(packet_id)); |
- if (packet_id < 0 || packet_id >= kMessages) { |
- broken_packets_++; |
- } else { |
- if (memcmp(read_buffer_->data(), sent_packets_[packet_id]->data(), |
- kMessageSize) != 0) |
- broken_packets_++; |
- } |
- } |
- } |
- } |
- |
- private: |
- scoped_refptr<net::IOBuffer> sent_packets_[kMessages]; |
- scoped_refptr<net::IOBuffer> read_buffer_; |
- |
- int write_errors_; |
- int read_errors_; |
- int packets_sent_; |
- int packets_received_; |
- int broken_packets_; |
+ scoped_ptr<net::StreamSocket> client_socket_; |
+ scoped_ptr<net::StreamSocket> host_socket_; |
}; |
// Verify that we can create and destory server objects without a connection. |
TEST_F(JingleSessionTest, CreateAndDestoy) { |
- CreateServerPair(false); |
+ CreateServerPair(1, FakeAuthenticator::ACCEPT); |
} |
// Verify that incoming session can be rejected, and that the status |
// of the connection is set to CLOSED in this case. |
TEST_F(JingleSessionTest, RejectConnection) { |
- CreateServerPair(false); |
+ CreateServerPair(1, FakeAuthenticator::ACCEPT); |
// Reject incoming session. |
EXPECT_CALL(host_server_listener_, OnIncomingSession(_, _)) |
@@ -801,117 +305,114 @@ TEST_F(JingleSessionTest, RejectConnection) { |
OnStateChange(Session::CONNECTING)) |
.Times(1); |
EXPECT_CALL(client_connection_callback_, |
- OnStateChange(Session::CLOSED)) |
- .Times(1) |
- .WillOnce(InvokeWithoutArgs(&QuitCurrentThread)); |
+ OnStateChange(Session::FAILED)) |
+ .Times(1); |
} |
- Authenticator* authenticator = |
- new V1ClientAuthenticator(kClientJid, kTestSharedSecretBad); |
+ Authenticator* authenticator = new FakeAuthenticator( |
+ FakeAuthenticator::CLIENT, 1, FakeAuthenticator::ACCEPT, true); |
client_session_.reset(client_server_->Connect( |
kHostJid, authenticator, |
CandidateSessionConfig::CreateDefault(), |
base::Bind(&MockSessionCallback::OnStateChange, |
base::Unretained(&client_connection_callback_)))); |
- ASSERT_TRUE(RunMessageLoopWithTimeout(TestTimeouts::action_max_timeout_ms())); |
+ message_loop_.RunAllPending(); |
} |
// Verify that we can connect two endpoints. |
TEST_F(JingleSessionTest, Connect) { |
- CreateServerPair(false); |
- ASSERT_TRUE(InitiateConnection(false)); |
+ CreateServerPair(1, FakeAuthenticator::ACCEPT); |
+ InitiateConnection(1, FakeAuthenticator::ACCEPT, false); |
} |
// Verify that we can't connect two endpoints with mismatched secrets. |
+TEST_F(JingleSessionTest, ConnectBadAuth) { |
+ CreateServerPair(1, FakeAuthenticator::REJECT); |
+ InitiateConnection(1, FakeAuthenticator::ACCEPT, true); |
+} |
+ |
TEST_F(JingleSessionTest, ConnectBadChannelAuth) { |
- CreateServerPair(true); |
- ASSERT_TRUE(InitiateConnection(true)); |
- scoped_refptr<TCPChannelTester> tester( |
- new TCPChannelTester(host_session_.get(), client_session_.get(), |
- kMessageSize, kMessages)); |
- tester->Start(); |
- ASSERT_TRUE(tester->WaitFinished()); |
- EXPECT_TRUE(tester->did_initialization_fail()); |
- |
- CloseSessions(); |
+ CreateServerPair(1, FakeAuthenticator::REJECT_CHANNEL); |
+ ASSERT_NO_FATAL_FAILURE( |
+ InitiateConnection(1, FakeAuthenticator::ACCEPT, false)); |
+ |
+ MockStreamChannelCallback client_callback; |
+ MockStreamChannelCallback host_callback; |
+ |
+ client_session_->CreateStreamChannel(kChannelName, base::Bind( |
+ &MockStreamChannelCallback::OnDone, |
+ base::Unretained(&client_callback))); |
+ host_session_->CreateStreamChannel(kChannelName, base::Bind( |
+ &MockStreamChannelCallback::OnDone, |
+ base::Unretained(&host_callback))); |
+ |
+ EXPECT_CALL(client_callback, OnDone(_)) |
+ .Times(AtMost(1)) |
+ .WillOnce(DeleteArg<0>()); |
+ EXPECT_CALL(host_callback, OnDone(NULL)) |
+ .WillOnce(QuitThread()); |
+ |
+ message_loop_.Run(); |
+ |
+ client_session_->CancelChannelCreation(kChannelName); |
+ host_session_->CancelChannelCreation(kChannelName); |
} |
// Verify that data can be transmitted over the event channel. |
TEST_F(JingleSessionTest, TestTcpChannel) { |
- CreateServerPair(false); |
- ASSERT_TRUE(InitiateConnection(false)); |
- scoped_refptr<TCPChannelTester> tester( |
- new TCPChannelTester(host_session_.get(), client_session_.get(), |
- kMessageSize, kMessages)); |
- tester->Start(); |
- ASSERT_TRUE(tester->WaitFinished()); |
- tester->CheckResults(); |
- |
- // Connections must be closed while |tester| still exists. |
- CloseSessions(); |
+ CreateServerPair(1, FakeAuthenticator::ACCEPT); |
+ ASSERT_NO_FATAL_FAILURE( |
+ InitiateConnection(1, FakeAuthenticator::ACCEPT, false)); |
+ |
+ ASSERT_NO_FATAL_FAILURE(CreateChannel()); |
+ |
+ StreamConnectionTester tester(host_socket_.get(), client_socket_.get(), |
+ kMessageSize, kMessages); |
+ tester.Start(); |
+ message_loop_.Run(); |
+ tester.CheckResults(); |
} |
// Verify that data can be transmitted over the video RTP channel. |
TEST_F(JingleSessionTest, TestUdpChannel) { |
- CreateServerPair(false); |
- ASSERT_TRUE(InitiateConnection(false)); |
- scoped_refptr<UDPChannelTester> tester( |
- new UDPChannelTester(host_session_.get(), client_session_.get())); |
- tester->Start(); |
- ASSERT_TRUE(tester->WaitFinished()); |
- tester->CheckResults(); |
- |
- // Connections must be closed while |tester| still exists. |
- CloseSessions(); |
-} |
- |
-// Send packets of different size to get the latency for sending data |
-// using sockets from JingleSession. |
-TEST_F(JingleSessionTest, FLAKY_TestSpeed) { |
- CreateServerPair(false); |
- ASSERT_TRUE(InitiateConnection(false)); |
- scoped_refptr<ChannelSpeedTester> tester; |
- |
- tester = new ChannelSpeedTester(host_session_.get(), |
- client_session_.get(), 512); |
- tester->Start(); |
- ASSERT_TRUE(tester->WaitFinished()); |
- LOG(INFO) << "Time for 512 bytes " |
- << tester->GetElapsedTime().InMilliseconds() << " ms."; |
- |
- CloseSessions(); |
- ASSERT_TRUE(InitiateConnection(false)); |
- |
- tester = new ChannelSpeedTester(host_session_.get(), |
- client_session_.get(), 1024); |
- tester->Start(); |
- ASSERT_TRUE(tester->WaitFinished()); |
- LOG(INFO) << "Time for 1024 bytes " |
- << tester->GetElapsedTime().InMilliseconds() << " ms."; |
- |
- CloseSessions(); |
- ASSERT_TRUE(InitiateConnection(false)); |
- |
- tester = new ChannelSpeedTester(host_session_.get(), |
- client_session_.get(), 51200); |
- tester->Start(); |
- ASSERT_TRUE(tester->WaitFinished()); |
- LOG(INFO) << "Time for 50k bytes " |
- << tester->GetElapsedTime().InMilliseconds() << " ms."; |
- |
- CloseSessions(); |
- ASSERT_TRUE(InitiateConnection(false)); |
- |
- tester = new ChannelSpeedTester(host_session_.get(), |
- client_session_.get(), 512000); |
- tester->Start(); |
- ASSERT_TRUE(tester->WaitFinished()); |
- LOG(INFO) << "Time for 500k bytes " |
- << tester->GetElapsedTime().InMilliseconds() << " ms."; |
- |
- // Connections must be closed while |tester| still exists. |
- CloseSessions(); |
+ CreateServerPair(1, FakeAuthenticator::ACCEPT); |
+ ASSERT_NO_FATAL_FAILURE( |
+ InitiateConnection(1, FakeAuthenticator::ACCEPT, false)); |
+ |
+ MockDatagramChannelCallback client_callback; |
+ MockDatagramChannelCallback host_callback; |
+ |
+ int counter = 2; |
+ net::Socket* client_socket = NULL; |
+ net::Socket* host_socket = NULL; |
+ EXPECT_CALL(client_callback, OnDone(_)) |
+ .WillOnce(DoAll(SaveArg<0>(&client_socket), |
+ QuitThreadOnCounter(&counter))); |
+ EXPECT_CALL(host_callback, OnDone(_)) |
+ .WillOnce(DoAll(SaveArg<0>(&host_socket), |
+ QuitThreadOnCounter(&counter))); |
+ |
+ client_session_->CreateDatagramChannel(kChannelName, base::Bind( |
+ &MockDatagramChannelCallback::OnDone, |
+ base::Unretained(&host_callback))); |
+ host_session_->CreateDatagramChannel(kChannelName, base::Bind( |
+ &MockDatagramChannelCallback::OnDone, |
+ base::Unretained(&client_callback))); |
+ |
+ message_loop_.Run(); |
+ |
+ scoped_ptr<net::Socket> client_socket_ptr(client_socket); |
+ scoped_ptr<net::Socket> host_socket_ptr(host_socket); |
+ |
+ ASSERT_TRUE(client_socket != NULL); |
+ ASSERT_TRUE(host_socket != NULL); |
+ |
+ DatagramConnectionTester tester( |
+ client_socket, host_socket, kMessageSize, kMessages, kUdpWriteDelayMs); |
+ tester.Start(); |
+ message_loop_.Run(); |
+ tester.CheckResults(); |
} |
} // namespace protocol |