summaryrefslogtreecommitdiffstats
path: root/tests/test_server.h
blob: cbcd4e0add8f1ec69f35368a614ce451b49897ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/**
 * @file test_server.h
 * @brief A throwaway HTTP/1.1 server on a random loopback port.
 *
 * The suite points the client at one of these through `base_url`. Nothing is
 * mocked: the code path under test is the one that runs in production, libcurl
 * and response-body reading included. It doubles as the test that `base_url`
 * works, since without it none of the suite would run.
 */
#ifndef CEPIS_TEST_SERVER_H
#define CEPIS_TEST_SERVER_H

#include <stddef.h>

typedef struct test_server test_server_t;

/** One canned reply. */
typedef struct {
        long status;
        /** Body, copied. `NULL` means empty. */
        const char *body;
        /** Extra header lines without the trailing CRLF, or `NULL`. */
        const char *headers;
} ts_reply_t;

/** @brief Start a server. @return `NULL` if it could not bind or spawn. */
test_server_t *ts_start(void);

/** @brief Stop and release a server. `NULL` is ignored. */
void ts_stop(test_server_t *server);

/** @brief `http://127.0.0.1:PORT`, owned by the server. */
const char *ts_base_url(const test_server_t *server);

/** @brief Register one reply for @p path, replacing any previous route. */
void ts_respond(test_server_t *server, const char *path, long status,
                const char *body, const char *headers);

/**
 * @brief Register a sequence of replies for @p path.
 *
 * Each request consumes the next entry; the last one repeats once the sequence
 * runs out. This is how retrying is tested.
 */
void ts_respond_seq(test_server_t *server, const char *path,
                    const ts_reply_t *replies, size_t count);

/**
 * @brief Register the sequence used for any path with no explicit route.
 *
 * Used by the chunking test, where the request paths are thousands of
 * characters long and matching them exactly buys nothing.
 */
void ts_respond_default(test_server_t *server, const ts_reply_t *replies,
                        size_t count);

/** @brief How many requests so far had a path starting with @p prefix. */
size_t ts_count(test_server_t *server, const char *prefix);

/** @brief How many requests the server has served in total. */
size_t ts_total(test_server_t *server);

/**
 * @brief The path of request @p index, or `NULL` when there is no such
 *        request. Owned by the server.
 */
const char *ts_path(test_server_t *server, size_t index);

#endif