39#define MOCK_PORT 19090
54 if (strcmp(req->
method,
"GET") == 0 &&
55 strcmp(req->
path,
"/api/test") == 0) {
79int main(
int argc,
char* argv[]) {
83 while ((
getoptret = getopt(argc, argv,
"V:h")) != -1) {
86 if (strcmp(optarg,
"LOG_DEBUG") == 0)
88 else if (strcmp(optarg,
"LOG_INFO") == 0)
90 else if (strcmp(optarg,
"LOG_NOTICE") == 0)
92 else if (strcmp(optarg,
"LOG_ERR") == 0)
97 fprintf(stderr,
"Usage: %s [-V LOG_LEVEL]\n", argv[0]);
106 fprintf(stderr,
"FAIL: could not start mock server\n");
109 printf(
"CHECK start server ... PASS\n");
114 fprintf(stderr,
"FAIL: could not create server thread\n");
123 SOCKET sock_fd = INVALID_SOCKET;
125 struct addrinfo hints;
126 struct addrinfo* res = NULL;
127 memset(&hints, 0,
sizeof(hints));
128 hints.ai_family = AF_INET;
129 hints.ai_socktype = SOCK_STREAM;
132 if (getaddrinfo(
"127.0.0.1",
port_str, &hints, &res) != 0 || !res) {
133 fprintf(stderr,
"FAIL: getaddrinfo\n");
135 pthread_join(thr, NULL);
139 sock_fd = socket(res->ai_family, res->ai_socktype,
141 if (sock_fd == INVALID_SOCKET ||
142 connect(sock_fd, res->ai_addr, (socklen_t)res->ai_addrlen) != 0) {
143 fprintf(stderr,
"FAIL: connect\n");
146 pthread_join(thr, NULL);
154 const char* http_req =
155 "GET /api/test HTTP/1.1\r\n"
156 "Host: localhost\r\n"
157 "Connection: close\r\n"
159 ssize_t sent = send(sock_fd, http_req, NETW_BUFLEN_CAST(strlen(http_req)), 0);
161 fprintf(stderr,
"FAIL: send\n");
162 closesocket(sock_fd);
164 pthread_join(thr, NULL);
171 memset(resp_buf, 0,
sizeof(resp_buf));
174 while ((nr = recv(sock_fd, resp_buf + total,
175 NETW_BUFLEN_CAST(
sizeof(resp_buf) - 1 - (
size_t)total), 0)) > 0) {
178 closesocket(sock_fd);
180 printf(
"Response:\n%s\n", resp_buf);
184 if (strstr(resp_buf,
"200") == NULL) {
185 fprintf(stderr,
"FAIL: expected 200 in response\n");
188 if (strstr(resp_buf,
"{\"status\":\"ok\"}") == NULL) {
189 fprintf(stderr,
"FAIL: expected JSON body in response\n");
192 printf(
"CHECK GET /api/test ... %s\n", pass ?
"PASS" :
"FAIL");
196 pthread_join(thr, NULL);
199 printf(
"CHECK cleanup ... PASS\n");
static void * server_thread(void *arg)
Thread function that runs the server accept loop.
#define MOCK_PORT
mock server port
static void on_request(N_HTTP_REQUEST *req, N_HTTP_RESPONSE *resp, void *user_data)
Request handler: returns JSON for GET /api/test, 404 otherwise.
static N_MOCK_SERVER * g_server
global server pointer for thread
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_DEBUG
debug-level messages
#define LOG_ERR
error conditions
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL )
#define LOG_NOTICE
normal but significant condition
#define LOG_INFO
informational
N_STR * char_to_nstr(const char *src)
Convert a char into a N_STR, short version.
N_STR * body
response body
char path[2048]
request path
char method[16]
HTTP method.
int status_code
HTTP status code.
char content_type[128]
Content-Type header value.
void n_mock_server_free(N_MOCK_SERVER **server)
Free a mock server and close the listening socket.
void n_mock_server_stop(N_MOCK_SERVER *server)
Signal the mock server to stop accepting connections.
int SOCKET
default socket declaration
void n_mock_server_run(N_MOCK_SERVER *server)
Run the mock server accept loop.
N_MOCK_SERVER * n_mock_server_start(int port, void(*on_request)(N_HTTP_REQUEST *, N_HTTP_RESPONSE *, void *), void *user_data)
Start a mock HTTP server: set up listener and return immediately.
parsed HTTP request for mock server callback
HTTP response to send from mock server callback.
Common headers and low-level functions & define.
N_STR and string function declaration.