Skip to content

Commit a05fdfe

Browse files
committed
Add C++ testing
1 parent 5b72a29 commit a05fdfe

File tree

4 files changed

+164
-10
lines changed

4 files changed

+164
-10
lines changed

cpp/test/client_connect/main.cpp

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
#include <gg/error.hpp>
2+
#include <gg/ipc/client.hpp>
3+
#include <source_location>
4+
extern "C" {
5+
#include <gg/ipc/mock.h>
6+
#include <gg/ipc/packet_sequences.h>
7+
#include <gg/process_wait.h>
8+
#include <unistd.h>
9+
#include <unity.h>
10+
}
11+
12+
namespace {
13+
int server_handle = -1;
14+
15+
constexpr const char *auth_token = "0123456789ABCDEF";
16+
constexpr const char *socket_path = "cpp_connect_socket.ipc";
17+
}
18+
19+
#define GG_TEST_ASSERT_OK(expr) TEST_ASSERT_EQUAL(GG_ERR_OK, (expr))
20+
#define GG_TEST_ASSERT_BAD(expr) TEST_ASSERT_NOT_EQUAL(GG_ERR_OK, (expr))
21+
22+
void suiteSetUp(void) {
23+
std::ios_base::sync_with_stdio(false);
24+
GgError ret
25+
= gg_test_setup_ipc(socket_path, 0777, &server_handle, auth_token);
26+
if ((ret != GG_ERR_OK) || (server_handle < 0)) {
27+
_Exit(1);
28+
}
29+
}
30+
31+
void setUp(void) {
32+
}
33+
34+
void tearDown(void) {
35+
}
36+
37+
int suiteTearDown(int num_failures) {
38+
gg_test_close(server_handle);
39+
server_handle = -1;
40+
return num_failures;
41+
}
42+
43+
namespace tests {
44+
45+
namespace {
46+
void connect_okay(void) {
47+
GgipcPacketSequence seq
48+
= gg_test_conn_ack_sequence(gg::Buffer { auth_token });
49+
50+
pid_t pid = fork();
51+
if (pid < 0) {
52+
TEST_IGNORE_MESSAGE("fork() failed.");
53+
}
54+
if (pid == 0) {
55+
auto &client = gg::ipc::Client::get();
56+
GG_TEST_ASSERT_OK(client.connect().value());
57+
TEST_PASS();
58+
}
59+
60+
GG_TEST_ASSERT_OK(
61+
gg_test_expect_packet_sequence(seq, 30, server_handle)
62+
);
63+
64+
bool clean_exit = false;
65+
GG_TEST_ASSERT_OK(gg_process_wait(pid, &clean_exit));
66+
TEST_ASSERT_TRUE(clean_exit);
67+
}
68+
69+
void connect_with_token_okay(void) {
70+
GgipcPacketSequence seq
71+
= gg_test_conn_ack_sequence(gg::Buffer { auth_token });
72+
73+
pid_t pid = fork();
74+
if (pid < 0) {
75+
TEST_IGNORE_MESSAGE("fork() failed.");
76+
}
77+
78+
if (pid == 0) {
79+
// make it impossible for client to get these env variables
80+
// done before SDK can make any threads
81+
// NOLINTBEGIN(concurrency-mt-unsafe)
82+
unsetenv("SVCUID");
83+
unsetenv("AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT");
84+
// NOLINTEND(concurrency-mt-unsafe)
85+
auto &client = gg::ipc::Client::get();
86+
GG_TEST_ASSERT_OK(
87+
client.connect(socket_path, gg::ipc::AuthToken { auth_token })
88+
.value()
89+
);
90+
91+
TEST_PASS();
92+
}
93+
94+
GG_TEST_ASSERT_OK(
95+
gg_test_expect_packet_sequence(seq, 5, server_handle)
96+
);
97+
98+
bool clean_exit = false;
99+
GG_TEST_ASSERT_OK(gg_process_wait(pid, &clean_exit));
100+
TEST_ASSERT_TRUE(clean_exit);
101+
}
102+
103+
void connect_bad(void) {
104+
GgipcPacketSequence seq
105+
= gg_test_connect_hangup_sequence(gg::Buffer { auth_token });
106+
107+
pid_t pid = fork();
108+
if (pid < 0) {
109+
TEST_IGNORE_MESSAGE("fork() failed.");
110+
}
111+
112+
if (pid == 0) {
113+
auto &client = gg::ipc::Client::get();
114+
GG_TEST_ASSERT_BAD(client.connect().value());
115+
TEST_PASS();
116+
}
117+
118+
GG_TEST_ASSERT_OK(
119+
gg_test_expect_packet_sequence(seq, 30, server_handle)
120+
);
121+
122+
/// TODO: verify Classic behavior
123+
GG_TEST_ASSERT_OK(gg_test_disconnect(server_handle));
124+
125+
bool clean_exit = false;
126+
GG_TEST_ASSERT_OK(gg_process_wait(pid, &clean_exit));
127+
TEST_ASSERT_TRUE(clean_exit);
128+
}
129+
}
130+
}
131+
132+
int main(int argc, char *argv[]) {
133+
(void) argc;
134+
(void) argv;
135+
suiteSetUp();
136+
137+
UNITY_BEGIN();
138+
RUN_TEST(tests::connect_okay);
139+
RUN_TEST(tests::connect_with_token_okay);
140+
RUN_TEST(tests::connect_bad);
141+
int num_failures = UNITY_END();
142+
143+
return suiteTearDown(num_failures);
144+
}

