|
1 | 1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | 2 | #include <fluent-bit.h> |
3 | 3 | #include "flb_tests_runtime.h" |
| 4 | +#include "../include/flb_tests_tmpdir.h" |
| 5 | +#include <errno.h> |
| 6 | + |
| 7 | +#ifdef FLB_SYSTEM_WINDOWS |
| 8 | +#include <windows.h> |
| 9 | +#else |
| 10 | +#include <dirent.h> |
| 11 | +#include <sys/stat.h> |
| 12 | +#endif |
4 | 13 |
|
5 | 14 | /* Test data */ |
6 | 15 | #include "data/td/json_td.h" /* JSON_TD */ |
|
14 | 23 | <HostId>Uuag1LuByRx9e6j5Onimru9pO4ZVKnJ2Qz7/C1NPcfTWAtRPfTaOFg==</HostId>\ |
15 | 24 | </Error>" |
16 | 25 |
|
| 26 | +static int count_files_recursive(const char *path) |
| 27 | +{ |
| 28 | +#ifdef FLB_SYSTEM_WINDOWS |
| 29 | + WIN32_FIND_DATAA data; |
| 30 | + HANDLE handle; |
| 31 | + char pattern[2048]; |
| 32 | + char child[2048]; |
| 33 | + int total = 0; |
| 34 | + |
| 35 | + snprintf(pattern, sizeof(pattern), "%s\\*", path); |
| 36 | + handle = FindFirstFileA(pattern, &data); |
| 37 | + if (handle == INVALID_HANDLE_VALUE) { |
| 38 | + return 0; |
| 39 | + } |
| 40 | + |
| 41 | + do { |
| 42 | + if (strcmp(data.cFileName, ".") == 0 || strcmp(data.cFileName, "..") == 0) { |
| 43 | + continue; |
| 44 | + } |
| 45 | + |
| 46 | + snprintf(child, sizeof(child), "%s\\%s", path, data.cFileName); |
| 47 | + if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { |
| 48 | + total += count_files_recursive(child); |
| 49 | + } |
| 50 | + else { |
| 51 | + total++; |
| 52 | + } |
| 53 | + } while (FindNextFileA(handle, &data) != 0); |
| 54 | + |
| 55 | + FindClose(handle); |
| 56 | + return total; |
| 57 | +#else |
| 58 | + DIR *dir; |
| 59 | + struct dirent *entry; |
| 60 | + struct stat st; |
| 61 | + char child[2048]; |
| 62 | + int total = 0; |
| 63 | + |
| 64 | + dir = opendir(path); |
| 65 | + if (dir == NULL) { |
| 66 | + return 0; |
| 67 | + } |
| 68 | + |
| 69 | + while ((entry = readdir(dir)) != NULL) { |
| 70 | + if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { |
| 71 | + continue; |
| 72 | + } |
| 73 | + |
| 74 | + snprintf(child, sizeof(child), "%s/%s", path, entry->d_name); |
| 75 | + if (stat(child, &st) != 0) { |
| 76 | + continue; |
| 77 | + } |
| 78 | + |
| 79 | + if (S_ISDIR(st.st_mode)) { |
| 80 | + total += count_files_recursive(child); |
| 81 | + } |
| 82 | + else if (S_ISREG(st.st_mode)) { |
| 83 | + total++; |
| 84 | + } |
| 85 | + } |
| 86 | + |
| 87 | + closedir(dir); |
| 88 | + return total; |
| 89 | +#endif |
| 90 | +} |
| 91 | + |
| 92 | +static int ensure_test_directory(const char *path) |
| 93 | +{ |
| 94 | +#ifdef FLB_SYSTEM_WINDOWS |
| 95 | + WIN32_FILE_ATTRIBUTE_DATA attributes; |
| 96 | + |
| 97 | + if (flb_utils_mkdir(path, 0777) == 0) { |
| 98 | + return 0; |
| 99 | + } |
| 100 | + |
| 101 | + if (GetFileAttributesExA(path, GetFileExInfoStandard, &attributes) != 0 && |
| 102 | + (attributes.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { |
| 103 | + return 0; |
| 104 | + } |
| 105 | + |
| 106 | + return -1; |
| 107 | +#else |
| 108 | + struct stat st; |
| 109 | + |
| 110 | + if (flb_utils_mkdir(path, 0777) == 0) { |
| 111 | + return 0; |
| 112 | + } |
| 113 | + |
| 114 | + if (errno == EEXIST && stat(path, &st) == 0 && S_ISDIR(st.st_mode)) { |
| 115 | + return 0; |
| 116 | + } |
| 117 | + |
| 118 | + return -1; |
| 119 | +#endif |
| 120 | +} |
| 121 | + |
17 | 122 | void flb_test_s3_multipart_success(void) |
18 | 123 | { |
19 | 124 | int ret; |
@@ -800,13 +905,73 @@ void flb_test_s3_default_retry_limit(void) |
800 | 905 | unsetenv("TEST_PutObject_CALL_COUNT"); |
801 | 906 | } |
802 | 907 |
|
| 908 | +void flb_test_s3_default_retry_exhausted_action_quarantine(void) |
| 909 | +{ |
| 910 | + int ret; |
| 911 | + flb_ctx_t *ctx; |
| 912 | + int in_ffd; |
| 913 | + int out_ffd; |
| 914 | + int file_count; |
| 915 | + char postfix[128]; |
| 916 | + char *store_dir; |
| 917 | + |
| 918 | + snprintf(postfix, sizeof(postfix), |
| 919 | + "/flb-s3-test-default-action-%u", (unsigned) rand()); |
| 920 | + store_dir = flb_test_tmpdir_cat(postfix); |
| 921 | + TEST_CHECK(store_dir != NULL); |
| 922 | + TEST_CHECK(ensure_test_directory(store_dir) == 0); |
| 923 | + |
| 924 | + setenv("FLB_S3_PLUGIN_UNDER_TEST", "true", 1); |
| 925 | + setenv("TEST_PUT_OBJECT_ERROR", ERROR_ACCESS_DENIED, 1); |
| 926 | + |
| 927 | + ctx = flb_create(); |
| 928 | + |
| 929 | + in_ffd = flb_input(ctx, (char *) "lib", NULL); |
| 930 | + TEST_CHECK(in_ffd >= 0); |
| 931 | + flb_input_set(ctx, in_ffd, "tag", "test", NULL); |
| 932 | + |
| 933 | + out_ffd = flb_output(ctx, (char *) "s3", NULL); |
| 934 | + TEST_CHECK(out_ffd >= 0); |
| 935 | + flb_output_set(ctx, out_ffd, "match", "*", NULL); |
| 936 | + flb_output_set(ctx, out_ffd, "region", "us-west-2", NULL); |
| 937 | + flb_output_set(ctx, out_ffd, "bucket", "fluent", NULL); |
| 938 | + flb_output_set(ctx, out_ffd, "use_put_object", "true", NULL); |
| 939 | + flb_output_set(ctx, out_ffd, "total_file_size", "5M", NULL); |
| 940 | + flb_output_set(ctx, out_ffd, "upload_timeout", "6s", NULL); |
| 941 | + flb_output_set(ctx, out_ffd, "store_dir", store_dir, NULL); |
| 942 | + flb_output_set(ctx, out_ffd, "Retry_Limit", "1", NULL); |
| 943 | + /* do not set retry_exhausted_action to validate default behavior */ |
| 944 | + |
| 945 | + ret = flb_start(ctx); |
| 946 | + TEST_CHECK(ret == 0); |
| 947 | + |
| 948 | + unsetenv("TEST_PutObject_CALL_COUNT"); |
| 949 | + flb_lib_push(ctx, in_ffd, (char *) JSON_TD, (int) sizeof(JSON_TD) - 1); |
| 950 | + sleep(10); |
| 951 | + |
| 952 | + file_count = count_files_recursive(store_dir); |
| 953 | + flb_stop(ctx); |
| 954 | + flb_destroy(ctx); |
| 955 | + |
| 956 | + TEST_CHECK_(file_count > 0, |
| 957 | + "Expected quarantined file(s) in store_dir, got %d", |
| 958 | + file_count); |
| 959 | + |
| 960 | + unsetenv("FLB_S3_PLUGIN_UNDER_TEST"); |
| 961 | + unsetenv("TEST_PUT_OBJECT_ERROR"); |
| 962 | + unsetenv("TEST_PutObject_CALL_COUNT"); |
| 963 | + |
| 964 | + flb_free(store_dir); |
| 965 | +} |
| 966 | + |
803 | 967 | /* Test list */ |
804 | 968 | TEST_LIST = { |
805 | 969 | {"multipart_success", flb_test_s3_multipart_success }, |
806 | 970 | {"putobject_success", flb_test_s3_putobject_success }, |
807 | 971 | {"putobject_error", flb_test_s3_putobject_error }, |
808 | 972 | {"putobject_retry_limit_semantics", flb_test_s3_putobject_retry_limit_semantics }, |
809 | 973 | {"default_retry_limit", flb_test_s3_default_retry_limit }, |
| 974 | + {"default_retry_exhausted_action_quarantine", flb_test_s3_default_retry_exhausted_action_quarantine }, |
810 | 975 | {"create_upload_error", flb_test_s3_create_upload_error }, |
811 | 976 | {"upload_part_error", flb_test_s3_upload_part_error }, |
812 | 977 | {"complete_upload_error", flb_test_s3_complete_upload_error }, |
|
0 commit comments