summaryrefslogtreecommitdiffstats
path: root/fluent-bit/tests/include/aws_client_mock.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 02:57:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 02:57:58 +0000
commitbe1c7e50e1e8809ea56f2c9d472eccd8ffd73a97 (patch)
tree9754ff1ca740f6346cf8483ec915d4054bc5da2d /fluent-bit/tests/include/aws_client_mock.c
parentInitial commit. (diff)
downloadnetdata-be1c7e50e1e8809ea56f2c9d472eccd8ffd73a97.tar.xz
netdata-be1c7e50e1e8809ea56f2c9d472eccd8ffd73a97.zip
Adding upstream version 1.44.3.upstream/1.44.3upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'fluent-bit/tests/include/aws_client_mock.c')
-rw-r--r--fluent-bit/tests/include/aws_client_mock.c256
1 files changed, 256 insertions, 0 deletions
diff --git a/fluent-bit/tests/include/aws_client_mock.c b/fluent-bit/tests/include/aws_client_mock.c
new file mode 100644
index 00000000..84ee6a1e
--- /dev/null
+++ b/fluent-bit/tests/include/aws_client_mock.c
@@ -0,0 +1,256 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#include "aws_client_mock.h"
+
+#include <fluent-bit/flb_aws_util.h>
+#include <fluent-bit/flb_http_client.h>
+
+/* Vtable mocked methods */
+static struct flb_http_client *flb_aws_client_mock_vtable_request(
+ struct flb_aws_client *aws_client, int method, const char *uri, const char *body,
+ size_t body_len, struct flb_aws_header *dynamic_headers, size_t dynamic_headers_len);
+
+/* Protected structs */
+
+/* flb_aws_client_mock pointer returned by mock_generator */
+static struct flb_aws_client_mock *flb_aws_client_mock_instance = NULL;
+
+/* Generator that returns clients with the test vtable */
+static struct flb_aws_client_generator mock_generator = {
+ .create = flb_aws_client_create_mock,
+};
+
+/* Test/mock flb_aws_client vtable */
+static struct flb_aws_client_vtable mock_client_vtable = {
+ .request = flb_aws_client_mock_vtable_request,
+};
+
+/*
+ * Configure generator
+ * 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)
+{
+ flb_aws_client_mock_destroy_generator();
+ flb_aws_client_mock_instance = flb_aws_client_mock_create(request_chain);
+}
+
+/*
+ * Clean up generator's memory
+ * Cleanup should be called on exiting generator
+ */
+void flb_aws_client_mock_destroy_generator()
+{
+ if (flb_aws_client_mock_instance != NULL) {
+ flb_aws_client_mock_destroy(flb_aws_client_mock_instance);
+ }
+}
+
+/* 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)
+{
+ struct flb_aws_client_mock *mock = flb_calloc(1, sizeof(struct flb_aws_client_mock));
+
+ /* Create a surrogate aws_client and copy to mock client */
+ struct flb_aws_client *surrogate_aws_client = flb_aws_client_generator()->create();
+ mock->super = *surrogate_aws_client;
+ mock->surrogate = surrogate_aws_client;
+ memset(mock->surrogate, 0, sizeof(struct flb_aws_client));
+
+ /* Switch vtable to mock vtable */
+ mock->super.client_vtable = &mock_client_vtable;
+ mock->request_chain = request_chain;
+ mock->next_request_index = 0;
+ return mock;
+}
+
+/* Destroy flb_aws_client_mock */
+void flb_aws_client_mock_destroy(struct flb_aws_client_mock *mock)
+{
+ /* Remove from generator registry if stored */
+ if (flb_aws_client_mock_instance == mock) {
+ flb_aws_client_mock_instance = NULL;
+ }
+
+ /* Resurrect surrogate, and destroy flb_aws_client */
+ *mock->surrogate = mock->super;
+ flb_aws_client_destroy(mock->surrogate);
+
+ /* Destroy mock flb_aws_client */
+ flb_free(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)
+{
+ return (struct flb_aws_client *)mock;
+}
+
+/* Get the number of unused requests */
+int flb_aws_client_mock_count_unused_requests(struct flb_aws_client_mock *mock)
+{
+ return mock->request_chain->length - mock->next_request_index;
+}
+
+/* Set flb_aws_client_mock_instance used in mock generator */
+void flb_aws_client_mock_set_generator_instance(struct flb_aws_client_mock *mock)
+{
+ flb_aws_client_mock_instance = mock;
+}
+
+/* Set flb_aws_client_mock_instance used in mock generator */
+struct flb_aws_client_mock *flb_aws_client_mock_get_generator_instance(
+ struct flb_aws_client_mock *mock)
+{
+ return flb_aws_client_mock_instance = mock;
+}
+
+/* Get generator used in mock */
+struct flb_aws_client_generator *flb_aws_client_get_mock_generator()
+{
+ return &mock_generator;
+}
+
+/* Get the number of unused requests */
+int flb_aws_client_mock_generator_count_unused_requests()
+{
+ TEST_ASSERT(flb_aws_client_mock_instance != 0);
+ return flb_aws_client_mock_count_unused_requests(flb_aws_client_mock_instance);
+}
+
+/* Return the mock instance */
+struct flb_aws_client *flb_aws_client_create_mock()
+{
+ TEST_CHECK(flb_aws_client_mock_instance != NULL);
+ TEST_MSG(
+ "[aws_mock_client] Must initialize flb_aws_client_mock_instance before calling "
+ "flb_aws_client_create_mock()");
+ TEST_MSG(
+ "[aws_mock_client] This ouccurs when the generator is called, before tests are "
+ "initialized.");
+
+ return flb_aws_client_mock_context(flb_aws_client_mock_instance);
+}
+
+/* Mock request used by flb_aws_client mock */
+static struct flb_http_client *flb_aws_client_mock_vtable_request(
+ struct flb_aws_client *aws_client, int method, const char *uri, const char *body,
+ size_t body_len, struct flb_aws_header *dynamic_headers, size_t dynamic_headers_len)
+{
+ int h;
+ int i;
+ int ret;
+
+ /* Get access to mock */
+ struct flb_aws_client_mock *mock = (struct flb_aws_client_mock *)aws_client;
+
+ /* Check that a response is left in the chain */
+ ret = TEST_CHECK(mock->next_request_index < mock->request_chain->length);
+ if (!ret) {
+ TEST_MSG(
+ "[flb_aws_client_mock] %d mock responses provided. Attempting to call %d "
+ "times. Aborting.",
+ (int)mock->request_chain->length, (int)mock->next_request_index + 1);
+ return NULL;
+ }
+ struct flb_aws_client_mock_response *response =
+ &(mock->request_chain->responses[mock->next_request_index]);
+ struct flb_http_client *c = NULL;
+
+ /* create an http client so that we can set the response */
+ c = flb_calloc(1, sizeof(struct flb_http_client));
+ if (!c) {
+ flb_errno();
+ return NULL;
+ }
+ mk_list_init(&c->headers);
+
+ /* Response configuration */
+ for (i = 0; i < response->length; ++i) {
+ struct flb_aws_client_mock_response_config *response_config =
+ &(response->config_parameters[i]);
+ void *val1 = response_config->config_value;
+ void *val2 = response_config->config_value_2;
+
+ /* Expectations */
+ if (response_config->config_parameter == FLB_AWS_CLIENT_MOCK_EXPECT_HEADER) {
+ int header_found = FLB_FALSE;
+ /* Search for header in request */
+ for (h = 0; h < dynamic_headers_len; ++h) {
+ ret = strncmp(dynamic_headers[h].key, (char *)val1,
+ dynamic_headers[h].key_len);
+ if (ret == 0) {
+ /* Check header value */
+ ret = strncmp(dynamic_headers[h].val, (char *)val2,
+ dynamic_headers[h].val_len + 1);
+ TEST_CHECK(ret == 0);
+ TEST_MSG("[aws_mock_client] Expected Header: (%s: %s)", (char *)val1,
+ (char *)val2);
+ TEST_MSG("[aws_mock_client] Received Header: (%s: %s)", (char *)val1,
+ dynamic_headers[h].val);
+
+ header_found = FLB_TRUE;
+ }
+ }
+ TEST_CHECK(header_found);
+ TEST_MSG("[aws_mock_client] Expected Header: (%s: %s)", (char *)val1,
+ (char *)val2);
+ TEST_MSG("[aws_mock_client] Header not received");
+ }
+ else if (response_config->config_parameter == FLB_AWS_CLIENT_MOCK_EXPECT_METHOD) {
+ char *flb_http_methods[] = {
+ "FLB_HTTP_GET", "FLB_HTTP_POST", "FLB_HTTP_PUT",
+ "FLB_HTTP_HEAD", "FLB_HTTP_CONNECT", "FLB_HTTP_PATCH",
+ };
+
+ /*
+ * Check method is what is expected
+ * Typecast config value from void * -> int
+ */
+ TEST_CHECK(method == (int)(uintptr_t)val1);
+ TEST_MSG("[aws_mock_client] Expected HTTP Method: %s",
+ flb_http_methods[(int)(uintptr_t)val1]);
+ TEST_MSG("[aws_mock_client] Received HTTP Method: %s",
+ flb_http_methods[method]);
+ }
+ else if (response_config->config_parameter ==
+ FLB_AWS_CLIENT_MOCK_EXPECT_HEADER_COUNT) {
+ TEST_CHECK(dynamic_headers_len == (int)(uintptr_t)val1);
+ TEST_MSG("[aws_mock_client] Expected %d Headers", (int)(uintptr_t)val1);
+ TEST_MSG("[aws_mock_client] Received %d Headers",
+ (int)(uintptr_t)dynamic_headers_len);
+ }
+ else if (response_config->config_parameter == FLB_AWS_CLIENT_MOCK_EXPECT_URI) {
+ ret = strncmp(uri, (char *)val1, strlen((char *)val1) + 1);
+ TEST_CHECK(ret == 0);
+ TEST_MSG("[aws_mock_client] Expected URI: %s", (char *)val1);
+ TEST_MSG("[aws_mock_client] Received URI: %s", uri);
+ }
+
+ /* Replace response client */
+ else if (response_config->config_parameter ==
+ FLB_AWS_CLIENT_MOCK_CONFIG_REPLACE) {
+ flb_http_client_destroy(c);
+ c = (struct flb_http_client *)val1;
+ }
+
+ /*
+ * Response setters
+ * Set client fields using XMacro definitions
+ */
+#define EXPAND_CLIENT_RESPONSE_PARAMETER(lower, UPPER, type) \
+ else if (response_config->config_parameter == FLB_AWS_CLIENT_MOCK_SET_##UPPER) \
+ { \
+ c->resp.lower = CONVERT_##type((char *)val1); \
+ }
+#include "aws_client_mock_client_resp.def"
+#undef EXPAND_CLIENT_RESPONSE_PARAMETER
+ }
+
+ /* Increment request */
+ ++mock->next_request_index;
+
+ return c;
+};