Drive: Add BatchableRequest subclass.
[chromium-blink-merge.git] / ppapi / tests / test_tcp_socket_private.cc
blob0d43a764c304958d80380138cbf68c5bffe54f4d
1 // Copyright (c) 2012 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.
5 #include "ppapi/tests/test_tcp_socket_private.h"
7 #include <stdlib.h>
9 #include <new>
11 #include "ppapi/cpp/private/tcp_socket_private.h"
12 #include "ppapi/tests/test_utils.h"
13 #include "ppapi/tests/testing_instance.h"
15 namespace {
17 // Validates the first line of an HTTP response.
18 bool ValidateHttpResponse(const std::string& s) {
19 // Just check that it begins with "HTTP/" and ends with a "\r\n".
20 return s.size() >= 5 &&
21 s.substr(0, 5) == "HTTP/" &&
22 s.substr(s.size() - 2) == "\r\n";
25 } // namespace
27 REGISTER_TEST_CASE(TCPSocketPrivate);
29 TestTCPSocketPrivate::TestTCPSocketPrivate(TestingInstance* instance)
30 : TestCase(instance) {
33 bool TestTCPSocketPrivate::Init() {
34 if (!pp::TCPSocketPrivate::IsAvailable())
35 return false;
37 // We need something to connect to, so we connect to the HTTP server whence we
38 // came. Grab the host and port.
39 if (!EnsureRunningOverHTTP())
40 return false;
42 if (!GetLocalHostPort(instance_->pp_instance(), &host_, &port_))
43 return false;
45 // Get the port for the SSL server.
46 ssl_port_ = instance_->ssl_server_port();
48 return true;
51 void TestTCPSocketPrivate::RunTests(const std::string& filter) {
52 RUN_CALLBACK_TEST(TestTCPSocketPrivate, Basic, filter);
53 RUN_CALLBACK_TEST(TestTCPSocketPrivate, ReadWrite, filter);
54 RUN_CALLBACK_TEST(TestTCPSocketPrivate, ReadWriteSSL, filter);
55 RUN_CALLBACK_TEST(TestTCPSocketPrivate, ConnectAddress, filter);
56 RUN_CALLBACK_TEST(TestTCPSocketPrivate, SetOption, filter);
57 RUN_CALLBACK_TEST(TestTCPSocketPrivate, LargeRead, filter);
60 std::string TestTCPSocketPrivate::TestBasic() {
61 pp::TCPSocketPrivate socket(instance_);
62 TestCompletionCallback cb(instance_->pp_instance(), callback_type());
64 cb.WaitForResult(socket.Connect(host_.c_str(), port_, cb.GetCallback()));
65 CHECK_CALLBACK_BEHAVIOR(cb);
66 ASSERT_EQ(PP_OK, cb.result());
68 PP_NetAddress_Private unused;
69 // TODO(viettrungluu): check the values somehow.
70 ASSERT_TRUE(socket.GetLocalAddress(&unused));
71 ASSERT_TRUE(socket.GetRemoteAddress(&unused));
73 socket.Disconnect();
75 PASS();
78 std::string TestTCPSocketPrivate::TestReadWrite() {
79 pp::TCPSocketPrivate socket(instance_);
80 TestCompletionCallback cb(instance_->pp_instance(), callback_type());
82 cb.WaitForResult(socket.Connect(host_.c_str(), port_, cb.GetCallback()));
83 CHECK_CALLBACK_BEHAVIOR(cb);
84 ASSERT_EQ(PP_OK, cb.result());
86 ASSERT_EQ(PP_OK, WriteStringToSocket(&socket, "GET / HTTP/1.0\r\n\r\n"));
88 // Read up to the first \n and check that it looks like valid HTTP response.
89 std::string s;
90 ASSERT_EQ(PP_OK, ReadFirstLineFromSocket(&socket, &s));
91 ASSERT_TRUE(ValidateHttpResponse(s));
93 socket.Disconnect();
95 PASS();
98 std::string TestTCPSocketPrivate::TestReadWriteSSL() {
99 pp::TCPSocketPrivate socket(instance_);
100 TestCompletionCallback cb(instance_->pp_instance(), callback_type());
102 cb.WaitForResult(socket.Connect(host_.c_str(), ssl_port_, cb.GetCallback()));
103 CHECK_CALLBACK_BEHAVIOR(cb);
104 ASSERT_EQ(PP_OK, cb.result());
106 cb.WaitForResult(
107 socket.SSLHandshake(host_.c_str(), ssl_port_, cb.GetCallback()));
108 CHECK_CALLBACK_BEHAVIOR(cb);
109 ASSERT_EQ(PP_OK, cb.result());
111 ASSERT_EQ(PP_OK, WriteStringToSocket(&socket, "GET / HTTP/1.0\r\n\r\n"));
113 // Read up to the first \n and check that it looks like valid HTTP response.
114 std::string s;
115 ASSERT_EQ(PP_OK, ReadFirstLineFromSocket(&socket, &s));
116 ASSERT_TRUE(ValidateHttpResponse(s));
118 socket.Disconnect();
120 PASS();
123 std::string TestTCPSocketPrivate::TestConnectAddress() {
124 PP_NetAddress_Private address;
126 // First, bring up a connection and grab the address.
128 pp::TCPSocketPrivate socket(instance_);
129 TestCompletionCallback cb(instance_->pp_instance(), callback_type());
130 cb.WaitForResult(socket.Connect(host_.c_str(), port_, cb.GetCallback()));
131 CHECK_CALLBACK_BEHAVIOR(cb);
132 ASSERT_EQ(PP_OK, cb.result());
133 ASSERT_TRUE(socket.GetRemoteAddress(&address));
134 // Omit the |Disconnect()| here to make sure we don't crash if we just let
135 // the resource be destroyed.
138 // Connect to that address.
139 pp::TCPSocketPrivate socket(instance_);
140 TestCompletionCallback cb(instance_->pp_instance(), callback_type());
141 cb.WaitForResult(socket.ConnectWithNetAddress(&address, cb.GetCallback()));
142 CHECK_CALLBACK_BEHAVIOR(cb);
143 ASSERT_EQ(PP_OK, cb.result());
145 // Make sure we can read/write to it properly (see |TestReadWrite()|).
146 ASSERT_EQ(PP_OK, WriteStringToSocket(&socket, "GET / HTTP/1.0\r\n\r\n"));
147 std::string s;
148 ASSERT_EQ(PP_OK, ReadFirstLineFromSocket(&socket, &s));
149 ASSERT_TRUE(ValidateHttpResponse(s));
151 socket.Disconnect();
153 PASS();
156 std::string TestTCPSocketPrivate::TestSetOption() {
157 pp::TCPSocketPrivate socket(instance_);
158 TestCompletionCallback cb(instance_->pp_instance(), callback_type());
160 cb.WaitForResult(
161 socket.SetOption(PP_TCPSOCKETOPTION_PRIVATE_NO_DELAY, true,
162 cb.GetCallback()));
163 CHECK_CALLBACK_BEHAVIOR(cb);
164 ASSERT_EQ(PP_ERROR_FAILED, cb.result());
166 cb.WaitForResult(socket.Connect(host_.c_str(), port_, cb.GetCallback()));
167 CHECK_CALLBACK_BEHAVIOR(cb);
168 ASSERT_EQ(PP_OK, cb.result());
170 cb.WaitForResult(
171 socket.SetOption(PP_TCPSOCKETOPTION_PRIVATE_NO_DELAY, true,
172 cb.GetCallback()));
173 CHECK_CALLBACK_BEHAVIOR(cb);
174 ASSERT_EQ(PP_OK, cb.result());
176 cb.WaitForResult(
177 socket.SetOption(PP_TCPSOCKETOPTION_PRIVATE_INVALID, true,
178 cb.GetCallback()));
179 CHECK_CALLBACK_BEHAVIOR(cb);
180 ASSERT_EQ(PP_ERROR_BADARGUMENT, cb.result());
182 socket.Disconnect();
184 PASS();
187 std::string TestTCPSocketPrivate::TestLargeRead() {
188 pp::TCPSocketPrivate socket(instance_);
190 TestCompletionCallback cb(instance_->pp_instance(), callback_type());
192 cb.WaitForResult(socket.Connect(host_.c_str(), port_, cb.GetCallback()));
193 CHECK_CALLBACK_BEHAVIOR(cb);
194 ASSERT_EQ(PP_OK, cb.result());
197 ASSERT_EQ(PP_OK, WriteStringToSocket(&socket, "GET / HTTP/1.0\r\n\r\n"));
199 const size_t kReadSize = 1024 * 1024 + 32;
200 // Create large buffer in heap to prevent run-time errors related to
201 // limits on stack size.
202 char* buffer = new (std::nothrow) char[kReadSize];
203 ASSERT_TRUE(buffer != NULL);
205 TestCompletionCallback cb(instance_->pp_instance(), callback_type());
206 cb.WaitForResult(socket.Read(buffer, kReadSize * sizeof(*buffer),
207 cb.GetCallback()));
208 CHECK_CALLBACK_BEHAVIOR(cb);
209 ASSERT_LE(0, cb.result());
211 delete [] buffer;
213 PASS();
216 int32_t TestTCPSocketPrivate::ReadFirstLineFromSocket(
217 pp::TCPSocketPrivate* socket,
218 std::string* s) {
219 char buffer[10000];
221 s->clear();
222 // Make sure we don't just hang if |Read()| spews.
223 while (s->size() < 1000000) {
224 TestCompletionCallback cb(instance_->pp_instance(), callback_type());
225 int32_t rv = socket->Read(buffer, sizeof(buffer), cb.GetCallback());
226 if (callback_type() == PP_REQUIRED && rv != PP_OK_COMPLETIONPENDING)
227 return PP_ERROR_FAILED;
228 cb.WaitForResult(rv);
229 if (cb.result() < 0)
230 return cb.result();
231 if (cb.result() == 0)
232 return PP_ERROR_FAILED; // Didn't get a \n-terminated line.
233 s->reserve(s->size() + cb.result());
234 for (int32_t i = 0; i < cb.result(); i++) {
235 s->push_back(buffer[i]);
236 if (buffer[i] == '\n')
237 return PP_OK;
240 return PP_ERROR_FAILED;
243 int32_t TestTCPSocketPrivate::WriteStringToSocket(pp::TCPSocketPrivate* socket,
244 const std::string& s) {
245 const char* buffer = s.data();
246 size_t written = 0;
247 while (written < s.size()) {
248 TestCompletionCallback cb(instance_->pp_instance(), callback_type());
249 int32_t rv = socket->Write(buffer + written,
250 static_cast<int32_t>(s.size() - written),
251 cb.GetCallback());
252 if (callback_type() == PP_REQUIRED && rv != PP_OK_COMPLETIONPENDING)
253 return PP_ERROR_FAILED;
254 cb.WaitForResult(rv);
255 if (cb.result() < 0)
256 return cb.result();
257 if (cb.result() == 0)
258 return PP_ERROR_FAILED;
259 written += cb.result();
261 if (written != s.size())
262 return PP_ERROR_FAILED;
263 return PP_OK;