Pepper: Add a test for PPB_TCPSocket_Private.

Actually, the interface is currently known as PPB_Flash_TCPSocket.

BUG=103993
TEST=ui_tests OutOfProcessPPAPITest.TCPSocketPrivate
TBR=dmichael@chromium.org

Review URL: http://codereview.chromium.org/8564034

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110026 0039d316-1c4b-4281-b951-d872f2087c98
parent b70a4a2b
......@@ -311,3 +311,8 @@ TEST_F(OutOfProcessPPAPITest, FAILS_UMA) {
TEST_PPAPI_IN_PROCESS(NetAddressPrivate)
TEST_PPAPI_OUT_OF_PROCESS(NetAddressPrivate)
// PPB_TCPSocket_Private currently isn't supported in-process.
TEST_F(OutOfProcessPPAPITest, TCPSocketPrivate) {
RunTestViaHTTP("TCPSocketPrivate");
}
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// TODO(yzshen): See the comment in corresponding .h file.
#include "ppapi/cpp/private/flash_tcp_socket.h"
#include "ppapi/c/pp_bool.h"
......@@ -32,6 +30,11 @@ TCPSocket::TCPSocket(Instance* instance) {
}
}
// static
bool TCPSocket::IsAvailable() {
return has_interface<PPB_Flash_TCPSocket>();
}
int32_t TCPSocket::Connect(const char* host,
uint16_t port,
const CompletionCallback& callback) {
......
......@@ -2,10 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// TODO(yzshen): This (and the .cc file) contain C++ wrappers for things
// in ppapi/c/private/ppb_flash_tcp_socket.h. This is currently not used in
// (or even compiled with) Chromium.
#ifndef PPAPI_CPP_PRIVATE_FLASH_TCP_SOCKET_H_
#define PPAPI_CPP_PRIVATE_FLASH_TCP_SOCKET_H_
......@@ -24,6 +20,9 @@ class TCPSocket : public Resource {
public:
explicit TCPSocket(Instance* instance);
// Returns true if the required interface is available.
static bool IsAvailable();
int32_t Connect(const char* host,
uint16_t port,
const CompletionCallback& callback);
......
......@@ -249,6 +249,8 @@
# Private interfaces.
'cpp/private/flash_fullscreen.cc',
'cpp/private/flash_fullscreen.h',
'cpp/private/flash_tcp_socket.cc',
'cpp/private/flash_tcp_socket.h',
'cpp/private/instance_private.cc',
'cpp/private/instance_private.h',
'cpp/private/net_address_private.cc',
......
......@@ -121,6 +121,8 @@
'tests/test_scrollbar.cc',
'tests/test_scrollbar.h',
'tests/test_struct_sizes.c',
'tests/test_tcp_socket_private.cc',
'tests/test_tcp_socket_private.h',
'tests/test_uma.cc',
'tests/test_uma.h',
'tests/test_url_loader.cc',
......
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ppapi/tests/test_tcp_socket_private.h"
#include <stdlib.h>
#include "base/string_split.h"
#include "ppapi/c/dev/ppb_url_util_dev.h"
#include "ppapi/cpp/dev/url_util_dev.h"
#include "ppapi/cpp/private/flash_tcp_socket.h"
#include "ppapi/cpp/var.h"
#include "ppapi/tests/testing_instance.h"
#include "ppapi/tests/test_utils.h"
namespace {
// Validates the first line of an HTTP response.
bool ValidateHttpResponse(const std::string& s) {
// Just check that it begins with "HTTP/" and ends with a "\r\n".
return s.size() >= 5 &&
s.substr(0, 5) == "HTTP/" &&
s.substr(s.size() - 2) == "\r\n";
}
} // namespace
REGISTER_TEST_CASE(TCPSocketPrivate);
TestTCPSocketPrivate::TestTCPSocketPrivate(TestingInstance* instance)
: TestCase(instance) {
}
bool TestTCPSocketPrivate::Init() {
if (!TCPSocketPrivate::IsAvailable())
return false;
// This test currently only works out-of-process (since the API is really only
// implemented in that case).
const PPB_Testing_Dev* testing = GetTestingInterface();
if (!testing)
return false;
if (!testing->IsOutOfProcess())
return false;
// We need something to connect to, so we connect to the HTTP server whence we
// came. Grab the host and port.
if (!EnsureRunningOverHTTP())
return false;
PP_URLComponents_Dev components;
pp::Var pp_url = pp::URLUtil_Dev::Get()->GetDocumentURL(*instance_,
&components);
if (!pp_url.is_string())
return false;
std::string url = pp_url.AsString();
// Double-check that we're running on HTTP.
if (components.scheme.len < 0)
return false;
if (url.substr(components.scheme.begin, components.scheme.len) != "http")
return false;
// Get host.
if (components.host.len < 0)
return false;
host_ = url.substr(components.host.begin, components.host.len);
// Get port (it's optional).
port_ = 80; // Default value.
if (components.port.len > 0) {
int i = atoi(url.substr(components.port.begin,
components.port.len).c_str());
if (i < 0 || i > 65535)
return false;
port_ = static_cast<uint16_t>(i);
}
return true;
}
void TestTCPSocketPrivate::RunTest() {
RUN_TEST_FORCEASYNC_AND_NOT(Basic);
RUN_TEST_FORCEASYNC_AND_NOT(ReadWrite);
RUN_TEST_FORCEASYNC_AND_NOT(ConnectAddress);
}
std::string TestTCPSocketPrivate::TestBasic() {
TCPSocketPrivate socket(instance_);
TestCompletionCallback cb(instance_->pp_instance(), force_async_);
int32_t rv = socket.Connect(host_.c_str(), port_, cb);
ASSERT_TRUE(!force_async_ || rv == PP_OK_COMPLETIONPENDING);
if (rv == PP_OK_COMPLETIONPENDING)
rv = cb.WaitForResult();
ASSERT_EQ(PP_OK, rv);
PP_NetAddress_Private unused;
// TODO(viettrungluu): check the values somehow.
ASSERT_TRUE(socket.GetLocalAddress(&unused));
ASSERT_TRUE(socket.GetRemoteAddress(&unused));
socket.Disconnect();
PASS();
}
std::string TestTCPSocketPrivate::TestReadWrite() {
TCPSocketPrivate socket(instance_);
TestCompletionCallback cb(instance_->pp_instance(), force_async_);
int32_t rv = socket.Connect(host_.c_str(), port_, cb);
ASSERT_TRUE(!force_async_ || rv == PP_OK_COMPLETIONPENDING);
if (rv == PP_OK_COMPLETIONPENDING)
rv = cb.WaitForResult();
ASSERT_EQ(PP_OK, rv);
ASSERT_EQ(PP_OK, WriteStringToSocket(&socket, "GET / HTTP/1.0\r\n\r\n"));
// Read up to the first \n and check that it looks like valid HTTP response.
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;
// First, bring up a connection and grab the address.
{
TCPSocketPrivate socket(instance_);
TestCompletionCallback cb(instance_->pp_instance(), force_async_);
int32_t rv = socket.Connect(host_.c_str(), port_, cb);
ASSERT_TRUE(!force_async_ || rv == PP_OK_COMPLETIONPENDING);
if (rv == PP_OK_COMPLETIONPENDING)
rv = cb.WaitForResult();
ASSERT_EQ(PP_OK, rv);
ASSERT_TRUE(socket.GetRemoteAddress(&address));
// Omit the |Disconnect()| here to make sure we don't crash if we just let
// the resource be destroyed.
}
// Connect to that address.
TCPSocketPrivate socket(instance_);
TestCompletionCallback cb(instance_->pp_instance(), force_async_);
int32_t rv = socket.ConnectWithNetAddress(&address, cb);
ASSERT_TRUE(!force_async_ || rv == PP_OK_COMPLETIONPENDING);
if (rv == PP_OK_COMPLETIONPENDING)
rv = cb.WaitForResult();
ASSERT_EQ(PP_OK, rv);
// Make sure we can read/write to it properly (see |TestReadWrite()|).
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();
}
// TODO(viettrungluu): Try testing SSL somehow.
int32_t TestTCPSocketPrivate::ReadFirstLineFromSocket(TCPSocketPrivate* socket,
std::string* s) {
char buffer[10000];
s->clear();
// Make sure we don't just hang if |Read()| spews.
while (s->size() < 1000000) {
TestCompletionCallback cb(instance_->pp_instance(), force_async_);
int32_t rv = socket->Read(buffer, sizeof(buffer), cb);
if (force_async_ && rv != PP_OK_COMPLETIONPENDING)
return PP_ERROR_FAILED;
if (rv == PP_OK_COMPLETIONPENDING)
rv = cb.WaitForResult();
if (rv < 0)
return rv;
if (rv == 0)
return PP_ERROR_FAILED; // Didn't get a \n-terminated line.
s->reserve(s->size() + rv);
for (int32_t i = 0; i < rv; i++) {
s->push_back(buffer[i]);
if (buffer[i] == '\n')
return PP_OK;
}
}
return PP_ERROR_FAILED;
}
int32_t TestTCPSocketPrivate::WriteStringToSocket(TCPSocketPrivate* socket,
const std::string& s) {
const char* buffer = s.data();
size_t written = 0;
while (written < s.size()) {
TestCompletionCallback cb(instance_->pp_instance(), force_async_);
int32_t rv = socket->Write(buffer + written, s.size() - written, cb);
if (force_async_ && rv != PP_OK_COMPLETIONPENDING)
return PP_ERROR_FAILED;
if (rv == PP_OK_COMPLETIONPENDING)
rv = cb.WaitForResult();
if (rv < 0)
return rv;
if (rv == 0)
return PP_ERROR_FAILED;
written += rv;
}
if (written != s.size())
return PP_ERROR_FAILED;
return PP_OK;
}
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef PAPPI_TESTS_TEST_TCP_SOCKET_PRIVATE_H_
#define PAPPI_TESTS_TEST_TCP_SOCKET_PRIVATE_H_
#include <string>
#include "ppapi/c/pp_stdint.h"
#include "ppapi/tests/test_case.h"
// TODO(viettrungluu): A rename is in progress and this reduces the amount of
// code that'll have to be changed.
namespace pp {
namespace flash {
class TCPSocket;
}
}
typedef pp::flash::TCPSocket TCPSocketPrivate;
class TestTCPSocketPrivate : public TestCase {
public:
explicit TestTCPSocketPrivate(TestingInstance* instance);
// TestCase implementation.
virtual bool Init();
virtual void RunTest();
private:
std::string TestBasic();
std::string TestReadWrite();
std::string TestConnectAddress();
int32_t ReadFirstLineFromSocket(TCPSocketPrivate* socket, std::string* s);
int32_t WriteStringToSocket(TCPSocketPrivate* socket, const std::string& s);
std::string host_;
uint16_t port_;
};
#endif // PAPPI_TESTS_TEST_TCP_SOCKET_PRIVATE_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment