close
This commit is contained in:
@@ -52,10 +52,13 @@ TEST(ClientServer, OneClient) {
|
|||||||
|
|
||||||
|
|
||||||
class ClientSendThread {
|
class ClientSendThread {
|
||||||
using ClientType = TestClient<false, false, 100_KiB>;
|
using ClientType = TestClient<false, false, 10_KiB>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ClientSendThread() { client = createAndConnectClient<ClientType>(); }
|
ClientSendThread() {
|
||||||
|
client = createAndConnectClient<ClientType>();
|
||||||
|
sendThread.setName("clSend");
|
||||||
|
}
|
||||||
|
|
||||||
~ClientSendThread() {
|
~ClientSendThread() {
|
||||||
sendThread.stopAndWait();
|
sendThread.stopAndWait();
|
||||||
@@ -63,11 +66,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void startSend() {
|
void startSend() {
|
||||||
auto c = client;
|
sendThread.start([this] { client->ping(); }, 100._Hz);
|
||||||
sendThread.start([c] { c->ping(); }, 100._Hz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendOnce() {client->ping();}
|
void sendOnce() { client->ping(); }
|
||||||
|
|
||||||
ClientType * client = nullptr;
|
ClientType * client = nullptr;
|
||||||
PIThread sendThread;
|
PIThread sendThread;
|
||||||
@@ -75,28 +77,24 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
int getServerPongs(PIClientServer::Server * s) {
|
int getServerPongs(PIClientServer::Server * s) {
|
||||||
int pongs = 0;
|
int pongs = 0;
|
||||||
s->forEachClient([&pongs](PIClientServer::ServerClient * sc){
|
s->forEachClient([&pongs](PIClientServer::ServerClient * sc) {
|
||||||
const auto c = static_cast<TestServerClient<> *>(sc);
|
const auto c = static_cast<TestServerClient<> *>(sc);
|
||||||
pongs += c->pongCnt();
|
pongs += c->pongCnt();
|
||||||
});
|
});
|
||||||
return pongs;
|
return pongs;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getClientsPongs(const PIVector<ClientSendThread *> & clients) {
|
int getClientsPongs(const PIVector<ClientSendThread *> & clients) {
|
||||||
int pongs = 0;
|
int pongs = 0;
|
||||||
clients.forEach([&pongs](ClientSendThread * c){
|
clients.forEach([&pongs](ClientSendThread * c) { pongs += c->client->pongCnt(); });
|
||||||
pongs += c->client->pongCnt();
|
return pongs;
|
||||||
});
|
|
||||||
return pongs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int getClientsPings(const PIVector<ClientSendThread *> & clients) {
|
int getClientsPings(const PIVector<ClientSendThread *> & clients) {
|
||||||
int pings = 0;
|
int pings = 0;
|
||||||
clients.forEach([&pings](ClientSendThread * c){
|
clients.forEach([&pings](ClientSendThread * c) { pings += c->client->pingCnt(); });
|
||||||
pings += c->client->pingCnt();
|
return pings;
|
||||||
});
|
|
||||||
return pings;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -113,98 +111,106 @@ TEST(ClientServer, ManyClients) {
|
|||||||
|
|
||||||
waitLoop([s]() { return s->clientsCount() == clients_count; }, loop_timeout);
|
waitLoop([s]() { return s->clientsCount() == clients_count; }, loop_timeout);
|
||||||
EXPECT_EQ(clients_count, s->clientsCount());
|
EXPECT_EQ(clients_count, s->clientsCount());
|
||||||
|
|
||||||
EXPECT_EQ(0, getServerPongs(s));
|
EXPECT_EQ(0, getServerPongs(s));
|
||||||
|
|
||||||
EXPECT_EQ(getClientsPings(clients), 0);
|
EXPECT_EQ(getClientsPings(clients), 0);
|
||||||
|
|
||||||
for (const auto c : clients) {
|
for (const auto c: clients) {
|
||||||
c->sendOnce();
|
c->sendOnce();
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_EQ(getClientsPings(clients), clients_count);
|
EXPECT_EQ(getClientsPings(clients), clients_count);
|
||||||
EXPECT_TRUE(clients.every([](ClientSendThread * c){return c->client->pingCnt() == 1;}));
|
EXPECT_TRUE(clients.every([](ClientSendThread * c) { return c->client->pingCnt() == 1; }));
|
||||||
EXPECT_TRUE(clients.every([](ClientSendThread * c){return c->client->pongCnt() == 0;}));
|
EXPECT_TRUE(clients.every([](ClientSendThread * c) { return c->client->pongCnt() == 0; }));
|
||||||
waitLoop([s]() { return getServerPongs(s) >= clients_count; }, loop_timeout);
|
waitLoop([s]() { return getServerPongs(s) >= clients_count; }, loop_timeout);
|
||||||
EXPECT_EQ(clients_count, getServerPongs(s));
|
EXPECT_EQ(clients_count, getServerPongs(s));
|
||||||
|
|
||||||
s->forEachClient([](PIClientServer::ServerClient * sc) { static_cast<TestServerClient<> *>(sc)->ping(); });
|
s->forEachClient([](PIClientServer::ServerClient * sc) { static_cast<TestServerClient<> *>(sc)->ping(); });
|
||||||
const auto clientCheckPong = [&clients](){return clients.every([](ClientSendThread * c){return c->client->pongCnt() == 1;});};
|
const auto clientCheckPong = [&clients]() { return clients.every([](ClientSendThread * c) { return c->client->pongCnt() == 1; }); };
|
||||||
waitLoop([&clientCheckPong]() { return clientCheckPong(); }, loop_timeout);
|
waitLoop([&clientCheckPong]() { return clientCheckPong(); }, loop_timeout);
|
||||||
EXPECT_TRUE(clientCheckPong());
|
EXPECT_TRUE(clientCheckPong());
|
||||||
|
|
||||||
for (const auto c : clients) {
|
for (const auto c: clients) {
|
||||||
c->startSend();
|
c->startSend();
|
||||||
}
|
}
|
||||||
(100_ms).sleep();
|
(100_ms).sleep();
|
||||||
EXPECT_TRUE(getClientsPings(clients) > clients_count*2);
|
EXPECT_TRUE(getClientsPings(clients) > clients_count * 2);
|
||||||
EXPECT_TRUE(getServerPongs(s) > clients_count*2);
|
EXPECT_TRUE(getServerPongs(s) > clients_count * 2);
|
||||||
piDeleteAllAndClear(clients);
|
piDeleteAllAndClear(clients);
|
||||||
waitLoop([s]() { return s->clientsCount() == 0; }, loop_timeout);
|
waitLoop([s]() { return s->clientsCount() == 0; }, loop_timeout);
|
||||||
EXPECT_EQ(0, s->clientsCount());
|
EXPECT_EQ(0, s->clientsCount());
|
||||||
delete s;
|
delete s;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ClientServer, DynamicClients) {
|
TEST(ClientServer, DynamicClients) {
|
||||||
auto const loop_timeout = 1000_ms;
|
auto const loop_timeout = 1000_ms;
|
||||||
constexpr int clients_count = 20;
|
constexpr int clients_count = 20;
|
||||||
PIVector<ClientSendThread *> clients;
|
PIVector<ClientSendThread *> clients;
|
||||||
PIMutex clients_mutex;
|
PIMutex clients_mutex;
|
||||||
auto s = createServer<true, true, 100_KiB>();
|
auto s = createServer<true, true, 10_KiB>();
|
||||||
|
|
||||||
const auto spawnClient = [&clients, &clients_mutex]() {
|
const auto spawnClient = [&clients, &clients_mutex]() {
|
||||||
auto c = new ClientSendThread();
|
auto c = new ClientSendThread();
|
||||||
c->startSend();
|
c->startSend();
|
||||||
clients_mutex.lock();
|
clients_mutex.lock();
|
||||||
clients << c;
|
clients << c;
|
||||||
clients_mutex.unlock();
|
clients_mutex.unlock();
|
||||||
piCout << "new client" << clients.size();
|
piCout << "new client" << clients.size();
|
||||||
};
|
};
|
||||||
|
|
||||||
piForTimes(clients_count) {
|
piForTimes(clients_count) {
|
||||||
spawnClient();
|
spawnClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
PIThread spawnThread;
|
PIThread spawnThread;
|
||||||
PIThread deleteThread;
|
PIThread deleteThread;
|
||||||
|
spawnThread.setName("spawn");
|
||||||
spawnThread.start([&spawnClient](){
|
deleteThread.setName("delete");
|
||||||
const int new_cnt = randomi() % 10;
|
|
||||||
piForTimes(new_cnt) {
|
spawnThread.start(
|
||||||
spawnClient();
|
[&spawnClient]() {
|
||||||
}
|
const int new_cnt = randomi() % 10;
|
||||||
}, 12_Hz);
|
piForTimes(new_cnt) {
|
||||||
|
spawnClient();
|
||||||
deleteThread.start([&clients, &clients_mutex](){
|
}
|
||||||
const int rm_cnt = randomi() % 10;
|
},
|
||||||
piForTimes(rm_cnt) {
|
12_Hz);
|
||||||
ClientSendThread * c = nullptr;
|
|
||||||
clients_mutex.lock();
|
deleteThread.start(
|
||||||
if (clients.size() > 10) {
|
[&clients, &clients_mutex]() {
|
||||||
c = clients.take_back();
|
const int rm_cnt = randomi() % 10;
|
||||||
}
|
piForTimes(rm_cnt) {
|
||||||
clients_mutex.unlock();
|
ClientSendThread * c = nullptr;
|
||||||
if (c) {
|
clients_mutex.lock();
|
||||||
delete c;
|
if (clients.size() > 10) {
|
||||||
piCout << "remove client" << clients.size();
|
c = clients.take_front();
|
||||||
}
|
}
|
||||||
}
|
clients_mutex.unlock();
|
||||||
}, 13_Hz);
|
if (c) {
|
||||||
|
delete c;
|
||||||
(1_s).sleep();
|
piCout << "remove client" << clients.size();
|
||||||
|
}
|
||||||
EXPECT_GE(s->clientsCount(), 10);
|
}
|
||||||
|
},
|
||||||
piCout << "now clients" << clients.size();
|
13_Hz);
|
||||||
|
|
||||||
//delete s;
|
(10_s).sleep();
|
||||||
|
|
||||||
deleteThread.stopAndWait();
|
EXPECT_GE(s->clientsCount(), 10);
|
||||||
spawnThread.stopAndWait();
|
|
||||||
|
piCout << "now clients" << clients.size();
|
||||||
piCout << "total clients" << clients.size();
|
|
||||||
|
|
||||||
piDeleteAllAndClear(clients);
|
deleteThread.stopAndWait();
|
||||||
waitLoop([s]() { return s->clientsCount() == 0; }, loop_timeout);
|
spawnThread.stopAndWait();
|
||||||
EXPECT_EQ(0, s->clientsCount());
|
|
||||||
|
|
||||||
|
piCout << "total clients" << clients.size();
|
||||||
|
|
||||||
|
piDeleteAllAndClear(clients);
|
||||||
|
waitLoop([s]() { return s->clientsCount() == 0; }, loop_timeout);
|
||||||
|
EXPECT_EQ(0, s->clientsCount());
|
||||||
|
|
||||||
|
delete s;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user