Skip to content

Commit a2c639d

Browse files
authored
Added core tests for network::Socket/Server/network::Address. Optimize code to reduce duplicate code (#5762)
* Added server tests --filter=[core] * Move more code from the .h header file to the .cc source file to facilitate the observation of test coverage. Optimize the code to reduce redundancy. * Optimize socket/file/address impl & tests, --filter=[core]
1 parent 27a97d7 commit a2c639d

File tree

16 files changed

+720
-491
lines changed

16 files changed

+720
-491
lines changed

core-tests/src/network/socket.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,48 @@ TEST(socket, sendfile_sync) {
188188
t2.join();
189189
}
190190

191+
TEST(socket, sendfile) {
192+
string file = "/tmp/swoole-file-not-exists";
193+
auto cli = make_socket(SW_SOCK_TCP, SW_FD_STREAM_CLIENT, 0);
194+
network::Address addr;
195+
addr.assign(SW_SOCK_TCP, TEST_HTTP_DOMAIN, 80);
196+
ASSERT_EQ(cli->connect(addr), SW_OK);
197+
198+
ASSERT_EQ(cli->sendfile_sync(file.c_str(), 0, 0, -1), SW_ERR);
199+
ASSERT_EQ(errno, ENOENT);
200+
201+
File fp(file, File::WRITE | File::CREATE);
202+
ASSERT_TRUE(fp.ready());
203+
204+
ASSERT_EQ(cli->sendfile_sync(file.c_str(), 0, 0, -1), SW_ERR);
205+
ASSERT_EQ(swoole_get_last_error(), SW_ERROR_FILE_EMPTY);
206+
207+
fp.write(SW_STRL(TEST_STR));
208+
fp.close();
209+
210+
ASSERT_EQ(cli->sendfile_sync(file.c_str(), 10, 100, -1), SW_ERR);
211+
ASSERT_EQ(swoole_get_last_error(), SW_ERROR_INVALID_PARAMS);
212+
213+
ASSERT_TRUE(fp.open(file, File::WRITE | File::APPEND));
214+
auto req = test::http_get_request(TEST_HTTP_DOMAIN, "/");
215+
fp.write(req);
216+
fp.close();
217+
218+
ASSERT_EQ(cli->sendfile_sync(file.c_str(), strlen(TEST_STR), 0, -1), SW_OK);
219+
220+
char rbuf[4096];
221+
auto n = cli->recv_sync(rbuf, sizeof(rbuf), 0);
222+
ASSERT_GT(n, 0);
223+
224+
String resp(rbuf, n);
225+
226+
ASSERT_TRUE(resp.contains(SW_STRL(TEST_HTTP_EXPECT)));
227+
228+
cli->free();
229+
230+
ASSERT_TRUE(File::remove(file));
231+
}
232+
191233
TEST(socket, peek) {
192234
char sock1_path[] = "/tmp/udp_unix1.sock";
193235
char sock2_path[] = "/tmp/udp_unix2.sock";
@@ -387,15 +429,57 @@ TEST(socket, dup) {
387429
test_socket_sync(sock_2, false);
388430
}
389431

432+
TEST(socket, ipv4_addr) {
433+
auto sock = make_socket(SW_SOCK_TCP, SW_FD_STREAM, 0);
434+
network::Address addr;
435+
436+
ASSERT_TRUE(addr.assign("tcp://127.0.0.1:12345"));
437+
ASSERT_EQ(sock->connect(addr), SW_ERR);
438+
ASSERT_EQ(errno, ECONNREFUSED);
439+
440+
ASSERT_TRUE(addr.assign("tcp://localhost:12345"));
441+
ASSERT_EQ(sock->connect(addr), SW_ERR);
442+
ASSERT_EQ(errno, ECONNREFUSED);
443+
444+
sock->free();
445+
}
446+
390447
TEST(socket, ipv6_addr) {
391448
auto sock = make_socket(SW_SOCK_TCP6, SW_FD_STREAM, 0);
392449
network::Address addr;
450+
393451
ASSERT_TRUE(addr.assign("tcp://[::1]:12345"));
394452
ASSERT_EQ(sock->connect(addr), SW_ERR);
395453
ASSERT_EQ(errno, ECONNREFUSED);
454+
455+
ASSERT_TRUE(addr.assign("tcp://[ip6-localhost]:12345"));
456+
ASSERT_EQ(sock->connect(addr), SW_ERR);
457+
ASSERT_EQ(errno, ECONNREFUSED);
458+
396459
sock->free();
397460
}
398461

462+
TEST(socket, unix_addr) {
463+
auto sock = make_socket(SW_SOCK_UNIX_STREAM, SW_FD_STREAM, 0);
464+
network::Address addr;
465+
ASSERT_TRUE(addr.assign("unix:///tmp/swoole-not-exists.sock"));
466+
ASSERT_EQ(sock->connect(addr), SW_ERR);
467+
ASSERT_EQ(errno, ENOENT);
468+
sock->free();
469+
}
470+
471+
TEST(socket, bad_addr) {
472+
network::Address addr;
473+
ASSERT_FALSE(addr.assign("test://[::1]:12345"));
474+
ASSERT_EQ(swoole_get_last_error(), SW_ERROR_BAD_HOST_ADDR);
475+
}
476+
477+
TEST(socket, bad_port) {
478+
network::Address addr;
479+
ASSERT_FALSE(addr.assign("tcp://[::1]:92345"));
480+
ASSERT_EQ(swoole_get_last_error(), SW_ERROR_BAD_PORT);
481+
}
482+
399483
TEST(socket, loopback_addr) {
400484
network::Address addr1;
401485
addr1.assign(SW_SOCK_TCP, "127.0.0.1", 0);

core-tests/src/os/msg_queue.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ using swoole::QueueNode;
2626
TEST(msg_queue, rbac) {
2727
MsgQueue q(0x950001);
2828
ASSERT_TRUE(q.ready());
29+
ASSERT_GE(q.get_id(), 0);
2930
QueueNode in;
3031
in.mtype = 999;
3132
strcpy(in.mdata, "hello world");

core-tests/src/server/server.cpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#include "swoole_lock.h"
2626
#include "swoole_util.h"
2727

28+
#include <numeric>
29+
2830
using namespace std;
2931
using namespace swoole;
3032

@@ -64,6 +66,87 @@ TEST(server, schedule) {
6466
ASSERT_EQ(_worker_id_set.size(), serv.worker_num - 2);
6567
}
6668

69+
TEST(server, schedule_1) {
70+
int ret;
71+
Server serv(Server::MODE_PROCESS);
72+
serv.worker_num = 8;
73+
serv.dispatch_mode = Server::DISPATCH_ROUND;
74+
serv.add_port(SW_SOCK_TCP, TEST_HOST, 0);
75+
76+
ret = serv.create();
77+
ASSERT_EQ(SW_OK, ret);
78+
79+
std::vector<size_t> counter;
80+
size_t schedule_count = 1024;
81+
82+
counter.resize(serv.worker_num);
83+
SW_LOOP_N(schedule_count) {
84+
auto worker_id = serv.schedule_worker(i * 13, nullptr);
85+
counter[worker_id]++;
86+
}
87+
88+
SW_LOOP_N(serv.worker_num) {
89+
ASSERT_EQ(counter[i], schedule_count / serv.worker_num);
90+
}
91+
}
92+
93+
double average_combined(const std::vector<size_t> &v1, const std::vector<size_t> &v2) {
94+
size_t total_size = v1.size() + v2.size();
95+
if (total_size == 0) return 0.0;
96+
size_t sum1 = std::accumulate(v1.begin(), v1.end(), size_t{0});
97+
size_t sum2 = std::accumulate(v2.begin(), v2.end(), size_t{0});
98+
return static_cast<double>(sum1 + sum2) / total_size;
99+
}
100+
101+
template <typename T, typename M, M T::*member>
102+
static void test_worker_schedule(int dispatch_mode) {
103+
int ret;
104+
Server serv(Server::MODE_PROCESS);
105+
serv.worker_num = 8;
106+
serv.dispatch_mode = dispatch_mode;
107+
auto port = serv.add_port(SW_SOCK_TCP, TEST_HOST, 0);
108+
109+
ret = serv.create();
110+
ASSERT_EQ(SW_OK, ret);
111+
112+
std::vector<size_t> counter;
113+
counter.resize(serv.worker_num);
114+
115+
size_t schedule_count = 256 * serv.worker_num;
116+
117+
std::vector<size_t> init_counter;
118+
init_counter.resize(serv.worker_num);
119+
120+
SW_LOOP_N(serv.worker_num) {
121+
T &worker = serv.workers[i];
122+
init_counter[i] = worker.*member = swoole_rand(32, 512);
123+
}
124+
125+
network::Socket fake_sock{};
126+
fake_sock.fd = 199;
127+
serv.add_connection(port, &fake_sock, port->get_fd());
128+
129+
SW_LOOP_N(schedule_count) {
130+
auto worker_id = serv.schedule_worker(fake_sock.fd, nullptr);
131+
counter[worker_id]++;
132+
T &worker = serv.workers[worker_id];
133+
(worker.*member)++;
134+
}
135+
136+
auto avg_elem = average_combined(init_counter, counter);
137+
SW_LOOP_N(serv.worker_num) {
138+
ASSERT_GE(counter[i] + init_counter[i], (int) avg_elem * 2 - 5);
139+
}
140+
}
141+
142+
TEST(server, schedule_9) {
143+
test_worker_schedule<Worker, size_t, &Worker::coroutine_num>(Server::DISPATCH_CO_REQ_LB);
144+
}
145+
146+
TEST(server, schedule_10) {
147+
test_worker_schedule<Worker, uint32_t, &Worker::concurrency>(Server::DISPATCH_CONCURRENT_LB);
148+
}
149+
67150
static const char *packet = "hello world\n";
68151

69152
TEST(server, base) {

ext-src/swoole_client.cc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -393,10 +393,8 @@ bool php_swoole_client_check_setting(Client *cli, zval *zset) {
393393
}
394394
} else {
395395
_open_tcp_nodelay:
396-
if (cli->socket->socket_type == SW_SOCK_TCP || cli->socket->socket_type == SW_SOCK_TCP6) {
397-
if (cli->socket->set_tcp_nodelay() < 0) {
398-
swoole_sys_warning("setsockopt(%d, TCP_NODELAY) failed", cli->socket->fd);
399-
}
396+
if (cli->socket->is_tcp() && !cli->socket->set_tcp_nodelay()) {
397+
swoole_sys_warning("setsockopt(%d, TCP_NODELAY) failed", cli->socket->fd);
400398
}
401399
}
402400
/**

ext-src/swoole_http_server.cc

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,9 @@ int php_swoole_http_server_onReceive(Server *serv, RecvData *req) {
118118
}
119119
http_server_add_server_array(ht, SW_ZSTR_KNOWN(SW_ZEND_STR_REMOTE_PORT), (zend_long) conn->info.get_port());
120120

121-
if (conn->info.type == SW_SOCK_TCP && IN_IS_ADDR_LOOPBACK(&conn->info.addr.inet_v4.sin_addr)) {
122-
http_server_add_server_array(
123-
ht, SW_ZSTR_KNOWN(SW_ZEND_STR_REMOTE_ADDR), SW_ZSTR_KNOWN(SW_ZEND_STR_ADDR_LOOPBACK_V4));
124-
} else if (conn->info.type == SW_SOCK_TCP6 && IN6_IS_ADDR_LOOPBACK(&conn->info.addr.inet_v6.sin6_addr)) {
125-
http_server_add_server_array(
126-
ht, SW_ZSTR_KNOWN(SW_ZEND_STR_REMOTE_ADDR), SW_ZSTR_KNOWN(SW_ZEND_STR_ADDR_LOOPBACK_V6));
121+
if (conn->info.is_loopback_addr()) {
122+
auto key = conn->info.type == SW_SOCK_TCP6 ? SW_ZEND_STR_ADDR_LOOPBACK_V6 : SW_ZEND_STR_ADDR_LOOPBACK_V4;
123+
http_server_add_server_array(ht, SW_ZSTR_KNOWN(SW_ZEND_STR_REMOTE_ADDR), SW_ZSTR_KNOWN(key));
127124
} else {
128125
if (serv->is_base_mode() && ctx->keepalive) {
129126
auto iter = client_ips.find(session_id);

include/swoole_error.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ enum swErrorCode {
5555
SW_ERROR_BAD_IPV6_ADDRESS = 720,
5656
SW_ERROR_UNREGISTERED_SIGNAL,
5757
SW_ERROR_BAD_HOST_ADDR,
58+
SW_ERROR_BAD_PORT,
5859

5960
// EventLoop
6061
SW_ERROR_EVENT_REMOVE_FAILED = 800,

include/swoole_file.h

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -61,23 +61,11 @@ class File {
6161
flags_ = 0;
6262
}
6363

64-
File(const std::string &path, int oflags) {
65-
fd_ = ::open(path.c_str(), oflags);
66-
path_ = path;
67-
flags_ = oflags;
68-
}
64+
File(const std::string &path, int oflags);
65+
File(const std::string &path, int oflags, int mode);
66+
~File();
6967

70-
File(const std::string &path, int oflags, int mode) {
71-
fd_ = ::open(path.c_str(), oflags, mode);
72-
path_ = path;
73-
flags_ = oflags;
74-
}
75-
76-
~File() {
77-
if (fd_ >= 0) {
78-
::close(fd_);
79-
}
80-
}
68+
bool open(const std::string &path, int oflags, int mode = 0);
8169

8270
bool ready() {
8371
return fd_ != -1;
@@ -87,6 +75,10 @@ class File {
8775
return ::write(fd_, __buf, __n);
8876
}
8977

78+
ssize_t write(const std::string &str) const {
79+
return ::write(fd_, str.c_str(), str.length());
80+
}
81+
9082
ssize_t read(void *__buf, size_t __n) const {
9183
return ::read(fd_, __buf, __n);
9284
}
@@ -171,7 +163,11 @@ class File {
171163
}
172164

173165
static bool exists(const std::string &file) {
174-
return access(file.c_str(), R_OK) == 0;
166+
return ::access(file.c_str(), R_OK) == 0;
167+
}
168+
169+
static bool remove(const std::string &file) {
170+
return ::remove(file.c_str()) == 0;
175171
}
176172
};
177173

include/swoole_server.h

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,22 +1129,7 @@ class Server {
11291129
Server(enum Mode _mode = MODE_BASE);
11301130
~Server();
11311131

1132-
bool set_document_root(const std::string &path) {
1133-
if (path.length() > PATH_MAX) {
1134-
swoole_warning("The length of document_root must be less than %d", PATH_MAX);
1135-
return false;
1136-
}
1137-
1138-
char _realpath[PATH_MAX];
1139-
if (!realpath(path.c_str(), _realpath)) {
1140-
swoole_warning("document_root[%s] does not exist", path.c_str());
1141-
return false;
1142-
}
1143-
1144-
document_root = std::string(_realpath);
1145-
return true;
1146-
}
1147-
1132+
bool set_document_root(const std::string &path);
11481133
void add_static_handler_location(const std::string &);
11491134
void add_static_handler_index_files(const std::string &);
11501135
bool select_static_handler(http_server::Request *request, Connection *conn);

0 commit comments

Comments
 (0)