test_gnunet_chat.h (15095B)
1 /* 2 This file is part of GNUnet. 3 Copyright (C) 2021--2024, 2026 GNUnet e.V. 4 5 GNUnet is free software: you can redistribute it and/or modify it 6 under the terms of the GNU Affero General Public License as published 7 by the Free Software Foundation, either version 3 of the License, 8 or (at your option) any later version. 9 10 GNUnet is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Affero General Public License for more details. 14 15 You should have received a copy of the GNU Affero General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 SPDX-License-Identifier: AGPL3.0-or-later 19 */ 20 /* 21 * @author Tobias Frisch 22 * @file test_gnunet_chat.h 23 */ 24 25 #ifndef TEST_GNUNET_CHAT_H_ 26 #define TEST_GNUNET_CHAT_H_ 27 28 #include <stdlib.h> 29 #include <check.h> 30 31 #define CK_DEFAULT_TIMEOUT 5 32 33 #include <gnunet/gnunet_chat_lib.h> 34 35 #define SETUP_GNUNET_CHAT_ACCOUNTS(test_call, test_accounts) \ 36 enum GNUNET_GenericReturnValue \ 37 on_setup_##test_call (void *cls, \ 38 struct GNUNET_CHAT_Context *context, \ 39 struct GNUNET_CHAT_Message *message) \ 40 { \ 41 static enum GNUNET_GenericReturnValue done = GNUNET_NO; \ 42 static size_t counter = 0; \ 43 \ 44 struct GNUNET_CHAT_Handle *handle = *( \ 45 (struct GNUNET_CHAT_Handle**) cls \ 46 ); \ 47 \ 48 enum GNUNET_CHAT_MessageKind kind; \ 49 kind = GNUNET_CHAT_message_get_kind(message); \ 50 \ 51 if (GNUNET_CHAT_KIND_CREATED_ACCOUNT == kind) \ 52 { \ 53 const struct GNUNET_CHAT_Account *account; \ 54 account = GNUNET_CHAT_message_get_account(message); \ 55 ck_assert_ptr_nonnull(account); \ 56 \ 57 fprintf(stdout, " - Setup account: %s\n", \ 58 GNUNET_CHAT_account_get_name(account)); \ 59 \ 60 const char **accounts; \ 61 for (accounts = test_accounts; *accounts; accounts++) \ 62 if (0 == strcmp(GNUNET_CHAT_account_get_name(account), \ 63 *accounts)) \ 64 break; \ 65 \ 66 if (*accounts) \ 67 counter = (counter? counter - 1 : counter); \ 68 } \ 69 \ 70 \ 71 if ((GNUNET_YES == done) && (0 == counter)) \ 72 GNUNET_CHAT_stop(handle); \ 73 \ 74 if ((GNUNET_CHAT_KIND_REFRESH != kind) || (GNUNET_YES == done)) \ 75 return GNUNET_YES; \ 76 \ 77 for (; test_accounts[counter]; counter++) \ 78 ck_assert(GNUNET_OK == GNUNET_CHAT_account_create( \ 79 handle, test_accounts[counter] \ 80 )); \ 81 \ 82 done = GNUNET_YES; \ 83 return GNUNET_YES; \ 84 } \ 85 \ 86 void \ 87 setup_##test_call (const struct GNUNET_CONFIGURATION_Handle *cfg) \ 88 { \ 89 static struct GNUNET_CHAT_Handle *handle = NULL; \ 90 handle = GNUNET_CHAT_start( \ 91 cfg, \ 92 on_setup_##test_call, \ 93 &handle \ 94 ); \ 95 \ 96 ck_assert_ptr_nonnull(handle); \ 97 } 98 99 #define CLEANUP_GNUNET_CHAT_ACCOUNTS(test_call, test_accounts) \ 100 enum GNUNET_GenericReturnValue \ 101 on_cleanup_##test_call (void *cls, \ 102 struct GNUNET_CHAT_Context *context, \ 103 struct GNUNET_CHAT_Message *message) \ 104 { \ 105 static enum GNUNET_GenericReturnValue done = GNUNET_NO; \ 106 static size_t counter = 0; \ 107 \ 108 struct GNUNET_CHAT_Handle *handle = *( \ 109 (struct GNUNET_CHAT_Handle**) cls \ 110 ); \ 111 \ 112 enum GNUNET_CHAT_MessageKind kind; \ 113 kind = GNUNET_CHAT_message_get_kind(message); \ 114 \ 115 if (GNUNET_CHAT_KIND_DELETED_ACCOUNT == kind) \ 116 { \ 117 const struct GNUNET_CHAT_Account *account; \ 118 account = GNUNET_CHAT_message_get_account(message); \ 119 ck_assert_ptr_nonnull(account); \ 120 \ 121 fprintf(stdout, " - Cleanup account: %s\n", \ 122 GNUNET_CHAT_account_get_name(account)); \ 123 \ 124 const char **accounts; \ 125 for (accounts = test_accounts; *accounts; accounts++) \ 126 if (0 == strcmp(GNUNET_CHAT_account_get_name(account), \ 127 *accounts)) \ 128 break; \ 129 \ 130 if (*accounts) \ 131 counter = (counter? counter - 1 : counter); \ 132 } \ 133 \ 134 if ((GNUNET_YES == done) && (0 == counter)) \ 135 GNUNET_CHAT_stop(handle); \ 136 \ 137 if ((GNUNET_CHAT_KIND_REFRESH != kind) || (GNUNET_YES == done)) \ 138 return GNUNET_YES; \ 139 \ 140 for (; test_accounts[counter]; counter++) \ 141 ck_assert(GNUNET_OK == GNUNET_CHAT_account_delete( \ 142 handle, test_accounts[counter] \ 143 )); \ 144 \ 145 done = GNUNET_YES; \ 146 return GNUNET_YES; \ 147 } \ 148 \ 149 void \ 150 cleanup_##test_call (const struct GNUNET_CONFIGURATION_Handle *cfg) \ 151 { \ 152 static struct GNUNET_CHAT_Handle *handle = NULL; \ 153 handle = GNUNET_CHAT_start( \ 154 cfg, \ 155 on_cleanup_##test_call, \ 156 &handle \ 157 ); \ 158 \ 159 ck_assert_ptr_nonnull(handle); \ 160 } 161 162 #define REQUIRE_GNUNET_CHAT_ACCOUNT(test_call, test_account) \ 163 const char *accounts_##test_call [] = { \ 164 test_account, NULL \ 165 }; \ 166 \ 167 SETUP_GNUNET_CHAT_ACCOUNTS(test_call, accounts_##test_call) \ 168 CLEANUP_GNUNET_CHAT_ACCOUNTS(test_call, accounts_##test_call) 169 170 #define __CREATE_GNUNET_TEST_TASK(test_call) \ 171 void \ 172 task_##test_call (void *cls, \ 173 __attribute__ ((unused)) char *const *args, \ 174 __attribute__ ((unused)) const char *cfgfile, \ 175 const struct GNUNET_CONFIGURATION_Handle *cfg) \ 176 { \ 177 ck_assert_ptr_nonnull(cls); \ 178 ck_assert_ptr_nonnull(cfg); \ 179 fprintf( \ 180 stdout, \ 181 "Stage: %s\n", \ 182 (const char*) cls \ 183 ); \ 184 test_call (cfg); \ 185 } 186 187 #define __CALL_GNUNET_TEST_TASK(test_call) \ 188 { \ 189 enum GNUNET_GenericReturnValue result; \ 190 const struct GNUNET_OS_ProjectData *data; \ 191 struct GNUNET_GETOPT_CommandLineOption options[] = { \ 192 GNUNET_GETOPT_OPTION_END \ 193 }; \ 194 \ 195 data = GNUNET_OS_project_data_gnunet (); \ 196 \ 197 char *binary = #test_call; \ 198 char *const args [] = { binary }; \ 199 \ 200 fprintf(stdout, "Running: %s\n", binary); \ 201 result = GNUNET_PROGRAM_run( \ 202 data, \ 203 1, \ 204 args, \ 205 binary, \ 206 "", \ 207 options, \ 208 task_##test_call, \ 209 binary \ 210 ); \ 211 \ 212 ck_assert(result == GNUNET_OK); \ 213 } 214 215 #define CREATE_GNUNET_TEST(test_name, test_call) \ 216 __CREATE_GNUNET_TEST_TASK(call_##test_call) \ 217 \ 218 START_TEST(test_name) \ 219 __CALL_GNUNET_TEST_TASK(call_##test_call) \ 220 END_TEST \ 221 \ 222 __CREATE_GNUNET_TEST_TASK(setup_##test_call) \ 223 __CREATE_GNUNET_TEST_TASK(cleanup_##test_call) \ 224 \ 225 void \ 226 setup_##test_name () \ 227 __CALL_GNUNET_TEST_TASK(setup_##test_call) \ 228 \ 229 void \ 230 cleanup_##test_name () \ 231 __CALL_GNUNET_TEST_TASK(cleanup_##test_call) 232 233 #define START_SUITE(suite_name, suite_title) \ 234 Suite* suite_name (void) \ 235 { \ 236 Suite *suite; \ 237 TCase *tcase; \ 238 \ 239 suite = suite_create(suite_title); 240 241 #define ADD_TEST_TO_SUITE(test_name, test_title) \ 242 tcase = tcase_create(test_title); \ 243 tcase_add_test(tcase, test_name); \ 244 \ 245 tcase_add_checked_fixture( \ 246 tcase, \ 247 setup_##test_name, \ 248 cleanup_##test_name \ 249 ); \ 250 \ 251 suite_add_tcase(suite, tcase); 252 253 #define END_SUITE \ 254 return suite; \ 255 } 256 257 #define MAIN_SUITE(suite_name, suite_check) \ 258 int main (void) \ 259 { \ 260 int tests_failed; \ 261 SRunner *runner; \ 262 \ 263 runner = srunner_create(suite_name ()); \ 264 srunner_set_fork_status(runner, CK_NOFORK); \ 265 srunner_run_all(runner, suite_check); \ 266 \ 267 tests_failed = srunner_ntests_failed(runner); \ 268 srunner_free(runner); \ 269 \ 270 return (tests_failed == 0? EXIT_SUCCESS : EXIT_FAILURE); \ 271 } 272 273 #endif /* TEST_GNUNET_CHAT_H_ */