summaryrefslogtreecommitdiffstats
path: root/fluent-bit/tests/include/aws_client_mock.h
blob: 7cdfc81066d176b12107782f1b0e46b52b4a0233 (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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
 * AWS Client Mock
 *
 * Note: AWS Client Mock is not intended to be used with asynchronously
 * running tests. A mock instance is stored and retrieved by
 * the mock generator
 */

/*
 * FLB_AWS_CLIENT_MOCK() definition
 * The following macro FLB_AWS_CLIENT_MOCK() translates a request definition
 * into a c compound literal, which constructs a mock request chain
 * at the block scope.

 * The following translation might ouccur:

    FLB_AWS_CLIENT_MOCK(
        response(
            expect("token", "aws_token")
            expect("time", "123456")
            set(STATUS, 200),
        ),
        response(
            set(STATUS, 200),
        )
    )

 * ^^^^^^^^^^^^^^^^^^^^^^^^^
 * *~~~> Translates to ~~~>*
 * *vvvvvvvvvvvvvvvvvvvvvvv*

    &(struct flb_aws_client_mock_request_chain){
        2,
        ((struct flb_aws_client_mock_response[]) { // Mock request chain
            {
                3,
                (struct flb_aws_client_mock_response_config[]){
                    ((struct flb_aws_client_mock_response_config) { // Response
 configuration FLB_AWS_CLIENT_MOCK_EXPECT_HEADER, (void *) "token", (void *) "aws_token"
                    }),
                    ((struct flb_aws_client_mock_response_config)
                        { FLB_AWS_CLIENT_MOCK_EXPECT_HEADER,
                            (void *) "time",
                            (void *) "123456"
                        }
                    )
                    ((struct flb_aws_client_mock_response_config) { // Response
 configuration FLB_AWS_CLIENT_MOCK_SET_STATUS, (void *) 200, (void *) 0
                    }),
                }
            },
            {
                1,
                &(struct flb_aws_client_mock_response_config) {
                    FLB_AWS_CLIENT_MOCK_SET_STATUS,
                    (void *) 200,
                    (void *) 0
                }
            }
        })
    }
*/

#ifndef AWS_CLIENT_MOCK_H
#define AWS_CLIENT_MOCK_H

/* Variadic Argument Counter, Counts up to 64 variadic args */
#define FLB_AWS_CLIENT_MOCK_COUNT64(...)                                                 \
    _FLB_AWS_CLIENT_MOCK_COUNT64(dummy, ##__VA_ARGS__, 63, 62, 61, 60, 59, 58, 57, 56,   \
                                 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, \
                                 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, \
                                 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, \
                                 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define _FLB_AWS_CLIENT_MOCK_COUNT64(                                                    \
    x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, \
    x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31, x32, x33, x34, x35, \
    x36, x37, x38, x39, x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x50, x51, x52, \
    x53, x54, x55, x56, x57, x58, x59, x60, x61, x62, x63, count, ...)                   \
    count

#define FLB_AWS_CLIENT_MOCK_EVAL(...) __VA_ARGS__
#define FLB_AWS_CLIENT_MOCK_EMPTY()
#define FLB_AWS_CLIENT_MOCK_DIFER(...) \
    FLB_AWS_CLIENT_MOCK_EVAL FLB_AWS_CLIENT_MOCK_EMPTY()(__VA_ARGS__)

/* Make block-scope addressable compound-literal request chain */
#define FLB_AWS_CLIENT_MOCK(...)                                          \
    FLB_AWS_CLIENT_MOCK_EVAL(&(struct flb_aws_client_mock_request_chain){ \
        FLB_AWS_CLIENT_MOCK_COUNT64(__VA_ARGS__),                         \
        (struct flb_aws_client_mock_response[]){__VA_ARGS__}})

#define FLB_AWS_CLIENT_MOCK_RESPONSE(...)                  \
    {                                                      \
        FLB_AWS_CLIENT_MOCK_COUNT64(__VA_ARGS__),          \
            (struct flb_aws_client_mock_response_config[]) \
        {                                                  \
            __VA_ARGS__                                    \
        }                                                  \
    }

#define FLB_AWS_CLIENT_MOCK_VFUNC___(name, n) name##n
#define FLB_AWS_CLIENT_MOCK_VFUNC(name, n) FLB_AWS_CLIENT_MOCK_VFUNC___(name, n)

#define FLB_AWS_CLIENT_MOCK_STAGE_CONFIG(mode, parameter, value, ...) \
    ((struct flb_aws_client_mock_response_config){                    \
        FLB_AWS_CLIENT_MOCK_##mode##parameter, (void *)value,         \
        FLB_AWS_CLIENT_MOCK_VFUNC(                                    \
            FLB_AWS_CLIENT_MOCK_STAGE_CONFIG_OPTIONAL_VALUES_,        \
            FLB_AWS_CLIENT_MOCK_COUNT64(__VA_ARGS__))(__VA_ARGS__)})

#define FLB_AWS_CLIENT_MOCK_STAGE_CONFIG_OPTIONAL_VALUES_1(value) (void *)value
#define FLB_AWS_CLIENT_MOCK_STAGE_CONFIG_OPTIONAL_VALUES_0() (void *)0

// DIFER() allows for correct arg count
#define response(...) FLB_AWS_CLIENT_MOCK_DIFER(FLB_AWS_CLIENT_MOCK_RESPONSE(__VA_ARGS__))
#define expect(...) \
    FLB_AWS_CLIENT_MOCK_DIFER(FLB_AWS_CLIENT_MOCK_STAGE_CONFIG(EXPECT_, __VA_ARGS__))
#define config(...) \
    FLB_AWS_CLIENT_MOCK_DIFER(FLB_AWS_CLIENT_MOCK_STAGE_CONFIG(CONFIG_, __VA_ARGS__))
#define set(...) \
    FLB_AWS_CLIENT_MOCK_DIFER(FLB_AWS_CLIENT_MOCK_STAGE_CONFIG(SET_, __VA_ARGS__))

/* Includes */
#include <fluent-bit/flb_aws_util.h>

#include "../lib/acutest/acutest.h"

/* Enum */
enum flb_aws_client_mock_response_config_parameter {
    FLB_AWS_CLIENT_MOCK_EXPECT_METHOD,  // int: FLB_HTTP_<method> where method = { "GET",
                                        // "POST", "PUT", "HEAD", "CONNECT", "PATCH" }
    FLB_AWS_CLIENT_MOCK_EXPECT_HEADER,  // (string, string): (header key, header value)
    FLB_AWS_CLIENT_MOCK_EXPECT_HEADER_COUNT,  // int: header count
    FLB_AWS_CLIENT_MOCK_EXPECT_URI,           // string: uri
    FLB_AWS_CLIENT_MOCK_CONFIG_REPLACE,  // flb_http_client ptr. Client can be null if
                                         // needed
// Define all client fields using XMacro definitions
#define EXPAND_CLIENT_RESPONSE_PARAMETER(x, UPPER, y) FLB_AWS_CLIENT_MOCK_SET_##UPPER,
#include "aws_client_mock_client_resp.def"
#undef EXPAND_CLIENT_RESPONSE_PARAMETER
};

/* Structs */
struct flb_aws_client_mock_response_config {
    enum flb_aws_client_mock_response_config_parameter config_parameter;
    void *config_value;  // Most configuration must be passed in string format.
    void *config_value_2;
};

struct flb_aws_client_mock_response {
    size_t length;
    struct flb_aws_client_mock_response_config *config_parameters;
};

struct flb_aws_client_mock_request_chain {
    size_t length;
    struct flb_aws_client_mock_response *responses;
};

struct flb_aws_client_mock {
    /* This member must come first in the struct's memory layout
     * so that this struct can mock flb_aws_client context */
    struct flb_aws_client super;
    struct flb_aws_client *surrogate;

    /* Additional data members added to mock */
    struct flb_aws_client_mock_request_chain *request_chain;
    size_t next_request_index;
};

/* Declarations */

/*
 * Configure mock generator to be returned by flb_aws_client_get_mock_generator()
 * Generator is injected into credential providers and returns a mocked
 * flb_aws_client instance.
 *
 * Note: Automatically creates mock and wires to generator
 *       Destroys any existing mock in generator
 */
void flb_aws_client_mock_configure_generator(
    struct flb_aws_client_mock_request_chain *request_chain);

/*
 * Clean up generator memory
 * Note: Cleanup should be called at the end of each test
 */
void flb_aws_client_mock_destroy_generator();

/* Create Mock of flb_aws_client */
struct flb_aws_client_mock *flb_aws_client_mock_create(
    struct flb_aws_client_mock_request_chain *request_chain);

/*
 * Destroy flb_aws_client_mock
 * Note: flb_aws_client_destroy must not be used prior to flb_aws_client_mock_destroy.
 */
void flb_aws_client_mock_destroy(struct flb_aws_client_mock *mock);

/* Get the number of unused requests */
int flb_aws_client_mock_count_unused_requests(struct flb_aws_client_mock *mock);

/* Return a Mocked flb_aws_client, ready for injection */
struct flb_aws_client *flb_aws_client_mock_context(struct flb_aws_client_mock *mock);

/* Generator Methods */
/* Get/set flb_aws_client_mock_instance used by mock generator */
void flb_aws_client_mock_set_generator_instance(struct flb_aws_client_mock *mock);
struct flb_aws_client_mock *flb_aws_client_mock_get_generator_instance(
    struct flb_aws_client_mock *mock);

int flb_aws_client_mock_generator_count_unused_requests();

/* Substitute Methods */
/* Get generator used in mock */
struct flb_aws_client_generator *flb_aws_client_get_mock_generator();

/* Return the mock instance */
struct flb_aws_client *flb_aws_client_create_mock();

#endif /* AWS_CLIENT_MOCK_H */