|
| 1 | +#include "sentry_core.h" |
| 2 | +#include "sentry_database.h" |
| 3 | +#include "sentry_envelope.h" |
| 4 | +#include "sentry_options.h" |
| 5 | +#include "sentry_path.h" |
| 6 | +#include "sentry_testsupport.h" |
| 7 | +#include "sentry_uuid.h" |
| 8 | +#include "sentry_value.h" |
| 9 | + |
| 10 | +#ifdef SENTRY_PLATFORM_WINDOWS |
| 11 | +# include <windows.h> |
| 12 | +#else |
| 13 | +# include <utime.h> |
| 14 | +#endif |
| 15 | + |
| 16 | +static int |
| 17 | +set_file_mtime(const sentry_path_t *path, time_t mtime) |
| 18 | +{ |
| 19 | +#ifdef SENTRY_PLATFORM_WINDOWS |
| 20 | + HANDLE h = CreateFileW(path->path_w, FILE_WRITE_ATTRIBUTES, 0, NULL, |
| 21 | + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); |
| 22 | + ULARGE_INTEGER ft |
| 23 | + = { (uint64_t)(mtime * 10000000ULL + 116444736000000000ULL) }; |
| 24 | + BOOL rv = SetFileTime(h, NULL, NULL, (FILETIME *)&ft); |
| 25 | + CloseHandle(h); |
| 26 | + return rv ? 0 : -1; |
| 27 | +#else |
| 28 | + struct utimbuf times = { .modtime = mtime, .actime = mtime }; |
| 29 | + return utime(path->path, ×); |
| 30 | +#endif |
| 31 | +} |
| 32 | + |
| 33 | +SENTRY_TEST(cache_keep) |
| 34 | +{ |
| 35 | + SENTRY_TEST_OPTIONS_NEW(options); |
| 36 | + sentry_options_set_dsn( options, "https://[email protected]/42"); |
| 37 | + sentry_options_set_cache_keep(options, true); |
| 38 | + sentry_init(options); |
| 39 | + |
| 40 | + sentry_path_t *cache_path |
| 41 | + = sentry__path_join_str(options->database_path, "cache"); |
| 42 | + TEST_ASSERT(!!cache_path); |
| 43 | + TEST_ASSERT(sentry__path_remove_all(cache_path) == 0); |
| 44 | + |
| 45 | + sentry_path_t *old_run_path |
| 46 | + = sentry__path_join_str(options->database_path, "old.run"); |
| 47 | + TEST_ASSERT(!!old_run_path); |
| 48 | + TEST_ASSERT(sentry__path_create_dir_all(old_run_path) == 0); |
| 49 | + |
| 50 | + sentry_envelope_t *envelope = sentry__envelope_new(); |
| 51 | + TEST_ASSERT(!!envelope); |
| 52 | + sentry_uuid_t event_id = sentry_uuid_new_v4(); |
| 53 | + sentry_value_t event = sentry__value_new_event_with_id(&event_id); |
| 54 | + sentry__envelope_add_event(envelope, event); |
| 55 | + |
| 56 | + char *envelope_filename = sentry__uuid_as_filename(&event_id, ".envelope"); |
| 57 | + TEST_ASSERT(!!envelope_filename); |
| 58 | + sentry_path_t *old_envelope_path |
| 59 | + = sentry__path_join_str(old_run_path, envelope_filename); |
| 60 | + TEST_ASSERT( |
| 61 | + sentry_envelope_write_to_path(envelope, old_envelope_path) == 0); |
| 62 | + sentry_envelope_free(envelope); |
| 63 | + |
| 64 | + sentry_path_t *cached_envelope_path |
| 65 | + = sentry__path_join_str(cache_path, envelope_filename); |
| 66 | + TEST_ASSERT(!!cached_envelope_path); |
| 67 | + |
| 68 | + TEST_ASSERT(sentry__path_is_file(old_envelope_path)); |
| 69 | + TEST_ASSERT(!sentry__path_is_file(cached_envelope_path)); |
| 70 | + |
| 71 | + sentry__process_old_runs(options, 0); |
| 72 | + |
| 73 | + TEST_ASSERT(!sentry__path_is_file(old_envelope_path)); |
| 74 | + TEST_ASSERT(sentry__path_is_file(cached_envelope_path)); |
| 75 | + |
| 76 | + sentry__path_free(old_envelope_path); |
| 77 | + sentry__path_free(cached_envelope_path); |
| 78 | + sentry__path_free(old_run_path); |
| 79 | + sentry__path_free(cache_path); |
| 80 | + sentry_free(envelope_filename); |
| 81 | + sentry_close(); |
| 82 | +} |
| 83 | + |
| 84 | +SENTRY_TEST(cache_max_size) |
| 85 | +{ |
| 86 | + SENTRY_TEST_OPTIONS_NEW(options); |
| 87 | + sentry_options_set_dsn( options, "https://[email protected]/42"); |
| 88 | + sentry_options_set_cache_keep(options, true); |
| 89 | + sentry_options_set_cache_max_size(options, 10); // 10 kb |
| 90 | + sentry_init(options); |
| 91 | + |
| 92 | + sentry_path_t *cache_path |
| 93 | + = sentry__path_join_str(options->database_path, "cache"); |
| 94 | + TEST_ASSERT(!!cache_path); |
| 95 | + TEST_ASSERT(sentry__path_remove_all(cache_path) == 0); |
| 96 | + TEST_ASSERT(sentry__path_create_dir_all(cache_path) == 0); |
| 97 | + |
| 98 | + // 10 x 5 kb files |
| 99 | + for (int i = 0; i < 10; i++) { |
| 100 | + sentry_uuid_t event_id = sentry_uuid_new_v4(); |
| 101 | + char *filename = sentry__uuid_as_filename(&event_id, ".envelope"); |
| 102 | + TEST_ASSERT(!!filename); |
| 103 | + sentry_path_t *filepath = sentry__path_join_str(cache_path, filename); |
| 104 | + sentry_free(filename); |
| 105 | + |
| 106 | + sentry_filewriter_t *fw = sentry__filewriter_new(filepath); |
| 107 | + TEST_ASSERT(!!fw); |
| 108 | + for (int j = 0; j < 500; j++) { |
| 109 | + sentry__filewriter_write(fw, "0123456789", 10); |
| 110 | + } |
| 111 | + TEST_CHECK_INT_EQUAL(sentry__filewriter_byte_count(fw), 5000); |
| 112 | + sentry__filewriter_free(fw); |
| 113 | + sentry__path_free(filepath); |
| 114 | + } |
| 115 | + |
| 116 | + sentry__cleanup_cache(options); |
| 117 | + |
| 118 | + int cache_count = 0; |
| 119 | + size_t cache_size = 0; |
| 120 | + sentry_pathiter_t *iter = sentry__path_iter_directory(cache_path); |
| 121 | + const sentry_path_t *entry; |
| 122 | + while (iter && (entry = sentry__pathiter_next(iter)) != NULL) { |
| 123 | + cache_count++; |
| 124 | + cache_size += sentry__path_get_size(entry); |
| 125 | + } |
| 126 | + sentry__pathiter_free(iter); |
| 127 | + |
| 128 | + TEST_CHECK_INT_EQUAL(cache_count, 2); |
| 129 | + TEST_CHECK(cache_size <= 10 * 1024); |
| 130 | + |
| 131 | + sentry__path_free(cache_path); |
| 132 | + sentry_close(); |
| 133 | +} |
| 134 | + |
| 135 | +SENTRY_TEST(cache_max_age) |
| 136 | +{ |
| 137 | + SENTRY_TEST_OPTIONS_NEW(options); |
| 138 | + sentry_options_set_dsn( options, "https://[email protected]/42"); |
| 139 | + sentry_options_set_cache_keep(options, true); |
| 140 | + sentry_options_set_cache_max_age(options, 3); // 3 days |
| 141 | + sentry_init(options); |
| 142 | + |
| 143 | + sentry_path_t *cache_path |
| 144 | + = sentry__path_join_str(options->database_path, "cache"); |
| 145 | + TEST_ASSERT(!!cache_path); |
| 146 | + TEST_ASSERT(sentry__path_remove_all(cache_path) == 0); |
| 147 | + TEST_ASSERT(sentry__path_create_dir_all(cache_path) == 0); |
| 148 | + |
| 149 | + // 10 files, 0-9 days old |
| 150 | + time_t now = time(NULL); |
| 151 | + for (int i = 0; i < 10; i++) { |
| 152 | + sentry_uuid_t event_id = sentry_uuid_new_v4(); |
| 153 | + char *filename = sentry__uuid_as_filename(&event_id, ".envelope"); |
| 154 | + TEST_ASSERT(!!filename); |
| 155 | + sentry_path_t *filepath = sentry__path_join_str(cache_path, filename); |
| 156 | + sentry_free(filename); |
| 157 | + |
| 158 | + TEST_ASSERT(sentry__path_touch(filepath) == 0); |
| 159 | + time_t mtime = now - (i * 24 * 60 * 60); // N days ago |
| 160 | + TEST_CHECK(set_file_mtime(filepath, mtime) == 0); |
| 161 | + sentry__path_free(filepath); |
| 162 | + } |
| 163 | + |
| 164 | + sentry__cleanup_cache(options); |
| 165 | + |
| 166 | + int cache_count = 0; |
| 167 | + sentry_pathiter_t *iter = sentry__path_iter_directory(cache_path); |
| 168 | + const sentry_path_t *entry; |
| 169 | + while (iter && (entry = sentry__pathiter_next(iter)) != NULL) { |
| 170 | + cache_count++; |
| 171 | + time_t mtime = sentry__path_get_mtime(entry); |
| 172 | + TEST_CHECK(now - mtime <= (3 * 24 * 60 * 60)); |
| 173 | + } |
| 174 | + sentry__pathiter_free(iter); |
| 175 | + |
| 176 | + TEST_CHECK_INT_EQUAL(cache_count, 4); |
| 177 | + |
| 178 | + sentry__path_free(cache_path); |
| 179 | + sentry_close(); |
| 180 | +} |
0 commit comments