1#include "server.h"
2#include "socket.h"
3
4#define CTEST_MAIN
5#include "ctest.h"
6
7#include "common.h"
8
9cstr server_host = "127.0.0.1";
10int server_port = 8181;
11cstr content = "Lorem ipsum dolor sit amet";
12
13void process(vws_svr_data* req, void* ctx)
14{
15 vws_tcp_svr* server = req->server;
16
17 vws.trace(VL_INFO, "process (%p)", req);
18
19 //> Prepare the response: echo the data back
20
21 // Allocate memory for the data to be sent in response
22 char* data = (char*)vws.malloc(req->size);
23
24 // Copy the request's data to the response data
25 strncpy(data, req->data, req->size);
26
27 // Create response
28 vws_svr_data* reply;
29
30 reply = vws_svr_data_own(req->server, req->cid, (ucstr)data, req->size);
31
32 // Free request
33 vws_svr_data_free(req);
34
35 if (vws.tracelevel >= VT_APPLICATION)
36 {
37 vws.trace(VL_INFO, "process(%lu): %i bytes", reply->cid, reply->size);
38 }
39
40 // Send reply. This will wakeup network thread.
41 vws_tcp_svr_send(reply);
42}
43
44void server_thread(void* arg)
45{
46 vws_tcp_svr* server = (vws_tcp_svr*)arg;
47 vws.tracelevel = VT_THREAD;
48 server->trace = vws.tracelevel;
49
50 vws_tcp_svr_run(server, server_host, server_port);
51}
52
53void client_thread(void* arg)
54{
55 // Connect
56 vws.trace(VL_INFO, "[CLIENT] Connecting");
57 vws_socket* s = vws_socket_new();
58 ASSERT_TRUE(vws_socket_connect(s, server_host, server_port, false));
59 vws.trace(VL_INFO, "[CLIENT] Connected");
60
61 // Send request
62 vws.trace(VL_INFO, "[CLIENT] Send: %s", content);
63 vws_socket_write(s, (ucstr)content, strlen(content));
64
65 // Get reply
66 ssize_t n = vws_socket_read(s);
67 ASSERT_TRUE(n > 0);
68 vws.trace(VL_INFO, "[CLIENT] Receive: %s", s->buffer->data);
69
70 // Disconnect and cleanup.
71 vws_socket_free(s);
72}
73
74CTEST(test_server, echo)
75{
76 vws_tcp_svr* server = vws_tcp_svr_new(10, 0, 0);
77 vws.tracelevel = VT_THREAD;
78 server->on_data_in = process;
79
80 vws.trace(VL_INFO, "[CLIENT] Starting server");
81
82 uv_thread_t server_tid;
83 uv_thread_create(&server_tid, server_thread, server);
84
85 // Wait for server to start up
86 while (server->state != VS_RUNNING)
87 {
88 vws_msleep(100);
89 }
90
91 int nc = 10;
92 uv_thread_t* threads = vws.malloc(sizeof(uv_thread_t) * nc);
93
94 for (int i = 0; i < nc; i++)
95 {
96 uv_thread_create(&threads[i], client_thread, NULL);
97 vws.trace(VL_INFO, "started client thread %p", threads[i]);
98 }
99
100 for (int i = 0; i < nc; i++)
101 {
102 uv_thread_join(&threads[i]);
103 vws.trace(VL_INFO, "stopped client thread %p", threads[i]);
104 }
105
106 free(threads);
107
108 // Shutdown server
109 vws.trace(VL_INFO, "[CLIENT] Stopping server");
110 vws_tcp_svr_stop(server);
111 uv_thread_join(&server_tid);
112 vws_tcp_svr_free(server);
113
114 vws.trace(VL_INFO, "[CLIENT] Done");
115}
116
117int main(int argc, const char* argv[])
118{
119 return ctest_main(argc, argv);
120}
121