OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ppapi/tests/test_websocket.h" | 5 #include "ppapi/tests/test_websocket.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "ppapi/c/dev/ppb_testing_dev.h" | 10 #include "ppapi/c/dev/ppb_testing_dev.h" |
11 #include "ppapi/c/dev/ppb_websocket_dev.h" | 11 #include "ppapi/c/dev/ppb_websocket_dev.h" |
12 #include "ppapi/c/pp_errors.h" | 12 #include "ppapi/c/pp_errors.h" |
13 #include "ppapi/c/pp_var.h" | 13 #include "ppapi/c/pp_var.h" |
14 #include "ppapi/c/pp_completion_callback.h" | 14 #include "ppapi/c/pp_completion_callback.h" |
15 #include "ppapi/c/ppb_core.h" | 15 #include "ppapi/c/ppb_core.h" |
16 #include "ppapi/c/ppb_var.h" | 16 #include "ppapi/c/ppb_var.h" |
17 #include "ppapi/cpp/dev/websocket_dev.h" | 17 #include "ppapi/cpp/dev/websocket_dev.h" |
| 18 #include "ppapi/cpp/helper/dev/websocket_api_dev.h" |
18 #include "ppapi/cpp/instance.h" | 19 #include "ppapi/cpp/instance.h" |
19 #include "ppapi/cpp/module.h" | 20 #include "ppapi/cpp/module.h" |
20 #include "ppapi/tests/test_utils.h" | 21 #include "ppapi/tests/test_utils.h" |
21 #include "ppapi/tests/testing_instance.h" | 22 #include "ppapi/tests/testing_instance.h" |
22 | 23 |
| 24 // These servers are provided by pywebsocket server side handlers in |
| 25 // LayoutTests/http/tests/websocket/tests/hybi/*_wsh. |
| 26 // pywebsocket server itself is launched in ppapi_ui_test.cc. |
23 const char kEchoServerURL[] = | 27 const char kEchoServerURL[] = |
24 "ws://localhost:8880/websocket/tests/hybi/echo"; | 28 "ws://localhost:8880/websocket/tests/hybi/echo"; |
25 | 29 |
26 const char kCloseServerURL[] = | 30 const char kCloseServerURL[] = |
27 "ws://localhost:8880/websocket/tests/hybi/close"; | 31 "ws://localhost:8880/websocket/tests/hybi/close"; |
28 | 32 |
29 const char kProtocolTestServerURL[] = | 33 const char kProtocolTestServerURL[] = |
30 "ws://localhost:8880/websocket/tests/hybi/protocol-test?protocol="; | 34 "ws://localhost:8880/websocket/tests/hybi/protocol-test?protocol="; |
31 | 35 |
32 const char* const kInvalidURLs[] = { | 36 const char* const kInvalidURLs[] = { |
33 "http://www.google.com/invalid_scheme", | 37 "http://www.google.com/invalid_scheme", |
34 "ws://www.google.com/invalid#fragment", | 38 "ws://www.google.com/invalid#fragment", |
35 "ws://www.google.com:65535/invalid_port", | 39 "ws://www.google.com:65535/invalid_port", |
36 NULL | 40 NULL |
37 }; | 41 }; |
38 | 42 |
39 // Connection close code is defined in WebSocket protocol specification. | 43 // Connection close code is defined in WebSocket protocol specification. |
40 // The magic number 1000 means gracefull closure without any error. | 44 // The magic number 1000 means gracefull closure without any error. |
41 // See section 7.4.1. of RFC 6455. | 45 // See section 7.4.1. of RFC 6455. |
42 const uint16_t kCloseCodeNormalClosure = 1000U; | 46 const uint16_t kCloseCodeNormalClosure = 1000U; |
43 | 47 |
| 48 namespace { |
| 49 |
| 50 struct WebSocketEvent { |
| 51 enum EventType { |
| 52 EVENT_OPEN, |
| 53 EVENT_MESSAGE, |
| 54 EVENT_ERROR, |
| 55 EVENT_CLOSE |
| 56 }; |
| 57 |
| 58 WebSocketEvent(EventType type, |
| 59 bool was_clean, |
| 60 uint16_t close_code, |
| 61 const pp::Var& var) |
| 62 : event_type(type), |
| 63 was_clean(was_clean), |
| 64 close_code(close_code), |
| 65 var(var) {} |
| 66 EventType event_type; |
| 67 bool was_clean; |
| 68 uint16_t close_code; |
| 69 pp::Var var; |
| 70 }; |
| 71 |
| 72 class TestWebSocketAPI : public pp::helper::WebSocketAPI_Dev { |
| 73 public: |
| 74 explicit TestWebSocketAPI(pp::Instance* instance) |
| 75 : pp::helper::WebSocketAPI_Dev(instance), |
| 76 connected_(false), |
| 77 received_(false), |
| 78 closed_(false), |
| 79 wait_for_connected_(false), |
| 80 wait_for_received_(false), |
| 81 wait_for_closed_(false), |
| 82 instance_(instance->pp_instance()) {} |
| 83 |
| 84 virtual void OnOpen() { |
| 85 events_.push_back( |
| 86 WebSocketEvent(WebSocketEvent::EVENT_OPEN, true, 0U, pp::Var())); |
| 87 connected_ = true; |
| 88 if (wait_for_connected_) { |
| 89 GetTestingInterface()->QuitMessageLoop(instance_); |
| 90 wait_for_connected_ = false; |
| 91 } |
| 92 } |
| 93 |
| 94 virtual void OnMessage(const pp::Var &message) { |
| 95 events_.push_back( |
| 96 WebSocketEvent(WebSocketEvent::EVENT_MESSAGE, true, 0U, message)); |
| 97 received_ = true; |
| 98 if (wait_for_received_) { |
| 99 GetTestingInterface()->QuitMessageLoop(instance_); |
| 100 wait_for_received_ = false; |
| 101 received_ = false; |
| 102 } |
| 103 } |
| 104 |
| 105 virtual void OnError() { |
| 106 events_.push_back( |
| 107 WebSocketEvent(WebSocketEvent::EVENT_ERROR, true, 0U, pp::Var())); |
| 108 } |
| 109 |
| 110 virtual void OnClose( |
| 111 bool was_clean, uint16_t code, const pp::Var& reason) { |
| 112 events_.push_back( |
| 113 WebSocketEvent(WebSocketEvent::EVENT_CLOSE, was_clean, code, reason)); |
| 114 connected_ = true; |
| 115 closed_ = true; |
| 116 if (wait_for_connected_ || wait_for_closed_) { |
| 117 GetTestingInterface()->QuitMessageLoop(instance_); |
| 118 wait_for_connected_ = false; |
| 119 wait_for_closed_ = false; |
| 120 } |
| 121 } |
| 122 |
| 123 void WaitForConnected() { |
| 124 if (!connected_) { |
| 125 wait_for_connected_ = true; |
| 126 GetTestingInterface()->RunMessageLoop(instance_); |
| 127 } |
| 128 } |
| 129 |
| 130 void WaitForReceived() { |
| 131 if (!received_) { |
| 132 wait_for_received_ = true; |
| 133 GetTestingInterface()->RunMessageLoop(instance_); |
| 134 } |
| 135 } |
| 136 |
| 137 void WaitForClosed() { |
| 138 if (!closed_) { |
| 139 wait_for_closed_ = true; |
| 140 GetTestingInterface()->RunMessageLoop(instance_); |
| 141 } |
| 142 } |
| 143 |
| 144 const std::vector<WebSocketEvent>& GetSeenEvents() const { |
| 145 return events_; |
| 146 } |
| 147 |
| 148 private: |
| 149 std::vector<WebSocketEvent> events_; |
| 150 bool connected_; |
| 151 bool received_; |
| 152 bool closed_; |
| 153 bool wait_for_connected_; |
| 154 bool wait_for_received_; |
| 155 bool wait_for_closed_; |
| 156 PP_Instance instance_; |
| 157 }; |
| 158 |
| 159 } // namespace |
| 160 |
44 REGISTER_TEST_CASE(WebSocket); | 161 REGISTER_TEST_CASE(WebSocket); |
45 | 162 |
46 bool TestWebSocket::Init() { | 163 bool TestWebSocket::Init() { |
47 websocket_interface_ = static_cast<const PPB_WebSocket_Dev*>( | 164 websocket_interface_ = static_cast<const PPB_WebSocket_Dev*>( |
48 pp::Module::Get()->GetBrowserInterface(PPB_WEBSOCKET_DEV_INTERFACE)); | 165 pp::Module::Get()->GetBrowserInterface(PPB_WEBSOCKET_DEV_INTERFACE)); |
49 var_interface_ = static_cast<const PPB_Var*>( | 166 var_interface_ = static_cast<const PPB_Var*>( |
50 pp::Module::Get()->GetBrowserInterface(PPB_VAR_INTERFACE)); | 167 pp::Module::Get()->GetBrowserInterface(PPB_VAR_INTERFACE)); |
51 core_interface_ = static_cast<const PPB_Core*>( | 168 core_interface_ = static_cast<const PPB_Core*>( |
52 pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE)); | 169 pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE)); |
53 if (!websocket_interface_ || !var_interface_ || !core_interface_) | 170 if (!websocket_interface_ || !var_interface_ || !core_interface_) |
54 return false; | 171 return false; |
55 | 172 |
56 return InitTestingInterface(); | 173 return InitTestingInterface(); |
57 } | 174 } |
58 | 175 |
59 void TestWebSocket::RunTests(const std::string& filter) { | 176 void TestWebSocket::RunTests(const std::string& filter) { |
60 RUN_TEST_WITH_REFERENCE_CHECK(IsWebSocket, filter); | 177 RUN_TEST_WITH_REFERENCE_CHECK(IsWebSocket, filter); |
61 RUN_TEST_WITH_REFERENCE_CHECK(UninitializedPropertiesAccess, filter); | 178 RUN_TEST_WITH_REFERENCE_CHECK(UninitializedPropertiesAccess, filter); |
62 RUN_TEST_WITH_REFERENCE_CHECK(InvalidConnect, filter); | 179 RUN_TEST_WITH_REFERENCE_CHECK(InvalidConnect, filter); |
63 RUN_TEST_WITH_REFERENCE_CHECK(Protocols, filter); | 180 RUN_TEST_WITH_REFERENCE_CHECK(Protocols, filter); |
64 RUN_TEST_WITH_REFERENCE_CHECK(GetURL, filter); | 181 RUN_TEST_WITH_REFERENCE_CHECK(GetURL, filter); |
65 RUN_TEST_WITH_REFERENCE_CHECK(ValidConnect, filter); | 182 RUN_TEST_WITH_REFERENCE_CHECK(ValidConnect, filter); |
66 RUN_TEST_WITH_REFERENCE_CHECK(InvalidClose, filter); | 183 RUN_TEST_WITH_REFERENCE_CHECK(InvalidClose, filter); |
67 RUN_TEST_WITH_REFERENCE_CHECK(ValidClose, filter); | 184 RUN_TEST_WITH_REFERENCE_CHECK(ValidClose, filter); |
68 RUN_TEST_WITH_REFERENCE_CHECK(GetProtocol, filter); | 185 RUN_TEST_WITH_REFERENCE_CHECK(GetProtocol, filter); |
69 RUN_TEST_WITH_REFERENCE_CHECK(TextSendReceive, filter); | 186 RUN_TEST_WITH_REFERENCE_CHECK(TextSendReceive, filter); |
70 | 187 |
71 RUN_TEST_WITH_REFERENCE_CHECK(CcInterfaces, filter); | 188 RUN_TEST_WITH_REFERENCE_CHECK(CcInterfaces, filter); |
| 189 |
| 190 RUN_TEST_WITH_REFERENCE_CHECK(HelperInvalidConnect, filter); |
| 191 RUN_TEST_WITH_REFERENCE_CHECK(HelperProtocols, filter); |
| 192 RUN_TEST_WITH_REFERENCE_CHECK(HelperGetURL, filter); |
| 193 RUN_TEST_WITH_REFERENCE_CHECK(HelperValidConnect, filter); |
| 194 RUN_TEST_WITH_REFERENCE_CHECK(HelperInvalidClose, filter); |
| 195 RUN_TEST_WITH_REFERENCE_CHECK(HelperValidClose, filter); |
| 196 RUN_TEST_WITH_REFERENCE_CHECK(HelperGetProtocol, filter); |
| 197 RUN_TEST_WITH_REFERENCE_CHECK(HelperTextSendReceive, filter); |
72 } | 198 } |
73 | 199 |
74 PP_Var TestWebSocket::CreateVar(const char* string) { | 200 PP_Var TestWebSocket::CreateVar(const char* string) { |
75 return var_interface_->VarFromUtf8(string, strlen(string)); | 201 return var_interface_->VarFromUtf8(string, strlen(string)); |
76 } | 202 } |
77 | 203 |
78 void TestWebSocket::ReleaseVar(const PP_Var& var) { | 204 void TestWebSocket::ReleaseVar(const PP_Var& var) { |
79 var_interface_->Release(var); | 205 var_interface_->Release(var); |
80 } | 206 } |
81 | 207 |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 | 542 |
417 // TODO(toyoshim): Add tests for GetBufferedAmount(). | 543 // TODO(toyoshim): Add tests for GetBufferedAmount(). |
418 // For now, the function doesn't work fine because update callback in WebKit is | 544 // For now, the function doesn't work fine because update callback in WebKit is |
419 // not landed yet. | 545 // not landed yet. |
420 | 546 |
421 // TODO(toyoshim): Add tests for didReceiveMessageError(). | 547 // TODO(toyoshim): Add tests for didReceiveMessageError(). |
422 | 548 |
423 // TODO(toyoshim): Add other function tests. | 549 // TODO(toyoshim): Add other function tests. |
424 | 550 |
425 std::string TestWebSocket::TestCcInterfaces() { | 551 std::string TestWebSocket::TestCcInterfaces() { |
426 // C++ bindings is simple straightforward, then just verifies interfaces work | 552 // The C++ bindings is simple straightforward. This just verifies that the |
427 // as a interface bridge fine. | 553 // bindings work fine as an interface bridge. |
428 pp::WebSocket_Dev ws(instance_); | 554 pp::WebSocket_Dev ws(instance_); |
429 | 555 |
430 // Check uninitialized properties access. | 556 // Check uninitialized properties access. |
431 ASSERT_EQ(0, ws.GetBufferedAmount()); | 557 ASSERT_EQ(0, ws.GetBufferedAmount()); |
432 ASSERT_EQ(0, ws.GetCloseCode()); | 558 ASSERT_EQ(0, ws.GetCloseCode()); |
433 ASSERT_TRUE(AreEqual(ws.GetCloseReason().pp_var(), "")); | 559 ASSERT_TRUE(AreEqual(ws.GetCloseReason().pp_var(), "")); |
434 ASSERT_EQ(false, ws.GetCloseWasClean()); | 560 ASSERT_EQ(false, ws.GetCloseWasClean()); |
435 ASSERT_TRUE(AreEqual(ws.GetExtensions().pp_var(), "")); | 561 ASSERT_TRUE(AreEqual(ws.GetExtensions().pp_var(), "")); |
436 ASSERT_TRUE(AreEqual(ws.GetProtocol().pp_var(), "")); | 562 ASSERT_TRUE(AreEqual(ws.GetProtocol().pp_var(), "")); |
437 ASSERT_EQ(PP_WEBSOCKETREADYSTATE_INVALID_DEV, ws.GetReadyState()); | 563 ASSERT_EQ(PP_WEBSOCKETREADYSTATE_INVALID_DEV, ws.GetReadyState()); |
438 ASSERT_TRUE(AreEqual(ws.GetURL().pp_var(), "")); | 564 ASSERT_TRUE(AreEqual(ws.GetURL().pp_var(), "")); |
439 | 565 |
440 // Check communication interfaces (connect, send, receive, and close). | 566 // Check communication interfaces (connect, send, receive, and close). |
441 TestCompletionCallback connect_callback(instance_->pp_instance()); | 567 TestCompletionCallback connect_callback(instance_->pp_instance()); |
442 int32_t result = ws.Connect(pp::Var(std::string(kCloseServerURL)), NULL, 0U, | 568 int32_t result = ws.Connect( |
443 connect_callback); | 569 pp::Var(std::string(kCloseServerURL)), NULL, 0U, connect_callback); |
444 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); | 570 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
445 result = connect_callback.WaitForResult(); | 571 result = connect_callback.WaitForResult(); |
446 ASSERT_EQ(PP_OK, result); | 572 ASSERT_EQ(PP_OK, result); |
447 | 573 |
448 std::string message("hello C++"); | 574 std::string message("hello C++"); |
449 result = ws.SendMessage(pp::Var(message)); | 575 result = ws.SendMessage(pp::Var(message)); |
450 ASSERT_EQ(PP_OK, result); | 576 ASSERT_EQ(PP_OK, result); |
451 | 577 |
452 pp::Var receive_var; | 578 pp::Var receive_var; |
453 TestCompletionCallback receive_callback(instance_->pp_instance()); | 579 TestCompletionCallback receive_callback(instance_->pp_instance()); |
(...skipping 15 matching lines...) Expand all Loading... |
469 ASSERT_EQ(kCloseCodeNormalClosure, ws.GetCloseCode()); | 595 ASSERT_EQ(kCloseCodeNormalClosure, ws.GetCloseCode()); |
470 ASSERT_TRUE(AreEqual(ws.GetCloseReason().pp_var(), reason.c_str())); | 596 ASSERT_TRUE(AreEqual(ws.GetCloseReason().pp_var(), reason.c_str())); |
471 ASSERT_EQ(true, ws.GetCloseWasClean()); | 597 ASSERT_EQ(true, ws.GetCloseWasClean()); |
472 ASSERT_TRUE(AreEqual(ws.GetExtensions().pp_var(), "")); | 598 ASSERT_TRUE(AreEqual(ws.GetExtensions().pp_var(), "")); |
473 ASSERT_TRUE(AreEqual(ws.GetProtocol().pp_var(), "")); | 599 ASSERT_TRUE(AreEqual(ws.GetProtocol().pp_var(), "")); |
474 ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSED_DEV, ws.GetReadyState()); | 600 ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSED_DEV, ws.GetReadyState()); |
475 ASSERT_TRUE(AreEqual(ws.GetURL().pp_var(), kCloseServerURL)); | 601 ASSERT_TRUE(AreEqual(ws.GetURL().pp_var(), kCloseServerURL)); |
476 | 602 |
477 PASS(); | 603 PASS(); |
478 } | 604 } |
| 605 |
| 606 std::string TestWebSocket::TestHelperInvalidConnect() { |
| 607 const pp::Var protocols[] = { pp::Var() }; |
| 608 |
| 609 TestWebSocketAPI websocket(instance_); |
| 610 int32_t result = websocket.Connect(pp::Var(), protocols, 1U); |
| 611 ASSERT_EQ(PP_ERROR_BADARGUMENT, result); |
| 612 ASSERT_EQ(0U, websocket.GetSeenEvents().size()); |
| 613 |
| 614 result = websocket.Connect(pp::Var(), protocols, 1U); |
| 615 ASSERT_EQ(PP_ERROR_INPROGRESS, result); |
| 616 ASSERT_EQ(0U, websocket.GetSeenEvents().size()); |
| 617 |
| 618 for (int i = 0; kInvalidURLs[i]; ++i) { |
| 619 TestWebSocketAPI ws(instance_); |
| 620 result = ws.Connect(pp::Var(std::string(kInvalidURLs[i])), protocols, 0U); |
| 621 ASSERT_EQ(PP_ERROR_BADARGUMENT, result); |
| 622 ASSERT_EQ(0U, ws.GetSeenEvents().size()); |
| 623 } |
| 624 |
| 625 PASS(); |
| 626 } |
| 627 |
| 628 std::string TestWebSocket::TestHelperProtocols() { |
| 629 const pp::Var bad_protocols[] = { |
| 630 pp::Var(std::string("x-test")), pp::Var(std::string("x-test")) }; |
| 631 const pp::Var good_protocols[] = { |
| 632 pp::Var(std::string("x-test")), pp::Var(std::string("x-yatest")) }; |
| 633 |
| 634 { |
| 635 TestWebSocketAPI websocket(instance_); |
| 636 int32_t result = websocket.Connect( |
| 637 pp::Var(std::string(kEchoServerURL)), bad_protocols, 2U); |
| 638 ASSERT_EQ(PP_ERROR_BADARGUMENT, result); |
| 639 ASSERT_EQ(0U, websocket.GetSeenEvents().size()); |
| 640 } |
| 641 |
| 642 { |
| 643 TestWebSocketAPI websocket(instance_); |
| 644 int32_t result = websocket.Connect( |
| 645 pp::Var(std::string(kEchoServerURL)), good_protocols, 2U); |
| 646 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 647 websocket.WaitForConnected(); |
| 648 const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); |
| 649 // Protocol arguments are valid, but this test run without a WebSocket |
| 650 // server. As a result, OnError() and OnClose() are invoked because of |
| 651 // a connection establishment failure. |
| 652 ASSERT_EQ(2U, events.size()); |
| 653 ASSERT_EQ(WebSocketEvent::EVENT_ERROR, events[0].event_type); |
| 654 ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[1].event_type); |
| 655 ASSERT_FALSE(events[1].was_clean); |
| 656 } |
| 657 |
| 658 PASS(); |
| 659 } |
| 660 |
| 661 std::string TestWebSocket::TestHelperGetURL() { |
| 662 const pp::Var protocols[] = { pp::Var() }; |
| 663 |
| 664 for (int i = 0; kInvalidURLs[i]; ++i) { |
| 665 TestWebSocketAPI websocket(instance_); |
| 666 int32_t result = websocket.Connect( |
| 667 pp::Var(std::string(kInvalidURLs[i])), protocols, 0U); |
| 668 ASSERT_EQ(PP_ERROR_BADARGUMENT, result); |
| 669 pp::Var url = websocket.GetURL(); |
| 670 ASSERT_TRUE(AreEqual(url.pp_var(), kInvalidURLs[i])); |
| 671 ASSERT_EQ(0U, websocket.GetSeenEvents().size()); |
| 672 } |
| 673 |
| 674 PASS(); |
| 675 } |
| 676 |
| 677 std::string TestWebSocket::TestHelperValidConnect() { |
| 678 const pp::Var protocols[] = { pp::Var() }; |
| 679 TestWebSocketAPI websocket(instance_); |
| 680 int32_t result = websocket.Connect( |
| 681 pp::Var(std::string(kEchoServerURL)), protocols, 0U); |
| 682 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 683 websocket.WaitForConnected(); |
| 684 const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); |
| 685 ASSERT_EQ(1U, events.size()); |
| 686 ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type); |
| 687 |
| 688 PASS(); |
| 689 } |
| 690 |
| 691 std::string TestWebSocket::TestHelperInvalidClose() { |
| 692 const pp::Var reason = pp::Var(std::string("close for test")); |
| 693 |
| 694 // Close before connect. |
| 695 { |
| 696 TestWebSocketAPI websocket(instance_); |
| 697 int32_t result = websocket.Close(kCloseCodeNormalClosure, reason); |
| 698 ASSERT_EQ(PP_ERROR_FAILED, result); |
| 699 ASSERT_EQ(0U, websocket.GetSeenEvents().size()); |
| 700 } |
| 701 |
| 702 // Close with bad arguments. |
| 703 { |
| 704 TestWebSocketAPI websocket(instance_); |
| 705 int32_t result = websocket.Connect(pp::Var(std::string(kEchoServerURL)), |
| 706 NULL, 0); |
| 707 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 708 websocket.WaitForConnected(); |
| 709 result = websocket.Close(1U, reason); |
| 710 ASSERT_EQ(PP_ERROR_NOACCESS, result); |
| 711 const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); |
| 712 ASSERT_EQ(1U, events.size()); |
| 713 ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type); |
| 714 } |
| 715 |
| 716 PASS(); |
| 717 } |
| 718 |
| 719 std::string TestWebSocket::TestHelperValidClose() { |
| 720 std::string reason("close for test"); |
| 721 pp::Var url = pp::Var(std::string(kCloseServerURL)); |
| 722 |
| 723 // Close. |
| 724 { |
| 725 TestWebSocketAPI websocket(instance_); |
| 726 int32_t result = websocket.Connect(url, NULL, 0U); |
| 727 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 728 websocket.WaitForConnected(); |
| 729 result = websocket.Close(kCloseCodeNormalClosure, pp::Var(reason)); |
| 730 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 731 websocket.WaitForClosed(); |
| 732 const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); |
| 733 ASSERT_EQ(2U, events.size()); |
| 734 ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type); |
| 735 ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[1].event_type); |
| 736 ASSERT_TRUE(events[1].was_clean); |
| 737 ASSERT_EQ(kCloseCodeNormalClosure, events[1].close_code); |
| 738 ASSERT_TRUE(AreEqual(events[1].var.pp_var(), reason.c_str())); |
| 739 } |
| 740 |
| 741 // Close in connecting. |
| 742 // The ongoing connect failed with PP_ERROR_ABORTED, then the close is done |
| 743 // successfully. |
| 744 { |
| 745 TestWebSocketAPI websocket(instance_); |
| 746 int32_t result = websocket.Connect(url, NULL, 0U); |
| 747 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 748 result = websocket.Close(kCloseCodeNormalClosure, pp::Var(reason)); |
| 749 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 750 websocket.WaitForClosed(); |
| 751 const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); |
| 752 ASSERT_TRUE(events.size() == 2 || events.size() == 3); |
| 753 int index = 0; |
| 754 if (events.size() == 3) |
| 755 ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[index++].event_type); |
| 756 ASSERT_EQ(WebSocketEvent::EVENT_ERROR, events[index++].event_type); |
| 757 ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[index].event_type); |
| 758 ASSERT_FALSE(events[index].was_clean); |
| 759 } |
| 760 |
| 761 // Close in closing. |
| 762 // The first close will be done successfully, then the second one failed with |
| 763 // with PP_ERROR_INPROGRESS immediately. |
| 764 { |
| 765 TestWebSocketAPI websocket(instance_); |
| 766 int32_t result = websocket.Connect(url, NULL, 0U); |
| 767 result = websocket.Close(kCloseCodeNormalClosure, pp::Var(reason)); |
| 768 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 769 result = websocket.Close(kCloseCodeNormalClosure, pp::Var(reason)); |
| 770 ASSERT_EQ(PP_ERROR_INPROGRESS, result); |
| 771 websocket.WaitForClosed(); |
| 772 const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); |
| 773 ASSERT_TRUE(events.size() == 2 || events.size() == 3) |
| 774 int index = 0; |
| 775 if (events.size() == 3) |
| 776 ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[index++].event_type); |
| 777 ASSERT_EQ(WebSocketEvent::EVENT_ERROR, events[index++].event_type); |
| 778 ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[index].event_type); |
| 779 ASSERT_FALSE(events[index].was_clean); |
| 780 } |
| 781 |
| 782 PASS(); |
| 783 } |
| 784 |
| 785 std::string TestWebSocket::TestHelperGetProtocol() { |
| 786 const std::string protocol("x-chat"); |
| 787 const pp::Var protocols[] = { pp::Var(protocol) }; |
| 788 std::string url(kProtocolTestServerURL); |
| 789 url += protocol; |
| 790 TestWebSocketAPI websocket(instance_); |
| 791 int32_t result = websocket.Connect(pp::Var(url), protocols, 1U); |
| 792 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 793 websocket.WaitForReceived(); |
| 794 ASSERT_TRUE(AreEqual(websocket.GetProtocol().pp_var(), protocol.c_str())); |
| 795 const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); |
| 796 // The server to which this test connect returns the decided protocol as a |
| 797 // text frame message. So the WebSocketEvent records EVENT_MESSAGE event |
| 798 // after EVENT_OPEN event. |
| 799 ASSERT_EQ(2U, events.size()); |
| 800 ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type); |
| 801 ASSERT_EQ(WebSocketEvent::EVENT_MESSAGE, events[1].event_type); |
| 802 ASSERT_TRUE(AreEqual(events[1].var.pp_var(), protocol.c_str())); |
| 803 ASSERT_TRUE(events[1].was_clean); |
| 804 |
| 805 PASS(); |
| 806 } |
| 807 |
| 808 std::string TestWebSocket::TestHelperTextSendReceive() { |
| 809 const pp::Var protocols[] = { pp::Var() }; |
| 810 TestWebSocketAPI websocket(instance_); |
| 811 int32_t result = |
| 812 websocket.Connect(pp::Var(std::string(kEchoServerURL)), protocols, 0U); |
| 813 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 814 websocket.WaitForConnected(); |
| 815 |
| 816 // Send 'hello pepper'. |
| 817 std::string message1("hello pepper"); |
| 818 result = websocket.Send(pp::Var(std::string(message1))); |
| 819 ASSERT_EQ(PP_OK, result); |
| 820 |
| 821 // Receive echoed 'hello pepper'. |
| 822 websocket.WaitForReceived(); |
| 823 |
| 824 // Send 'goodbye pepper'. |
| 825 std::string message2("goodbye pepper"); |
| 826 result = websocket.Send(pp::Var(std::string(message2))); |
| 827 |
| 828 // Receive echoed 'goodbye pepper'. |
| 829 websocket.WaitForReceived(); |
| 830 |
| 831 const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); |
| 832 ASSERT_EQ(3U, events.size()); |
| 833 ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type); |
| 834 ASSERT_EQ(WebSocketEvent::EVENT_MESSAGE, events[1].event_type); |
| 835 ASSERT_TRUE(AreEqual(events[1].var.pp_var(), message1.c_str())); |
| 836 ASSERT_EQ(WebSocketEvent::EVENT_MESSAGE, events[2].event_type); |
| 837 ASSERT_TRUE(AreEqual(events[2].var.pp_var(), message2.c_str())); |
| 838 |
| 839 PASS(); |
| 840 } |
OLD | NEW |