test_gnunet_chat.h (15108B)
1 /* 2 This file is part of GNUnet. 3 Copyright (C) 2021--2024 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 <stdio.h> 29 #include <stdlib.h> 30 #include <check.h> 31 32 #define CK_DEFAULT_TIMEOUT 5 33 34 #include <gnunet/gnunet_chat_lib.h> 35 36 #define SETUP_GNUNET_CHAT_ACCOUNTS(test_call, test_accounts) \ 37 enum GNUNET_GenericReturnValue \ 38 on_setup_##test_call (void *cls, \ 39 struct GNUNET_CHAT_Context *context, \ 40 struct GNUNET_CHAT_Message *message) \ 41 { \ 42 static enum GNUNET_GenericReturnValue done = GNUNET_NO; \ 43 static size_t counter = 0; \ 44 \ 45 struct GNUNET_CHAT_Handle *handle = *( \ 46 (struct GNUNET_CHAT_Handle**) cls \ 47 ); \ 48 \ 49 enum GNUNET_CHAT_MessageKind kind; \ 50 kind = GNUNET_CHAT_message_get_kind(message); \ 51 \ 52 if (GNUNET_CHAT_KIND_CREATED_ACCOUNT == kind) \ 53 { \ 54 const struct GNUNET_CHAT_Account *account; \ 55 account = GNUNET_CHAT_message_get_account(message); \ 56 ck_assert_ptr_nonnull(account); \ 57 \ 58 fprintf(stdout, " - Setup account: %s\n", \ 59 GNUNET_CHAT_account_get_name(account)); \ 60 \ 61 const char **accounts; \ 62 for (accounts = test_accounts; *accounts; accounts++) \ 63 if (0 == strcmp(GNUNET_CHAT_account_get_name(account), \ 64 *accounts)) \ 65 break; \ 66 \ 67 if (*accounts) \ 68 counter = (counter? counter - 1 : counter); \ 69 } \ 70 \ 71 \ 72 if ((GNUNET_YES == done) && (0 == counter)) \ 73 GNUNET_CHAT_stop(handle); \ 74 \ 75 if ((GNUNET_CHAT_KIND_REFRESH != kind) || (GNUNET_YES == done)) \ 76 return GNUNET_YES; \ 77 \ 78 for (; test_accounts[counter]; counter++) \ 79 ck_assert(GNUNET_OK == GNUNET_CHAT_account_create( \ 80 handle, test_accounts[counter] \ 81 )); \ 82 \ 83 done = GNUNET_YES; \ 84 return GNUNET_YES; \ 85 } \ 86 \ 87 void \ 88 setup_##test_call (const struct GNUNET_CONFIGURATION_Handle *cfg) \ 89 { \ 90 static struct GNUNET_CHAT_Handle *handle = NULL; \ 91 handle = GNUNET_CHAT_start( \ 92 cfg, \ 93 on_setup_##test_call, \ 94 &handle \ 95 ); \ 96 \ 97 ck_assert_ptr_nonnull(handle); \ 98 } 99 100 #define CLEANUP_GNUNET_CHAT_ACCOUNTS(test_call, test_accounts) \ 101 enum GNUNET_GenericReturnValue \ 102 on_cleanup_##test_call (void *cls, \ 103 struct GNUNET_CHAT_Context *context, \ 104 struct GNUNET_CHAT_Message *message) \ 105 { \ 106 static enum GNUNET_GenericReturnValue done = GNUNET_NO; \ 107 static size_t counter = 0; \ 108 \ 109 struct GNUNET_CHAT_Handle *handle = *( \ 110 (struct GNUNET_CHAT_Handle**) cls \ 111 ); \ 112 \ 113 enum GNUNET_CHAT_MessageKind kind; \ 114 kind = GNUNET_CHAT_message_get_kind(message); \ 115 \ 116 if (GNUNET_CHAT_KIND_DELETED_ACCOUNT == kind) \ 117 { \ 118 const struct GNUNET_CHAT_Account *account; \ 119 account = GNUNET_CHAT_message_get_account(message); \ 120 ck_assert_ptr_nonnull(account); \ 121 \ 122 fprintf(stdout, " - Cleanup account: %s\n", \ 123 GNUNET_CHAT_account_get_name(account)); \ 124 \ 125 const char **accounts; \ 126 for (accounts = test_accounts; *accounts; accounts++) \ 127 if (0 == strcmp(GNUNET_CHAT_account_get_name(account), \ 128 *accounts)) \ 129 break; \ 130 \ 131 if (*accounts) \ 132 counter = (counter? counter - 1 : counter); \ 133 } \ 134 \ 135 if ((GNUNET_YES == done) && (0 == counter)) \ 136 GNUNET_CHAT_stop(handle); \ 137 \ 138 if ((GNUNET_CHAT_KIND_REFRESH != kind) || (GNUNET_YES == done)) \ 139 return GNUNET_YES; \ 140 \ 141 for (; test_accounts[counter]; counter++) \ 142 ck_assert(GNUNET_OK == GNUNET_CHAT_account_delete( \ 143 handle, test_accounts[counter] \ 144 )); \ 145 \ 146 done = GNUNET_YES; \ 147 return GNUNET_YES; \ 148 } \ 149 \ 150 void \ 151 cleanup_##test_call (const struct GNUNET_CONFIGURATION_Handle *cfg) \ 152 { \ 153 static struct GNUNET_CHAT_Handle *handle = NULL; \ 154 handle = GNUNET_CHAT_start( \ 155 cfg, \ 156 on_cleanup_##test_call, \ 157 &handle \ 158 ); \ 159 \ 160 ck_assert_ptr_nonnull(handle); \ 161 } 162 163 #define REQUIRE_GNUNET_CHAT_ACCOUNT(test_call, test_account) \ 164 const char *accounts_##test_call [] = { \ 165 test_account, NULL \ 166 }; \ 167 \ 168 SETUP_GNUNET_CHAT_ACCOUNTS(test_call, accounts_##test_call) \ 169 CLEANUP_GNUNET_CHAT_ACCOUNTS(test_call, accounts_##test_call) 170 171 #define __CREATE_GNUNET_TEST_TASK(test_call) \ 172 void \ 173 task_##test_call (void *cls, \ 174 __attribute__ ((unused)) char *const *args, \ 175 __attribute__ ((unused)) const char *cfgfile, \ 176 const struct GNUNET_CONFIGURATION_Handle *cfg) \ 177 { \ 178 ck_assert_ptr_nonnull(cls); \ 179 ck_assert_ptr_nonnull(cfg); \ 180 fprintf( \ 181 stdout, \ 182 "Stage: %s\n", \ 183 (const char*) cls \ 184 ); \ 185 test_call (cfg); \ 186 } 187 188 #define __CALL_GNUNET_TEST_TASK(test_call) \ 189 { \ 190 enum GNUNET_GenericReturnValue result; \ 191 const struct GNUNET_OS_ProjectData *data; \ 192 struct GNUNET_GETOPT_CommandLineOption options[] = { \ 193 GNUNET_GETOPT_OPTION_END \ 194 }; \ 195 \ 196 data = GNUNET_OS_project_data_gnunet (); \ 197 \ 198 char *binary = #test_call; \ 199 char *const args [] = { binary }; \ 200 \ 201 fprintf(stdout, "Running: %s\n", binary); \ 202 result = GNUNET_PROGRAM_run( \ 203 data, \ 204 1, \ 205 args, \ 206 binary, \ 207 "", \ 208 options, \ 209 task_##test_call, \ 210 binary \ 211 ); \ 212 \ 213 ck_assert(result == GNUNET_OK); \ 214 } 215 216 #define CREATE_GNUNET_TEST(test_name, test_call) \ 217 __CREATE_GNUNET_TEST_TASK(call_##test_call) \ 218 \ 219 START_TEST(test_name) \ 220 __CALL_GNUNET_TEST_TASK(call_##test_call) \ 221 END_TEST \ 222 \ 223 __CREATE_GNUNET_TEST_TASK(setup_##test_call) \ 224 __CREATE_GNUNET_TEST_TASK(cleanup_##test_call) \ 225 \ 226 void \ 227 setup_##test_name () \ 228 __CALL_GNUNET_TEST_TASK(setup_##test_call) \ 229 \ 230 void \ 231 cleanup_##test_name () \ 232 __CALL_GNUNET_TEST_TASK(cleanup_##test_call) 233 234 #define START_SUITE(suite_name, suite_title) \ 235 Suite* suite_name (void) \ 236 { \ 237 Suite *suite; \ 238 TCase *tcase; \ 239 \ 240 suite = suite_create(suite_title); 241 242 #define ADD_TEST_TO_SUITE(test_name, test_title) \ 243 tcase = tcase_create(test_title); \ 244 tcase_add_test(tcase, test_name); \ 245 \ 246 tcase_add_checked_fixture( \ 247 tcase, \ 248 setup_##test_name, \ 249 cleanup_##test_name \ 250 ); \ 251 \ 252 suite_add_tcase(suite, tcase); 253 254 #define END_SUITE \ 255 return suite; \ 256 } 257 258 #define MAIN_SUITE(suite_name, suite_check) \ 259 int main (void) \ 260 { \ 261 int tests_failed; \ 262 SRunner *runner; \ 263 \ 264 runner = srunner_create(suite_name ()); \ 265 srunner_set_fork_status(runner, CK_NOFORK); \ 266 srunner_run_all(runner, suite_check); \ 267 \ 268 tests_failed = srunner_ntests_failed(runner); \ 269 srunner_free(runner); \ 270 \ 271 return (tests_failed == 0? EXIT_SUCCESS : EXIT_FAILURE); \ 272 } 273 274 #endif /* TEST_GNUNET_CHAT_H_ */