• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 <arpa/inet.h>
17 #include <securec.h>
18 #include <sys/un.h>
19 
20 #include "gtest/gtest.h"
21 #include "websocket/client/websocket_client.h"
22 #include "websocket/server/websocket_server.h"
23 
24 using namespace OHOS::ArkCompiler::Toolchain;
25 
26 namespace panda::test {
27 class WebSocketTest : public testing::Test {
28 public:
SetUpTestCase()29     static void SetUpTestCase()
30     {
31         GTEST_LOG_(INFO) << "SetUpTestCase";
32     }
33 
TearDownTestCase()34     static void TearDownTestCase()
35     {
36         GTEST_LOG_(INFO) << "TearDownCase";
37     }
38 
SetUp()39     void SetUp() override
40     {
41     }
42 
TearDown()43     void TearDown() override
44     {
45     }
46 
47 #if defined(OHOS_PLATFORM)
48     static constexpr char UNIX_DOMAIN_PATH[] = "server.sock";
49 #endif
50     static constexpr char HELLO_SERVER[]    = "hello server";
51     static constexpr char HELLO_CLIENT[]    = "hello client";
52     static constexpr char SERVER_OK[]       = "server ok";
53     static constexpr char CLIENT_OK[]       = "client ok";
54     static constexpr char QUIT[]            = "quit";
55     static constexpr char PING[]            = "ping";
56     static constexpr int TCP_PORT           = 9230;
57     static const std::string LONG_MSG;
58     static const std::string LONG_LONG_MSG;
59 };
60 
61 const std::string WebSocketTest::LONG_MSG       = std::string(1000, 'f');
62 const std::string WebSocketTest::LONG_LONG_MSG  = std::string(0xfffff, 'f');
63 
64 HWTEST_F(WebSocketTest, ConnectWebSocketTest, testing::ext::TestSize.Level0)
65 {
66     WebSocketServer serverSocket;
67     bool ret = false;
68 #if defined(OHOS_PLATFORM)
69     int appPid = getpid();
70     ret = serverSocket.InitUnixWebSocket(UNIX_DOMAIN_PATH + std::to_string(appPid), 5);
71 #else
72     ret = serverSocket.InitTcpWebSocket(TCP_PORT, 5);
73 #endif
74     ASSERT_TRUE(ret);
75     pid_t pid = fork();
76     if (pid == 0) {
77         // subprocess, handle client connect and recv/send message
78         // note: EXPECT/ASSERT produce errors in subprocess that can not lead to failure of testcase in mainprocess,
79         //       so testcase still success finally.
80         WebSocketClient clientSocket;
81         bool retClient = false;
82 #if defined(OHOS_PLATFORM)
83         retClient = clientSocket.InitToolchainWebSocketForSockName(UNIX_DOMAIN_PATH + std::to_string(appPid), 5);
84 #else
85         retClient = clientSocket.InitToolchainWebSocketForPort(TCP_PORT, 5);
86 #endif
87         ASSERT_TRUE(retClient);
88         retClient = clientSocket.ClientSendWSUpgradeReq();
89         ASSERT_TRUE(retClient);
90         retClient = clientSocket.ClientRecvWSUpgradeRsp();
91         ASSERT_TRUE(retClient);
92         retClient = clientSocket.SendReply(HELLO_SERVER);
93         EXPECT_TRUE(retClient);
94         std::string recv = clientSocket.Decode();
95         EXPECT_EQ(strcmp(recv.c_str(), HELLO_CLIENT), 0);
96         if (strcmp(recv.c_str(), HELLO_CLIENT) == 0) {
97             retClient = clientSocket.SendReply(CLIENT_OK);
98             EXPECT_TRUE(retClient);
99         }
100         retClient = clientSocket.SendReply(LONG_MSG);
101         EXPECT_TRUE(retClient);
102         recv = clientSocket.Decode();
103         EXPECT_EQ(strcmp(recv.c_str(), SERVER_OK), 0);
104         if (strcmp(recv.c_str(), SERVER_OK) == 0) {
105             retClient = clientSocket.SendReply(CLIENT_OK);
106             EXPECT_TRUE(retClient);
107         }
108         retClient = clientSocket.SendReply(LONG_LONG_MSG);
109         EXPECT_TRUE(retClient);
110         recv = clientSocket.Decode();
111         EXPECT_EQ(strcmp(recv.c_str(), SERVER_OK), 0);
112         if (strcmp(recv.c_str(), SERVER_OK) == 0) {
113             retClient = clientSocket.SendReply(CLIENT_OK);
114             EXPECT_TRUE(retClient);
115         }
116         retClient = clientSocket.SendReply(PING, FrameType::PING); // send a ping frame and wait for pong frame
117         EXPECT_TRUE(retClient);
118         recv = clientSocket.Decode(); // get the pong frame
119         EXPECT_EQ(strcmp(recv.c_str(), ""), 0); // pong frame has no data
120         retClient = clientSocket.SendReply(QUIT);
121         EXPECT_TRUE(retClient);
122         clientSocket.Close();
123         exit(0);
124     } else if (pid > 0) {
125         // mainprocess, handle server connect and recv/send message
126         ret = serverSocket.AcceptNewConnection();
127         ASSERT_TRUE(ret);
128         std::string recv = serverSocket.Decode();
129         EXPECT_EQ(strcmp(recv.c_str(), HELLO_SERVER), 0);
130         serverSocket.SendReply(HELLO_CLIENT);
131         recv = serverSocket.Decode();
132         EXPECT_EQ(strcmp(recv.c_str(), CLIENT_OK), 0);
133         recv = serverSocket.Decode();
134         EXPECT_EQ(strcmp(recv.c_str(), LONG_MSG.c_str()), 0);
135         serverSocket.SendReply(SERVER_OK);
136         recv = serverSocket.Decode();
137         EXPECT_EQ(strcmp(recv.c_str(), CLIENT_OK), 0);
138         recv = serverSocket.Decode();
139         EXPECT_EQ(strcmp(recv.c_str(), LONG_LONG_MSG.c_str()), 0);
140         serverSocket.SendReply(SERVER_OK);
141         recv = serverSocket.Decode();
142         EXPECT_EQ(strcmp(recv.c_str(), CLIENT_OK), 0);
143         recv = serverSocket.Decode();
144         EXPECT_EQ(strcmp(recv.c_str(), PING), 0); // the ping frame has "PING" and send a pong frame
145         recv = serverSocket.Decode();
146         EXPECT_EQ(strcmp(recv.c_str(), QUIT), 0);
147         serverSocket.Close();
148         // sleep ensure that linux os core can really release resource
149         sleep(3);
150     } else {
151         std::cerr << "ConnectWebSocketTest::fork failed, error = "
152                   << errno << ", desc = " << strerror(errno) << std::endl;
153     }
154 }
155 
156 HWTEST_F(WebSocketTest, ReConnectWebSocketTest, testing::ext::TestSize.Level0)
157 {
158     WebSocketServer serverSocket;
159     bool ret = false;
160 #if defined(OHOS_PLATFORM)
161     int appPid = getpid();
162     ret = serverSocket.InitUnixWebSocket(UNIX_DOMAIN_PATH + std::to_string(appPid), 5);
163 #else
164     ret = serverSocket.InitTcpWebSocket(TCP_PORT, 5);
165 #endif
166     ASSERT_TRUE(ret);
167     for (int i = 0; i < 5; i++) {
168         pid_t pid = fork();
169         if (pid == 0) {
170             // subprocess, handle client connect and recv/send message
171             // note: EXPECT/ASSERT produce errors in subprocess that can not lead to failure of testcase in mainprocess,
172             //       so testcase still success finally.
173             WebSocketClient clientSocket;
174             bool retClient = false;
175 #if defined(OHOS_PLATFORM)
176             retClient = clientSocket.InitToolchainWebSocketForSockName(UNIX_DOMAIN_PATH + std::to_string(appPid), 5);
177 #else
178             retClient = clientSocket.InitToolchainWebSocketForPort(TCP_PORT, 5);
179 #endif
180             ASSERT_TRUE(retClient);
181             retClient = clientSocket.ClientSendWSUpgradeReq();
182             ASSERT_TRUE(retClient);
183             retClient = clientSocket.ClientRecvWSUpgradeRsp();
184             ASSERT_TRUE(retClient);
185             retClient = clientSocket.SendReply(HELLO_SERVER + std::to_string(i));
186             EXPECT_TRUE(retClient);
187             std::string recv = clientSocket.Decode();
188             EXPECT_EQ(strcmp(recv.c_str(), (HELLO_CLIENT + std::to_string(i)).c_str()), 0);
189             if (strcmp(recv.c_str(), (HELLO_CLIENT + std::to_string(i)).c_str()) == 0) {
190                 retClient = clientSocket.SendReply(CLIENT_OK + std::to_string(i));
191                 EXPECT_TRUE(retClient);
192             }
193             clientSocket.Close();
194             exit(0);
195         } else if (pid > 0) {
196             // mainprocess, handle server connect and recv/send message
197             ret = serverSocket.AcceptNewConnection();
198             ASSERT_TRUE(ret);
199             std::string recv = serverSocket.Decode();
200             EXPECT_EQ(strcmp(recv.c_str(), (HELLO_SERVER + std::to_string(i)).c_str()), 0);
201             serverSocket.SendReply(HELLO_CLIENT + std::to_string(i));
202             recv = serverSocket.Decode();
203             EXPECT_EQ(strcmp(recv.c_str(), (CLIENT_OK + std::to_string(i)).c_str()), 0);
204             while (serverSocket.IsConnected()) {
205                 serverSocket.Decode();
206             }
207         } else {
208             std::cerr << "ReConnectWebSocketTest::fork failed, error = "
209                       << errno << ", desc = " << strerror(errno) << std::endl;
210         }
211     }
212     serverSocket.Close();
213 }
214 }  // namespace panda::test