我正在编写一些单元测试,其目的是运行websocket服务器,单元测试是连接到所述服务器的http客户端,并确保响应对应于请求。
所以我正在寻找的主要流程是:
基本上重复测试Y / Z / A / B
我的代码是这样的:
#define WEBSOCKET_SERVER_IPV4 "127.0.0.1"
#define WEBSOCKET_SERVER_PORT "3000"
#define WEBSOCKETSECURE_SERVER_IPV4 "127.0.0.1"
#define WEBSOCKETSECURE_SERVER_PORT "3001"
class WebSocketT : public ::testing ::Test{
public:
WebSocketT(){
printf(">>>>>>---START WS SERVER---\n");
cf = new ConfigManager("/opt/ra/la-d.conf");
pid_t pid = fork();
if (pid == 0){
main_websocket_process(cf);
exit(EXIT_SUCCESS);
}else if (pid > 0){
ws_child = pid;
started = 1;
printf("started child: %i", (int)pid);
}
else {
printf("fork failed");
exit(EXIT_FAILURE);
}
sleep(5);
}
~WebSocketT(){
if (started != 0){
if (kill (ws_child, SIGKILL) != 0){
printf("ERROR kill: %s", strerror(errno));
} else printf("killed");
sleep(3);
}
delete cf;
}
private:
pid_t ws_child;
ConfigManager *cf;
};
/**
* Test can connect normal
*/
TEST_F(WebSocketT, connect_normal){
// FILE* ecgwsd_fp = popen("/opt/ra/ecgwsd/bin/ecgwsd /opt/ra/ecgwsd/default.conf &", "r"); sleep(3);
Hub h;
bool got_open_message= false;
h.onMessage([&got_open_message](WebSocket<CLIENT> *ws, char *message, size_t length, OpCode opCode){
if (length == 13821){
got_open_message = true;
ASSERT_EQ(strncmp(message, "{\"softw", 7), 0);
}
if (got_open_message == true) ws->close();
fflush(stdout);
});
h.onConnection([](WebSocket<uWS::CLIENT> *ws, HttpRequest req){
//ws->send("{}");
ws->send(ws_json_open.c_str(), ws_json_open.length(), OpCode::TEXT);
});
h.onDisconnection([](WebSocket<uWS::CLIENT> *ws, int code, char *message, size_t length){
//nothign
});
h.onError([](void * u){
printf("ERROR in websocket connection");
FAIL();
});
h.connect("ws://" WEBSOCKET_SERVER_IPV4 ":" WEBSOCKET_SERVER_PORT "/TESTSTS", nullptr );
h.run();
};
/**
* Test can connect secure
*/
TEST_F(WebSocketT, connect_secure){
Hub h;
bool ssl_connected = false;
h.onMessage([](WebSocket<SERVER> *ws, char *message, size_t length, OpCode opCode){
printf("Was a message");
});
h.onConnection([&ssl_connected](WebSocket<uWS::CLIENT> *ws, HttpRequest req){
//ws->send("{}");
ssl_connected = true;
ws->close();
});
h.onDisconnection([&ssl_connected](WebSocket<uWS::CLIENT> *ws, int code, char *message, size_t length){
ASSERT_EQ(ssl_connected, true);
});
h.onError([](void * u){
printf("ERROR in websocket secure connection, %s", (char*) u);
FAIL();
});
h.connect("wss://" WEBSOCKETSECURE_SERVER_IPV4 ":" WEBSOCKETSECURE_SERVER_PORT "/", nullptr );
h.run();
};
所以这里我们的测试X是:正常/安全
问题是,当我运行它时,connect_normal可以连接到服务器,但connect_secure不能。如果我注释掉connect_normal,那么连接安全就可以了。
我还尝试通过将websocket服务器编译为单独的二进制文件而不是将其作为“/ path / to / binary / websocket_server --port = 3242&amp;”运行来解决此问题。在gitlab的连续集成配置中。这有完全相同的问题。
我能解决这个问题的唯一方法是创建一个单独的二进制文件,它可以作为一个独立的可执行文件运行,而不是在每个测试用例的开头我用popen ("/path/to/websocket/server --port=3434 &", "r"); sleep(3);
运行可执行文件,睡眠是允许服务器有一段时间启动。这个单独的二进制文件也运行“main_websocket_process”,但是在主函数内(+日志+信号处理) - 所以逻辑上它应该在websocket活动方面做同样的事情。
使用popen和sleep看起来很脏,那么有没有办法为每个测试用例干净地运行这个服务器?为服务器编写模拟是不实际的。另外,为什么上面的代码适用于单个测试用例,但是下一个代码失败?它应该在每个测试用例上运行构造函数和析构函数吗?