mock/gg/ipc/mock.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@
22
#define GG_IPC_MOCK_H
33

44
#include <gg/attr.h>
5+
#include <sys/types.h>
6+
#include <stddef.h>
7+
8+
#ifdef __cplusplus
9+
#include <gg/ipc/mock_types.hpp>
10+
#include <gg/types.hpp>
11+
#else
512
#include <gg/eventstream/rpc.h>
613
#include <gg/eventstream/types.h>
714
#include <gg/object.h>
8-
#include <sys/types.h>
9-
#include <stddef.h>
15+
#endif
1016

1117
typedef enum {
1218
CLIENT_TO_SERVER = 0,

mock/ggl/process_wait.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
#ifndef GGL_TEST_PROCESS_WAIT_H
2-
#define GGL_TEST_PROCESS_WAIT_H
1+
#ifndef GG_TEST_PROCESS_WAIT_H
2+
#define GG_TEST_PROCESS_WAIT_H
33

44
#ifdef __cplusplus
5-
#include <ggl/error.hpp>
5+
#include <gg/error.hpp>
66
#else
7-
#include <ggl/error.h>
7+
#include <gg/error.h>
88
#endif
99

1010
#include <sys/types.h>
1111
#include <stdbool.h>
1212

13-
GglError gg_process_wait(pid_t pid, bool *exit_status);
13+
GgError gg_process_wait(pid_t pid, bool *exit_status);
1414

1515
#endif

mock/mock.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#include "gg/ipc/mock.h"
22
#include "gg/object_compare.h"
3-
#include "inttypes.h"
4-
#include "sys/epoll.h"
53
#include <assert.h>
64
#include <errno.h>
75
#include <gg/arena.h>
@@ -24,6 +22,8 @@
2422
#include <gg/object_visit.h>
2523
#include <gg/socket.h>
2624
#include <gg/socket_epoll.h>
25+
#include <inttypes.h>
26+
#include <sys/epoll.h>
2727
#include <sys/socket.h>
2828
#include <sys/stat.h>
2929
#include <sys/un.h>
@@ -360,7 +360,7 @@ GgError gg_test_expect_packet_sequence(
360360
assert(sock_fd >= 0);
361361
assert(epoll_fd >= 0);
362362

363-
if (client_timeout < 5) {
363+
if (client_timeout <= 0) {
364364
client_timeout = 5;
365365
}
366366

@@ -377,6 +377,10 @@ GgError gg_test_expect_packet_sequence(
377377
GG_LOGE("Failed to wait for test client connect (%d).", errno);
378378
return GG_ERR_TIMEOUT;
379379
}
380+
if (epoll_ret == 0) {
381+
GG_LOGE("Client exited before connecting.");
382+
return GG_ERR_TIMEOUT;
383+
}
380384
struct sockaddr_un addr = { .sun_family = AF_UNIX, .sun_path = { 0 } };
381385
socklen_t len = sizeof(addr);
382386
client_fd = accept(sock_fd, &addr, &len);

0 commit comments

Comments
 (0)