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"
11 #include "ppapi/cpp/private/tcp_socket_private.h"
12 #include "ppapi/tests/test_utils.h"
13 #include "ppapi/tests/testing_instance.h"
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";
27 REGISTER_TEST_CASE(TCPSocketPrivate
);
29 TestTCPSocketPrivate::TestTCPSocketPrivate(TestingInstance
* instance
)
30 : TestCase(instance
) {
33 bool TestTCPSocketPrivate::Init() {
34 if (!pp::TCPSocketPrivate::IsAvailable())
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())
42 if (!GetLocalHostPort(instance_
->pp_instance(), &host_
, &port_
))
45 // Get the port for the SSL server.
46 ssl_port_
= instance_
->ssl_server_port();
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
));
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.
90 ASSERT_EQ(PP_OK
, ReadFirstLineFromSocket(&socket
, &s
));
91 ASSERT_TRUE(ValidateHttpResponse(s
));
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());
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.
115 ASSERT_EQ(PP_OK
, ReadFirstLineFromSocket(&socket
, &s
));
116 ASSERT_TRUE(ValidateHttpResponse(s
));
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"));
148 ASSERT_EQ(PP_OK
, ReadFirstLineFromSocket(&socket
, &s
));
149 ASSERT_TRUE(ValidateHttpResponse(s
));
156 std::string
TestTCPSocketPrivate::TestSetOption() {
157 pp::TCPSocketPrivate
socket(instance_
);
158 TestCompletionCallback
cb(instance_
->pp_instance(), callback_type());
161 socket
.SetOption(PP_TCPSOCKETOPTION_PRIVATE_NO_DELAY
, true,
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());
171 socket
.SetOption(PP_TCPSOCKETOPTION_PRIVATE_NO_DELAY
, true,
173 CHECK_CALLBACK_BEHAVIOR(cb
);
174 ASSERT_EQ(PP_OK
, cb
.result());
177 socket
.SetOption(PP_TCPSOCKETOPTION_PRIVATE_INVALID
, true,
179 CHECK_CALLBACK_BEHAVIOR(cb
);
180 ASSERT_EQ(PP_ERROR_BADARGUMENT
, cb
.result());
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
),
208 CHECK_CALLBACK_BEHAVIOR(cb
);
209 ASSERT_LE(0, cb
.result());
216 int32_t TestTCPSocketPrivate::ReadFirstLineFromSocket(
217 pp::TCPSocketPrivate
* socket
,
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
);
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')
240 return PP_ERROR_FAILED
;
243 int32_t TestTCPSocketPrivate::WriteStringToSocket(pp::TCPSocketPrivate
* socket
,
244 const std::string
& s
) {
245 const char* buffer
= s
.data();
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
),
252 if (callback_type() == PP_REQUIRED
&& rv
!= PP_OK_COMPLETIONPENDING
)
253 return PP_ERROR_FAILED
;
254 cb
.WaitForResult(rv
);
257 if (cb
.result() == 0)
258 return PP_ERROR_FAILED
;
259 written
+= cb
.result();
261 if (written
!= s
.size())
262 return PP_ERROR_FAILED
;