blob: f51e8fcb644fb32fbb39f33f2d60a0770441c4b6 [file] [log] [blame]
Brian Silverman41cdd3e2019-01-19 19:48:58 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) 2018 FIRST. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
8#include "wpi/WebSocketServer.h" // NOLINT(build/include_order)
9
10#include "WebSocketTest.h"
11#include "wpi/HttpParser.h"
12#include "wpi/SmallString.h"
13
14namespace wpi {
15
16class WebSocketIntegrationTest : public WebSocketTest {};
17
18TEST_F(WebSocketIntegrationTest, Open) {
19 int gotServerOpen = 0;
20 int gotClientOpen = 0;
21
22 serverPipe->Listen([&]() {
23 auto conn = serverPipe->Accept();
24 auto server = WebSocketServer::Create(*conn);
25 server->connected.connect([&](StringRef url, WebSocket&) {
26 ++gotServerOpen;
27 ASSERT_EQ(url, "/test");
28 });
29 });
30
31 clientPipe->Connect(pipeName, [&] {
32 auto ws = WebSocket::CreateClient(*clientPipe, "/test", pipeName);
33 ws->closed.connect([&](uint16_t code, StringRef reason) {
34 Finish();
35 if (code != 1005 && code != 1006)
36 FAIL() << "Code: " << code << " Reason: " << reason;
37 });
38 ws->open.connect([&, s = ws.get() ](StringRef) {
39 ++gotClientOpen;
40 s->Close();
41 });
42 });
43
44 loop->Run();
45
46 ASSERT_EQ(gotServerOpen, 1);
47 ASSERT_EQ(gotClientOpen, 1);
48}
49
50TEST_F(WebSocketIntegrationTest, Protocol) {
51 int gotServerOpen = 0;
52 int gotClientOpen = 0;
53
54 serverPipe->Listen([&]() {
55 auto conn = serverPipe->Accept();
56 auto server = WebSocketServer::Create(*conn, {"proto1", "proto2"});
57 server->connected.connect([&](StringRef, WebSocket& ws) {
58 ++gotServerOpen;
59 ASSERT_EQ(ws.GetProtocol(), "proto1");
60 });
61 });
62
63 clientPipe->Connect(pipeName, [&] {
64 auto ws =
65 WebSocket::CreateClient(*clientPipe, "/test", pipeName, {"proto1"});
66 ws->closed.connect([&](uint16_t code, StringRef reason) {
67 Finish();
68 if (code != 1005 && code != 1006)
69 FAIL() << "Code: " << code << " Reason: " << reason;
70 });
71 ws->open.connect([&, s = ws.get() ](StringRef protocol) {
72 ++gotClientOpen;
73 s->Close();
74 ASSERT_EQ(protocol, "proto1");
75 });
76 });
77
78 loop->Run();
79
80 ASSERT_EQ(gotServerOpen, 1);
81 ASSERT_EQ(gotClientOpen, 1);
82}
83
84TEST_F(WebSocketIntegrationTest, ServerSendBinary) {
85 int gotData = 0;
86
87 serverPipe->Listen([&]() {
88 auto conn = serverPipe->Accept();
89 auto server = WebSocketServer::Create(*conn);
90 server->connected.connect([&](StringRef, WebSocket& ws) {
91 ws.SendBinary(uv::Buffer{"\x03\x04", 2}, [&](auto, uv::Error) {});
92 ws.Close();
93 });
94 });
95
96 clientPipe->Connect(pipeName, [&] {
97 auto ws = WebSocket::CreateClient(*clientPipe, "/test", pipeName);
98 ws->closed.connect([&](uint16_t code, StringRef reason) {
99 Finish();
100 if (code != 1005 && code != 1006)
101 FAIL() << "Code: " << code << " Reason: " << reason;
102 });
103 ws->binary.connect([&](ArrayRef<uint8_t> data, bool) {
104 ++gotData;
105 std::vector<uint8_t> recvData{data.begin(), data.end()};
106 std::vector<uint8_t> expectData{0x03, 0x04};
107 ASSERT_EQ(recvData, expectData);
108 });
109 });
110
111 loop->Run();
112
113 ASSERT_EQ(gotData, 1);
114}
115
116TEST_F(WebSocketIntegrationTest, ClientSendText) {
117 int gotData = 0;
118
119 serverPipe->Listen([&]() {
120 auto conn = serverPipe->Accept();
121 auto server = WebSocketServer::Create(*conn);
122 server->connected.connect([&](StringRef, WebSocket& ws) {
123 ws.text.connect([&](StringRef data, bool) {
124 ++gotData;
125 ASSERT_EQ(data, "hello");
126 });
127 });
128 });
129
130 clientPipe->Connect(pipeName, [&] {
131 auto ws = WebSocket::CreateClient(*clientPipe, "/test", pipeName);
132 ws->closed.connect([&](uint16_t code, StringRef reason) {
133 Finish();
134 if (code != 1005 && code != 1006)
135 FAIL() << "Code: " << code << " Reason: " << reason;
136 });
137 ws->open.connect([&, s = ws.get() ](StringRef) {
138 s->SendText(uv::Buffer{"hello"}, [&](auto, uv::Error) {});
139 s->Close();
140 });
141 });
142
143 loop->Run();
144
145 ASSERT_EQ(gotData, 1);
146}
147
148} // namespace wpi