/* This file is part of GNUnet. Copyright (C) 2013 GNUnet e.V. GNUnet is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . SPDX-License-Identifier: AGPL3.0-or-later */ /** * @file identity/test_identity.c * @brief testcase for identity service * @author Christian Grothoff */ #include "platform.h" #include "gnunet_util_lib.h" #include "gnunet_identity_service.h" #include "gnunet_testing_lib.h" #define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 10) /** * Return value from 'main'. */ static int res; /** * Handle to identity service. */ static struct GNUNET_IDENTITY_Handle *h; /** * Handle to identity operation. */ static struct GNUNET_IDENTITY_Operation *op; /** * Handle for task for timeout termination. */ static struct GNUNET_SCHEDULER_Task *endbadly_task; #define CHECK(cond) \ do \ { \ if (!(cond)) \ { \ GNUNET_break(0); \ end(); \ return; \ } \ } while (0) /** * Clean up all resources used. */ static void cleanup(void *cls) { (void)cls; if (NULL != op) { GNUNET_IDENTITY_cancel(op); op = NULL; } if (NULL != h) { GNUNET_IDENTITY_disconnect(h); h = NULL; } } /** * Termiante the testcase (failure). * * @param cls NULL */ static void endbadly(void *cls) { GNUNET_SCHEDULER_shutdown(); res = 1; } /** * Termiante the testcase. */ static void end() { if (NULL != endbadly_task) { GNUNET_SCHEDULER_cancel(endbadly_task); endbadly_task = NULL; } GNUNET_SCHEDULER_shutdown(); } /** * Continuation called from successful delete operation. * * @param cls NULL * @param emsg (should also be NULL) */ static void delete_cont(void *cls, const char *emsg) { op = NULL; CHECK(NULL == emsg); res = 0; end(); } /** * Continuation called from expected-to-fail rename operation. * * @param cls NULL * @param emsg (should also be NULL) */ static void get_cb(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *identifier) { op = NULL; CHECK(NULL != ego); CHECK(NULL != identifier); CHECK(0 == strcmp(identifier, "test-id")); op = GNUNET_IDENTITY_delete(h, "test-id", &delete_cont, NULL); } /** * Called with events about egos. * * @param cls NULL * @param ego ego handle * @param ego_ctx context for application to store data for this ego * (during the lifetime of this process, initially NULL) * @param identifier identifier assigned by the user for this ego, * NULL if the user just deleted the ego and it * must thus no longer be used */ static void dummy_cb(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *identifier) { (void)cls; (void)ego; (void)ctx; (void)identifier; } /** * Main function of the test, run from scheduler. * * @param cls NULL * @param cfg configuration we use (also to connect to identity service) * @param peer handle to access more of the peer (not used) */ static void run_get(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_TESTING_Peer *peer) { endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT, &endbadly, NULL); GNUNET_SCHEDULER_add_shutdown(&cleanup, NULL); h = GNUNET_IDENTITY_connect(cfg, &dummy_cb, NULL); CHECK(NULL != h); op = GNUNET_IDENTITY_get(h, "test-service", &get_cb, NULL); } /** * Continuation called from successful rename operation. * * @param cls NULL * @param emsg (should also be NULL) */ static void success_set_cont(void *cls, const char *emsg) { op = NULL; CHECK(NULL == emsg); end(); } /** * Called with events about egos. * * @param cls NULL * @param ego ego handle * @param ego_ctx context for application to store data for this ego * (during the lifetime of this process, initially NULL) * @param identifier identifier assigned by the user for this ego, * NULL if the user just deleted the ego and it * must thus no longer be used */ static void notification_cb(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *identifier) { if (NULL == ego) return; /* skip first call */ if (NULL == identifier) return; /* deletion / shutdown */ op = GNUNET_IDENTITY_set(h, "test-service", ego, &success_set_cont, NULL); } /** * Called with events about created ego. * * @param cls NULL * @param pk private key of the ego, or NULL on error * @param emsg error message */ static void create_cb(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk, const char *emsg) { CHECK(NULL == emsg); CHECK(NULL != pk); op = NULL; } /** * Main function of the test, run from scheduler. * * @param cls NULL * @param cfg configuration we use (also to connect to identity service) * @param peer handle to access more of the peer (not used) */ static void run_set(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_TESTING_Peer *peer) { endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT, &endbadly, NULL); GNUNET_SCHEDULER_add_shutdown(&cleanup, NULL); h = GNUNET_IDENTITY_connect(cfg, ¬ification_cb, NULL); CHECK(NULL != h); op = GNUNET_IDENTITY_create(h, "test-id", &create_cb, NULL); } int main(int argc, char *argv[]) { GNUNET_DISK_directory_remove("/tmp/gnunet/test-identity-service"); res = 1; if (0 != GNUNET_TESTING_service_run("test-identity-defaults", "identity", "test_identity.conf", &run_set, NULL)) return 1; if (0 != GNUNET_TESTING_service_run("test-identity-defaults", "identity", "test_identity.conf", &run_get, NULL)) return 1; GNUNET_DISK_directory_remove("/tmp/gnunet/test-identity-service"); return res; } /* end of test_identity_defaults.c */