• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <hwext/gtest-ext.h>
17 #include <hwext/gtest-tag.h>
18 #include <netinet/in.h>
19 #include <sys/socket.h>
20 
21 #include "http_server.h"
22 #include "http_socket.h"
23 #include "rpc/rpc_server.h"
24 #include "string_help.h"
25 
26 using namespace testing::ext;
27 namespace SysTuning {
28 namespace TraceStreamer {
29 using namespace SysTuning::base;
30 #define UNUSED(expr)             \
31     do {                         \
32         static_cast<void>(expr); \
33     } while (0)
34 
35 const uint32_t MAX_TESET_BUF_SIZE = 1024;
36 std::string g_parserData = "sugov:0-178   (  178) [001] .... 28462.257501: cpu_frequency: state=816000 cpu_id=0 \n";
37 std::string g_sqlQuery("select * from measure;");
38 char g_clientRecvBuf[MAX_TESET_BUF_SIZE] = {0};
39 class HttpServerTest : public ::testing::Test {
40 public:
SetUp()41     void SetUp()
42     {
43         stream_.InitFilter();
44     }
TearDown()45     void TearDown() {}
46 
47 public:
48     TraceStreamerSelector stream_ = {};
49 };
50 
ResultCallbackFunc(const std::string result,int num)51 void ResultCallbackFunc(const std::string result, int num)
52 {
53     // unused
54     UNUSED(result);
55 }
56 
HttpServerThread(void * arg)57 void* HttpServerThread(void* arg)
58 {
59     HttpServer* httpServer = static_cast<HttpServer*>(arg);
60     httpServer->Run();
61     TS_LOGI("Server thread end");
62     pthread_exit(nullptr);
63 }
64 
HttpClient(const char * buf)65 int HttpClient(const char* buf)
66 {
67     struct sockaddr_in addr;
68     addr.sin_family = AF_INET;
69     addr.sin_addr.s_addr = htons(INADDR_ANY);
70     const uint16_t listenPort = 9001;
71     addr.sin_port = htons(listenPort);
72     struct timeval recvTimeout = {1, 100000};
73 
74     int sockfd = socket(AF_INET, SOCK_STREAM, 0);
75     if (sockfd < 0) {
76         TS_LOGI("CreateSocket socket error");
77         return -1;
78     }
79 
80     int ret = connect(sockfd, (struct sockaddr*)(&addr), sizeof(struct sockaddr));
81     if (ret < 0) {
82         TS_LOGE("Connect error");
83         return -1;
84     }
85 
86     ret = send(sockfd, buf, strlen(buf), 0);
87     if (ret < 0) {
88         TS_LOGE("Send error");
89         return -1;
90     }
91 
92     if (!memset_s(g_clientRecvBuf, strlen(g_clientRecvBuf), 0, strlen(g_clientRecvBuf))) {
93         TS_LOGE("memset_s error");
94         return -1;
95     }
96     int index = 0;
97     ret = setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char*)(&recvTimeout), sizeof(recvTimeout));
98     if (ret != 0) {
99         TS_LOGE("set recv time out error");
100         return -1;
101     }
102     while (1) {
103         ret = recv(sockfd, g_clientRecvBuf + index, MAX_TESET_BUF_SIZE, 0);
104         if (ret < 0) {
105             TS_LOGE("Recv timeout");
106             break;
107         }
108         index += ret;
109     }
110     return 0;
111 }
112 
113 /**
114  * @tc.name: HttpCorrectRequest
115  * @tc.desc: HTTP correct request
116  * @tc.type: FUNC
117  */
118 HWTEST_F(HttpServerTest, HttpCorrectRequest, TestSize.Level1)
119 {
120     TS_LOGI("test21-1");
121     HttpServer httpServer;
122     RpcServer rpcServer;
123     pthread_t pthreadId = 0;
124     int ret = 0;
125 
126     ret = rpcServer.ParseData((const uint8_t*)g_parserData.c_str(), g_parserData.length(), ResultCallbackFunc);
127     ret = rpcServer.ParseDataOver(nullptr, 0, ResultCallbackFunc);
128     ret = rpcServer.SqlQuery((const uint8_t*)g_sqlQuery.c_str(), g_sqlQuery.length(), ResultCallbackFunc);
129 
130     httpServer.RegisterRpcFunction(&rpcServer);
131     ret = pthread_create(&pthreadId, nullptr, HttpServerThread, &httpServer);
132     if (ret != 0) {
133         TS_LOGE("Server pthread create fail");
134         pthread_exit(nullptr);
135     }
136 
137     sleep(1);
138     std::string bufToSend =
139         "GET /sqlquery HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length:\
140                 23\r\n\r\nselect * from measure\r\n";
141 
142     ret = HttpClient(bufToSend.c_str());
143     if (ret < 0) {
144         TS_LOGE("Client fail");
145     }
146     httpServer.Exit();
147     ret = pthread_join(pthreadId, nullptr);
148     if (ret != 0) {
149         TS_LOGE("Server pthread jion fail");
150     }
151     char targetStr[MAX_TESET_BUF_SIZE] = {
152         "HTTP/1.1 200 OK\r\nConnection: Keep-Alive\r\nContent-Type: application/json\r\nTransfer-Encoding: "
153         "chunked\r\n\r\n62\r\nok\r\n{\"columns\":[\"type\",\"ts\",\"value\",\"filter_id\"],\"values\":[[\"measure\","
154         "28462257501000,816000,0]]}"
155         "\r\n\r\n0\r\n\r\n"};
156 
157     EXPECT_STREQ(targetStr, g_clientRecvBuf);
158 }
159 /**
160  * @tc.name: OthreAgreement
161  * @tc.desc: Use http1 1. Agreements other than agreements
162  * @tc.type: FUNC
163  */
164 HWTEST_F(HttpServerTest, OthreAgreement, TestSize.Level1)
165 {
166     TS_LOGI("test21-2");
167     HttpServer httpServer;
168     RpcServer rpcServer;
169     pthread_t pthreadId = 0;
170     int ret = 0;
171 
172     httpServer.RegisterRpcFunction(&rpcServer);
173     ret = pthread_create(&pthreadId, nullptr, HttpServerThread, &httpServer);
174     if (ret != 0) {
175         TS_LOGE("Server pthread create fail");
176         pthread_exit(nullptr);
177     }
178 
179     sleep(1);
180     std::string bufToSend =
181               "GET /sqlquery HTTP/0.9\r\nHost: 127.0.0.1\r\nContent-Length:\
182                23\r\n\r\nselect * from measure\r\n";
183 
184     ret = HttpClient(bufToSend.c_str());
185     if (ret < 0) {
186         TS_LOGE("Client fail");
187     }
188     httpServer.Exit();
189     ret = pthread_join(pthreadId, nullptr);
190     if (ret != 0) {
191         TS_LOGE("Server pthread jion fail");
192     }
193     char targetStr[MAX_TESET_BUF_SIZE] = {"HTTP/1.1 400 Bad Request\r\nConnection: Keep-Alive\r\n\r\n"};
194     EXPECT_STREQ(targetStr, g_clientRecvBuf);
195 }
196 
197 /**
198  * @tc.name: OthreProtocols
199  * @tc.desc: Use protocols other than GET and POST
200  * @tc.type: FUNC
201  */
202 HWTEST_F(HttpServerTest, OthreProtocols, TestSize.Level1)
203 {
204     TS_LOGI("test21-3");
205     HttpServer httpServer;
206     RpcServer rpcServer;
207     pthread_t pthreadId = 0;
208     int ret = 0;
209 
210     httpServer.RegisterRpcFunction(&rpcServer);
211     ret = pthread_create(&pthreadId, nullptr, HttpServerThread, &httpServer);
212     if (ret != 0) {
213         TS_LOGE("Server pthread create fail");
214         pthread_exit(nullptr);
215     }
216 
217     sleep(1);
218     std::string bufToSend =
219               "HEAD /sqlquery HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length:\
220                23\r\n\r\nselect * from measure\r\n";
221 
222     ret = HttpClient(bufToSend.c_str());
223     if (ret < 0) {
224         TS_LOGE("Client fail");
225     }
226     httpServer.Exit();
227     ret = pthread_join(pthreadId, nullptr);
228     if (ret != 0) {
229         TS_LOGE("Server pthread jion fail");
230     }
231     char targetStr[MAX_TESET_BUF_SIZE] = {"HTTP/1.1 405 Method Not Allowed\r\nConnection: Keep-Alive\r\n\r\n"};
232     EXPECT_STREQ(targetStr, g_clientRecvBuf);
233 }
234 
235 /**
236  * @tc.name: RequestLineFormatError
237  * @tc.desc: Request line format error
238  * @tc.type: FUNC
239  */
240 HWTEST_F(HttpServerTest, RequestLineFormatError, TestSize.Level1)
241 {
242     TS_LOGI("test21-4");
243     HttpServer httpServer;
244     RpcServer rpcServer;
245     pthread_t pthreadId = 0;
246     int ret = 0;
247 
248     httpServer.RegisterRpcFunction(&rpcServer);
249     ret = pthread_create(&pthreadId, nullptr, HttpServerThread, &httpServer);
250     if (ret != 0) {
251         TS_LOGE("Server pthread create fail");
252         pthread_exit(nullptr);
253     }
254 
255     sleep(1);
256     std::string bufToSend =
257               "POST /sqlqueryHTTP/0.9\r\nHost: 127.0.0.1\r\nContent-Length:\
258                20\r\n\r\nselect * from meta\r\n";
259 
260     ret = HttpClient(bufToSend.c_str());
261     if (ret < 0) {
262         TS_LOGE("Client fail");
263     }
264     httpServer.Exit();
265     ret = pthread_join(pthreadId, nullptr);
266     if (ret != 0) {
267         TS_LOGE("Server pthread jion fail");
268     }
269     char targetStr[MAX_TESET_BUF_SIZE] = {"HTTP/1.1 400 Bad Request\r\nConnection: Keep-Alive\r\n\r\n"};
270     EXPECT_STREQ(targetStr, g_clientRecvBuf);
271 }
272 
273 /**
274  * @tc.name: RequestIsNotRPC
275  * @tc.desc: The URI of HTTP request is not the method of RPC
276  * @tc.type: FUNC
277  */
278 HWTEST_F(HttpServerTest, RequestIsNotRPC, TestSize.Level1)
279 {
280     TS_LOGI("test21-5");
281     HttpServer httpServer;
282     RpcServer rpcServer;
283     pthread_t pthreadId = 0;
284     int ret = 0;
285 
286     httpServer.RegisterRpcFunction(&rpcServer);
287     ret = pthread_create(&pthreadId, nullptr, HttpServerThread, &httpServer);
288     if (ret != 0) {
289         TS_LOGE("Server pthread create fail");
290         pthread_exit(nullptr);
291     }
292 
293     sleep(1);
294     std::string bufToSend =
295               "POST /query HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length:20\r\n\r\n\
296                select * from meta\r\n";
297 
298     ret = HttpClient(bufToSend.c_str());
299     if (ret < 0) {
300         TS_LOGE("Client fail");
301     }
302     httpServer.Exit();
303     ret = pthread_join(pthreadId, nullptr);
304     if (ret != 0) {
305         TS_LOGE("Server pthread jion fail");
306     }
307     char targetStr[MAX_TESET_BUF_SIZE] = {"HTTP/1.1 404 Not Found\r\nConnection: Keep-Alive\r\n\r\n"};
308     EXPECT_STREQ(targetStr, g_clientRecvBuf);
309 }
310 /**
311  * @tc.name: RequestTimeout
312  * @tc.desc: Incomplete request content data
313  * @tc.type: FUNC
314  */
315 HWTEST_F(HttpServerTest, RequestTimeout, TestSize.Level1)
316 {
317     TS_LOGI("test21-6");
318     HttpServer httpServer;
319     RpcServer rpcServer;
320     pthread_t pthreadId = 0;
321     int ret = 0;
322 
323     httpServer.RegisterRpcFunction(&rpcServer);
324     ret = pthread_create(&pthreadId, nullptr, HttpServerThread, &httpServer);
325     if (ret != 0) {
326         TS_LOGE("Server pthread create fail");
327         pthread_exit(nullptr);
328     }
329 
330     sleep(1);
331     std::string buf =
332         "GET /sqlquery HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length:\
333                 28\r\n\r\nselect * from measure\r\n";
334 
335     ret = HttpClient(buf.c_str());
336     if (ret < 0) {
337         TS_LOGE("Client fail");
338     }
339     httpServer.Exit();
340     ret = pthread_join(pthreadId, nullptr);
341     if (ret != 0) {
342         TS_LOGE("Server pthread jion fail");
343     }
344     char targetStr[MAX_TESET_BUF_SIZE] = {"HTTP/1.1 408 Request Time-out\r\nConnection: Keep-Alive\r\n\r\n"};
345     EXPECT_STREQ(targetStr, g_clientRecvBuf);
346 }
347 } // namespace TraceStreamer
348 } // namespace SysTuning