This source file includes following definitions.
- ValidateHttpResponse
- Init
- RunTests
- TestBasic
- TestReadWrite
- TestReadWriteSSL
- TestConnectAddress
- TestSetOption
- TestLargeRead
- ReadFirstLineFromSocket
- WriteStringToSocket
#include "ppapi/tests/test_tcp_socket_private.h"
#include <stdlib.h>
#include <new>
#include "ppapi/cpp/private/tcp_socket_private.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h"
namespace {
bool ValidateHttpResponse(const std::string& s) {
return s.size() >= 5 &&
s.substr(0, 5) == "HTTP/" &&
s.substr(s.size() - 2) == "\r\n";
}
}
REGISTER_TEST_CASE(TCPSocketPrivate);
TestTCPSocketPrivate::TestTCPSocketPrivate(TestingInstance* instance)
: TestCase(instance) {
}
bool TestTCPSocketPrivate::Init() {
if (!pp::TCPSocketPrivate::IsAvailable())
return false;
if (!EnsureRunningOverHTTP())
return false;
if (!GetLocalHostPort(instance_->pp_instance(), &host_, &port_))
return false;
ssl_port_ = instance_->ssl_server_port();
return true;
}
void TestTCPSocketPrivate::RunTests(const std::string& filter) {
RUN_CALLBACK_TEST(TestTCPSocketPrivate, Basic, filter);
RUN_CALLBACK_TEST(TestTCPSocketPrivate, ReadWrite, filter);
RUN_CALLBACK_TEST(TestTCPSocketPrivate, ReadWriteSSL, filter);
RUN_CALLBACK_TEST(TestTCPSocketPrivate, ConnectAddress, filter);
RUN_CALLBACK_TEST(TestTCPSocketPrivate, SetOption, filter);
RUN_CALLBACK_TEST(TestTCPSocketPrivate, LargeRead, filter);
}
std::string TestTCPSocketPrivate::TestBasic() {
pp::TCPSocketPrivate socket(instance_);
TestCompletionCallback cb(instance_->pp_instance(), callback_type());
cb.WaitForResult(socket.Connect(host_.c_str(), port_, cb.GetCallback()));
CHECK_CALLBACK_BEHAVIOR(cb);
ASSERT_EQ(PP_OK, cb.result());
PP_NetAddress_Private unused;
ASSERT_TRUE(socket.GetLocalAddress(&unused));
ASSERT_TRUE(socket.GetRemoteAddress(&unused));
socket.Disconnect();
PASS();
}
std::string TestTCPSocketPrivate::TestReadWrite() {
pp::TCPSocketPrivate socket(instance_);
TestCompletionCallback cb(instance_->pp_instance(), callback_type());
cb.WaitForResult(socket.Connect(host_.c_str(), port_, cb.GetCallback()));
CHECK_CALLBACK_BEHAVIOR(cb);
ASSERT_EQ(PP_OK, cb.result());
ASSERT_EQ(PP_OK, WriteStringToSocket(&socket, "GET / HTTP/1.0\r\n\r\n"));
std::string s;
ASSERT_EQ(PP_OK, ReadFirstLineFromSocket(&socket, &s));
ASSERT_TRUE(ValidateHttpResponse(s));
socket.Disconnect();
PASS();
}
std::string TestTCPSocketPrivate::TestReadWriteSSL() {
pp::TCPSocketPrivate socket(instance_);
TestCompletionCallback cb(instance_->pp_instance(), callback_type());
cb.WaitForResult(socket.Connect(host_.c_str(), ssl_port_, cb.GetCallback()));
CHECK_CALLBACK_BEHAVIOR(cb);
ASSERT_EQ(PP_OK, cb.result());
cb.WaitForResult(
socket.SSLHandshake(host_.c_str(), ssl_port_, cb.GetCallback()));
CHECK_CALLBACK_BEHAVIOR(cb);
ASSERT_EQ(PP_OK, cb.result());
ASSERT_EQ(PP_OK, WriteStringToSocket(&socket, "GET / HTTP/1.0\r\n\r\n"));
std::string s;
ASSERT_EQ(PP_OK, ReadFirstLineFromSocket(&socket, &s));
ASSERT_TRUE(ValidateHttpResponse(s));
socket.Disconnect();
PASS();
}
std::string TestTCPSocketPrivate::TestConnectAddress() {
PP_NetAddress_Private address;
{
pp::TCPSocketPrivate socket(instance_);
TestCompletionCallback cb(instance_->pp_instance(), callback_type());
cb.WaitForResult(socket.Connect(host_.c_str(), port_, cb.GetCallback()));
CHECK_CALLBACK_BEHAVIOR(cb);
ASSERT_EQ(PP_OK, cb.result());
ASSERT_TRUE(socket.GetRemoteAddress(&address));
}
pp::TCPSocketPrivate socket(instance_);
TestCompletionCallback cb(instance_->pp_instance(), callback_type());
cb.WaitForResult(socket.ConnectWithNetAddress(&address, cb.GetCallback()));
CHECK_CALLBACK_BEHAVIOR(cb);
ASSERT_EQ(PP_OK, cb.result());
ASSERT_EQ(PP_OK, WriteStringToSocket(&socket, "GET / HTTP/1.0\r\n\r\n"));
std::string s;
ASSERT_EQ(PP_OK, ReadFirstLineFromSocket(&socket, &s));
ASSERT_TRUE(ValidateHttpResponse(s));
socket.Disconnect();
PASS();
}
std::string TestTCPSocketPrivate::TestSetOption() {
pp::TCPSocketPrivate socket(instance_);
TestCompletionCallback cb(instance_->pp_instance(), callback_type());
cb.WaitForResult(
socket.SetOption(PP_TCPSOCKETOPTION_PRIVATE_NO_DELAY, true,
cb.GetCallback()));
CHECK_CALLBACK_BEHAVIOR(cb);
ASSERT_EQ(PP_ERROR_FAILED, cb.result());
cb.WaitForResult(socket.Connect(host_.c_str(), port_, cb.GetCallback()));
CHECK_CALLBACK_BEHAVIOR(cb);
ASSERT_EQ(PP_OK, cb.result());
cb.WaitForResult(
socket.SetOption(PP_TCPSOCKETOPTION_PRIVATE_NO_DELAY, true,
cb.GetCallback()));
CHECK_CALLBACK_BEHAVIOR(cb);
ASSERT_EQ(PP_OK, cb.result());
cb.WaitForResult(
socket.SetOption(PP_TCPSOCKETOPTION_PRIVATE_INVALID, true,
cb.GetCallback()));
CHECK_CALLBACK_BEHAVIOR(cb);
ASSERT_EQ(PP_ERROR_BADARGUMENT, cb.result());
socket.Disconnect();
PASS();
}
std::string TestTCPSocketPrivate::TestLargeRead() {
pp::TCPSocketPrivate socket(instance_);
{
TestCompletionCallback cb(instance_->pp_instance(), callback_type());
cb.WaitForResult(socket.Connect(host_.c_str(), port_, cb.GetCallback()));
CHECK_CALLBACK_BEHAVIOR(cb);
ASSERT_EQ(PP_OK, cb.result());
}
ASSERT_EQ(PP_OK, WriteStringToSocket(&socket, "GET / HTTP/1.0\r\n\r\n"));
const size_t kReadSize = 1024 * 1024 + 32;
char* buffer = new (std::nothrow) char[kReadSize];
ASSERT_TRUE(buffer != NULL);
TestCompletionCallback cb(instance_->pp_instance(), callback_type());
cb.WaitForResult(socket.Read(buffer, kReadSize * sizeof(*buffer),
cb.GetCallback()));
CHECK_CALLBACK_BEHAVIOR(cb);
ASSERT_LE(0, cb.result());
delete [] buffer;
PASS();
}
int32_t TestTCPSocketPrivate::ReadFirstLineFromSocket(
pp::TCPSocketPrivate* socket,
std::string* s) {
char buffer[10000];
s->clear();
while (s->size() < 1000000) {
TestCompletionCallback cb(instance_->pp_instance(), callback_type());
int32_t rv = socket->Read(buffer, sizeof(buffer), cb.GetCallback());
if (callback_type() == PP_REQUIRED && rv != PP_OK_COMPLETIONPENDING)
return PP_ERROR_FAILED;
cb.WaitForResult(rv);
if (cb.result() < 0)
return cb.result();
if (cb.result() == 0)
return PP_ERROR_FAILED;
s->reserve(s->size() + cb.result());
for (int32_t i = 0; i < cb.result(); i++) {
s->push_back(buffer[i]);
if (buffer[i] == '\n')
return PP_OK;
}
}
return PP_ERROR_FAILED;
}
int32_t TestTCPSocketPrivate::WriteStringToSocket(pp::TCPSocketPrivate* socket,
const std::string& s) {
const char* buffer = s.data();
size_t written = 0;
while (written < s.size()) {
TestCompletionCallback cb(instance_->pp_instance(), callback_type());
int32_t rv = socket->Write(buffer + written, s.size() - written,
cb.GetCallback());
if (callback_type() == PP_REQUIRED && rv != PP_OK_COMPLETIONPENDING)
return PP_ERROR_FAILED;
cb.WaitForResult(rv);
if (cb.result() < 0)
return cb.result();
if (cb.result() == 0)
return PP_ERROR_FAILED;
written += cb.result();
}
if (written != s.size())
return PP_ERROR_FAILED;
return PP_OK;
}