Skip to content

Commit 4fe25a8

Browse files
committed
Add test code used to diagnose bug dhbaird#37.
1 parent 5abf4a7 commit 4fe25a8

File tree

4 files changed

+230
-1
lines changed

4 files changed

+230
-1
lines changed

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
CXXFLAGS = -std=gnu++0x -Wall
22
LDLIBS = -lstdc++
3-
.PHONY: all clean
3+
.PHONY: all clean test
44
all: example-client example-client-cpp11
55
clean:
66
-rm example-client example-client-cpp11 *.o
7+
cd test; $(MAKE) clean
8+
test:
9+
cd test; $(MAKE) test
710
testserver: node_modules
811
node example-server.js
912
node_modules:

test/Makefile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CXXFLAGS = -std=gnu++1y -Wall -I..
2+
LDLIBS = -lstdc++
3+
.PHONY: all clean
4+
test: easywsclient.t
5+
node testServer.js & sleep 1 && ./easywsclient.t
6+
clean:
7+
-rm easywsclient.t *.o
8+
vpath %.cpp ../
9+
vpath %.hpp ../
10+
easywsclient.t: easywsclient.t.o easywsclient.o
11+
easywsclient.o: easywsclient.cpp easywsclient.hpp

test/easywsclient.t.cpp

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
#include "easywsclient.hpp"
2+
#ifdef _WIN32
3+
#pragma comment( lib, "ws2_32" )
4+
#include <WinSock2.h>
5+
#endif
6+
#include <assert.h>
7+
#include <stdio.h>
8+
#include <string>
9+
#include <memory>
10+
#include <vector>
11+
#include <utility>
12+
#include <iostream>
13+
#include <sstream>
14+
15+
using easywsclient::WebSocket;
16+
17+
template<class T>
18+
std::string toString(const T& t, size_t maxLen=32)
19+
{
20+
std::stringstream ss;
21+
ss << t;
22+
std::string s = ss.str();
23+
if (s.length() > maxLen) {
24+
return s.substr(0, maxLen-3) + "...";
25+
}
26+
else {
27+
return s;
28+
}
29+
}
30+
31+
#define ASSERT_EQ(a, b) \
32+
if ((a) != (b)) { \
33+
std::cout << "Failed: " #a " == " #b "\n" \
34+
<< "Expected: " << toString(b) << "\n" \
35+
<< " Actual: " << toString(a) << "\n"; \
36+
throw std::runtime_error("test assertion failed"); \
37+
}
38+
39+
namespace {
40+
41+
#ifdef _WIN32
42+
class WSAInit
43+
{
44+
public:
45+
WSAInit()
46+
{
47+
INT rc;
48+
WSADATA wsaData;
49+
rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
50+
if (rc) {
51+
throw std::runtime_error("WSAStartup failed");
52+
}
53+
}
54+
~WSAInit()
55+
{
56+
WSACleanup();
57+
}
58+
};
59+
#endif
60+
61+
class KillServer
62+
{
63+
public:
64+
KillServer() : d_ws(WebSocket::from_url(http://github.com/%3Cspan%20class=%22pl-s%22%3E%3Cspan%20class=%22pl-pds%22%3E"%3C/span%3Ews://localhost:8123/killServer%3Cspan%20class=%22pl-pds%22%3E"%3C/span%3E%3C/span%3E))
65+
{
66+
assert(d_ws);
67+
}
68+
~KillServer()
69+
{
70+
d_ws->send("exit"); // sending any message instructs the server to die
71+
d_ws->poll();
72+
d_ws->poll();
73+
}
74+
private:
75+
std::unique_ptr<WebSocket> d_ws;
76+
};
77+
78+
std::string makeString(size_t length)
79+
{
80+
std::vector<char> v;
81+
v.reserve(length + 1);
82+
for (size_t i = 0; i < length; ++i) {
83+
v.push_back('0' + (i % 10));
84+
}
85+
v.push_back(0);
86+
return &v[0];
87+
}
88+
89+
}
90+
91+
void test()
92+
{
93+
#ifdef _WIN32
94+
WSAInit wsaInit;
95+
#endif
96+
KillServer killServer;
97+
98+
std::unique_ptr<WebSocket> ws(WebSocket::from_url("ws://localhost:8123/echoWithSize"));
99+
assert(ws);
100+
101+
ws->send("four");
102+
std::string message;
103+
while (ws->getReadyState() != WebSocket::CLOSED) {
104+
bool gotMessage = false;
105+
ws->poll();
106+
ws->dispatch([gotMessageOut=&gotMessage, messageOut=&message, ws=ws.get()](const std::string& message) {
107+
*gotMessageOut = true;
108+
*messageOut = message;
109+
});
110+
if (gotMessage) {
111+
break;
112+
}
113+
}
114+
ASSERT_EQ("4\nfour", message);
115+
116+
std::vector<std::pair<std::string, std::string> > v;
117+
v.emplace_back( "0", makeString(0));
118+
v.emplace_back( "1", makeString(1));
119+
v.emplace_back( "123", makeString(123));
120+
v.emplace_back( "124", makeString(124));
121+
v.emplace_back( "125", makeString(125));
122+
v.emplace_back( "126", makeString(126));
123+
v.emplace_back( "127", makeString(127));
124+
v.emplace_back( "128", makeString(128));
125+
v.emplace_back("10000", makeString(10000));
126+
v.emplace_back("32767", makeString(32767));
127+
v.emplace_back("65500", makeString(65500));
128+
v.emplace_back("65529", makeString(65529));
129+
v.emplace_back("65530", makeString(65530));
130+
v.emplace_back("65531", makeString(65531));
131+
v.emplace_back("65532", makeString(65532));
132+
v.emplace_back("65533", makeString(65533));
133+
v.emplace_back("65534", makeString(65534));
134+
v.emplace_back("65535", makeString(65535));
135+
v.emplace_back("65536", makeString(65536));
136+
v.emplace_back("65537", makeString(65537));
137+
138+
for (auto i = v.begin(); i != v.end(); ++i) {
139+
ws->send(i->second);
140+
std::string message;
141+
while (ws->getReadyState() != WebSocket::CLOSED) {
142+
bool gotMessage = false;
143+
ws->poll();
144+
ws->dispatch([gotMessageOut=&gotMessage, messageOut=&message, ws=ws.get()](const std::string& message) {
145+
*gotMessageOut = true;
146+
*messageOut = message;
147+
});
148+
if (gotMessage) {
149+
break;
150+
}
151+
}
152+
ASSERT_EQ(i->first + "\n" + i->second, message);
153+
}
154+
155+
ws->close();
156+
}
157+
158+
int main()
159+
{
160+
try {
161+
test();
162+
}
163+
catch (...) {
164+
throw;
165+
}
166+
return 0;
167+
}

test/testServer.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
Prerequisites:
3+
4+
1. Install node.js and npm
5+
2. npm install ws
6+
7+
See also,
8+
9+
http://einaros.github.com/ws/
10+
11+
To run,
12+
13+
node example-server.js
14+
*/
15+
16+
"use strict"; // http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
17+
var WebSocketServer = require('ws').Server;
18+
var http = require('http');
19+
var app = http.createServer();
20+
var server; // assigned by app.listen() below
21+
22+
var wssEchoWithSize = new WebSocketServer({server: app, path: '/echoWithSize'});
23+
wssEchoWithSize.on('connection', function(ws) {
24+
ws.on('message', function(data, flags) {
25+
if (flags.binary) { return; }
26+
ws.send(data.length + '\n' + data);
27+
});
28+
ws.on('close', function() {
29+
});
30+
ws.on('error', function(e) {
31+
});
32+
});
33+
34+
var wssKillServer = new WebSocketServer({server: app, path: '/killServer'});
35+
wssKillServer.on('connection', function(ws) {
36+
ws.on('message', function(data, flags) {
37+
if (flags.binary) { return; }
38+
server.close();
39+
});
40+
ws.on('close', function() {
41+
});
42+
ws.on('error', function(e) {
43+
});
44+
});
45+
46+
var PORT = parseInt(process.env.PORT || '8123');
47+
server = app.listen(PORT);
48+
console.log('Listening on port ' + PORT + '...');

0 commit comments

Comments
 (0)