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