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"
9 #include "ppapi/cpp/private/tcp_socket_private.h"
10 #include "ppapi/tests/testing_instance.h"
11 #include "ppapi/tests/test_utils.h"
15 // Validates the first line of an HTTP response.
16 bool ValidateHttpResponse(const std::string
& s
) {
17 // Just check that it begins with "HTTP/" and ends with a "\r\n".
18 return s
.size() >= 5 &&
19 s
.substr(0, 5) == "HTTP/" &&
20 s
.substr(s
.size() - 2) == "\r\n";
25 REGISTER_TEST_CASE(TCPSocketPrivate
);
27 TestTCPSocketPrivate::TestTCPSocketPrivate(TestingInstance
* instance
)
28 : TestCase(instance
) {
31 bool TestTCPSocketPrivate::Init() {
32 if (!pp::TCPSocketPrivate::IsAvailable())
35 // We need something to connect to, so we connect to the HTTP server whence we
36 // came. Grab the host and port.
37 if (!EnsureRunningOverHTTP())
40 if (!GetLocalHostPort(instance_
->pp_instance(), &host_
, &port_
))
43 // Get the port for the SSL server.
44 ssl_port_
= instance_
->ssl_server_port();
49 void TestTCPSocketPrivate::RunTests(const std::string
& filter
) {
50 RUN_CALLBACK_TEST(TestTCPSocketPrivate
, Basic
, filter
);
51 RUN_CALLBACK_TEST(TestTCPSocketPrivate
, ReadWrite
, filter
);
52 RUN_CALLBACK_TEST(TestTCPSocketPrivate
, ReadWriteSSL
, filter
);
53 RUN_CALLBACK_TEST(TestTCPSocketPrivate
, ConnectAddress
, filter
);
54 RUN_CALLBACK_TEST(TestTCPSocketPrivate
, SetOption
, filter
);
57 std::string
TestTCPSocketPrivate::TestBasic() {
58 pp::TCPSocketPrivate
socket(instance_
);
59 TestCompletionCallback
cb(instance_
->pp_instance(), callback_type());
61 cb
.WaitForResult(socket
.Connect(host_
.c_str(), port_
, cb
.GetCallback()));
62 CHECK_CALLBACK_BEHAVIOR(cb
);
63 ASSERT_EQ(PP_OK
, cb
.result());
65 PP_NetAddress_Private unused
;
66 // TODO(viettrungluu): check the values somehow.
67 ASSERT_TRUE(socket
.GetLocalAddress(&unused
));
68 ASSERT_TRUE(socket
.GetRemoteAddress(&unused
));
75 std::string
TestTCPSocketPrivate::TestReadWrite() {
76 pp::TCPSocketPrivate
socket(instance_
);
77 TestCompletionCallback
cb(instance_
->pp_instance(), callback_type());
79 cb
.WaitForResult(socket
.Connect(host_
.c_str(), port_
, cb
.GetCallback()));
80 CHECK_CALLBACK_BEHAVIOR(cb
);
81 ASSERT_EQ(PP_OK
, cb
.result());
83 ASSERT_EQ(PP_OK
, WriteStringToSocket(&socket
, "GET / HTTP/1.0\r\n\r\n"));
85 // Read up to the first \n and check that it looks like valid HTTP response.
87 ASSERT_EQ(PP_OK
, ReadFirstLineFromSocket(&socket
, &s
));
88 ASSERT_TRUE(ValidateHttpResponse(s
));
95 std::string
TestTCPSocketPrivate::TestReadWriteSSL() {
96 pp::TCPSocketPrivate
socket(instance_
);
97 TestCompletionCallback
cb(instance_
->pp_instance(), callback_type());
99 cb
.WaitForResult(socket
.Connect(host_
.c_str(), ssl_port_
, cb
.GetCallback()));
100 CHECK_CALLBACK_BEHAVIOR(cb
);
101 ASSERT_EQ(PP_OK
, cb
.result());
104 socket
.SSLHandshake(host_
.c_str(), ssl_port_
, cb
.GetCallback()));
105 CHECK_CALLBACK_BEHAVIOR(cb
);
106 ASSERT_EQ(PP_OK
, cb
.result());
108 ASSERT_EQ(PP_OK
, WriteStringToSocket(&socket
, "GET / HTTP/1.0\r\n\r\n"));
110 // Read up to the first \n and check that it looks like valid HTTP response.
112 ASSERT_EQ(PP_OK
, ReadFirstLineFromSocket(&socket
, &s
));
113 ASSERT_TRUE(ValidateHttpResponse(s
));
120 std::string
TestTCPSocketPrivate::TestConnectAddress() {
121 PP_NetAddress_Private address
;
123 // First, bring up a connection and grab the address.
125 pp::TCPSocketPrivate
socket(instance_
);
126 TestCompletionCallback
cb(instance_
->pp_instance(), callback_type());
127 cb
.WaitForResult(socket
.Connect(host_
.c_str(), port_
, cb
.GetCallback()));
128 CHECK_CALLBACK_BEHAVIOR(cb
);
129 ASSERT_EQ(PP_OK
, cb
.result());
130 ASSERT_TRUE(socket
.GetRemoteAddress(&address
));
131 // Omit the |Disconnect()| here to make sure we don't crash if we just let
132 // the resource be destroyed.
135 // Connect to that address.
136 pp::TCPSocketPrivate
socket(instance_
);
137 TestCompletionCallback
cb(instance_
->pp_instance(), callback_type());
138 cb
.WaitForResult(socket
.ConnectWithNetAddress(&address
, cb
.GetCallback()));
139 CHECK_CALLBACK_BEHAVIOR(cb
);
140 ASSERT_EQ(PP_OK
, cb
.result());
142 // Make sure we can read/write to it properly (see |TestReadWrite()|).
143 ASSERT_EQ(PP_OK
, WriteStringToSocket(&socket
, "GET / HTTP/1.0\r\n\r\n"));
145 ASSERT_EQ(PP_OK
, ReadFirstLineFromSocket(&socket
, &s
));
146 ASSERT_TRUE(ValidateHttpResponse(s
));
153 std::string
TestTCPSocketPrivate::TestSetOption() {
154 pp::TCPSocketPrivate
socket(instance_
);
155 TestCompletionCallback
cb(instance_
->pp_instance(), callback_type());
158 socket
.SetOption(PP_TCPSOCKETOPTION_NO_DELAY
, true, cb
.GetCallback()));
159 CHECK_CALLBACK_BEHAVIOR(cb
);
160 ASSERT_EQ(PP_ERROR_FAILED
, cb
.result());
162 cb
.WaitForResult(socket
.Connect(host_
.c_str(), port_
, cb
.GetCallback()));
163 CHECK_CALLBACK_BEHAVIOR(cb
);
164 ASSERT_EQ(PP_OK
, cb
.result());
167 socket
.SetOption(PP_TCPSOCKETOPTION_NO_DELAY
, true, cb
.GetCallback()));
168 CHECK_CALLBACK_BEHAVIOR(cb
);
169 ASSERT_EQ(PP_OK
, cb
.result());
172 socket
.SetOption(PP_TCPSOCKETOPTION_INVALID
, true, cb
.GetCallback()));
173 CHECK_CALLBACK_BEHAVIOR(cb
);
174 ASSERT_EQ(PP_ERROR_BADARGUMENT
, cb
.result());
181 int32_t TestTCPSocketPrivate::ReadFirstLineFromSocket(
182 pp::TCPSocketPrivate
* socket
,
187 // Make sure we don't just hang if |Read()| spews.
188 while (s
->size() < 1000000) {
189 TestCompletionCallback
cb(instance_
->pp_instance(), callback_type());
190 int32_t rv
= socket
->Read(buffer
, sizeof(buffer
), cb
.GetCallback());
191 if (callback_type() == PP_REQUIRED
&& rv
!= PP_OK_COMPLETIONPENDING
)
192 return PP_ERROR_FAILED
;
193 cb
.WaitForResult(rv
);
196 if (cb
.result() == 0)
197 return PP_ERROR_FAILED
; // Didn't get a \n-terminated line.
198 s
->reserve(s
->size() + cb
.result());
199 for (int32_t i
= 0; i
< cb
.result(); i
++) {
200 s
->push_back(buffer
[i
]);
201 if (buffer
[i
] == '\n')
205 return PP_ERROR_FAILED
;
208 int32_t TestTCPSocketPrivate::WriteStringToSocket(pp::TCPSocketPrivate
* socket
,
209 const std::string
& s
) {
210 const char* buffer
= s
.data();
212 while (written
< s
.size()) {
213 TestCompletionCallback
cb(instance_
->pp_instance(), callback_type());
214 int32_t rv
= socket
->Write(buffer
+ written
, s
.size() - written
,
216 if (callback_type() == PP_REQUIRED
&& rv
!= PP_OK_COMPLETIONPENDING
)
217 return PP_ERROR_FAILED
;
218 cb
.WaitForResult(rv
);
221 if (cb
.result() == 0)
222 return PP_ERROR_FAILED
;
223 written
+= cb
.result();
225 if (written
!= s
.size())
226 return PP_ERROR_FAILED
;