X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fdatastore%2Fperf_datastore_api.c;h=c51502cc65d9937cd579e03a10e6d56838471d87;hb=61c39c60565b386e0e12ea669556b030e8cd7180;hp=2344dafe89e23d28438c6aef3fd5f0e38ebfce66;hpb=5b29c6182ab28a0510e3a59fb2edba6eab9c914a;p=oweals%2Fgnunet.git diff --git a/src/datastore/perf_datastore_api.c b/src/datastore/perf_datastore_api.c index 2344dafe8..c51502cc6 100644 --- a/src/datastore/perf_datastore_api.c +++ b/src/datastore/perf_datastore_api.c @@ -1,10 +1,10 @@ /* This file is part of GNUnet. - (C) 2004, 2005, 2006, 2007, 2009 Christian Grothoff (and other contributing authors) + (C) 2004, 2005, 2006, 2007, 2009, 2011 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 2, or (at your + by the Free Software Foundation; either version 3, or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but @@ -36,17 +36,14 @@ #include "gnunet_util_lib.h" #include "gnunet_protocols.h" #include "gnunet_datastore_service.h" - -#define VERBOSE GNUNET_NO +#include "gnunet_testing_lib.h" +#include /** * How long until we give up on transmitting the message? */ #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15) - -static struct GNUNET_DATASTORE_Handle *datastore; - /** * Target datastore size (in bytes). */ @@ -79,71 +76,67 @@ static unsigned long long stored_ops; static struct GNUNET_TIME_Absolute start_time; +static const char *plugin_name; + +static struct GNUNET_DATASTORE_Handle *datastore; + static int ok; + enum RunPhase - { - RP_DONE = 0, - RP_PUT, - RP_CUT, - RP_REPORT - }; +{ + RP_DONE = 0, + RP_PUT, + RP_CUT, + RP_REPORT, + RP_ERROR +}; struct CpsRunContext { - struct GNUNET_SCHEDULER_Handle *sched; const struct GNUNET_CONFIGURATION_Handle *cfg; enum RunPhase phase; int j; unsigned long long size; int i; - - GNUNET_HashCode key; - uint32_t esize; - char data[65536]; }; - static void -run_continuation (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc); - - +run_continuation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); static void -check_success (void *cls, - int success, - const char *msg) +check_success (void *cls, int success, struct GNUNET_TIME_Absolute min_expiration, const char *msg) { struct CpsRunContext *crc = cls; + if (GNUNET_OK != success) - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%s\n", msg); - GNUNET_assert (GNUNET_OK == success); + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Check success failed: `%s'\n", msg); + crc->phase = RP_ERROR; + GNUNET_SCHEDULER_add_now (&run_continuation, crc); + return; + } #if REPORT_ID - fprintf (stderr, "I"); + FPRINTF (stderr, "%s", "I"); #endif stored_bytes += crc->size; stored_ops++; stored_entries++; crc->j++; - if (crc->j == PUT_10) - { - crc->j = 0; - crc->i++; - if (crc->i == ITERATIONS) - crc->phase = RP_DONE; - else - crc->phase = RP_CUT; - } - GNUNET_SCHEDULER_add_continuation (crc->sched, - GNUNET_NO, - &run_continuation, - crc, - GNUNET_SCHEDULER_REASON_PREREQ_DONE); + if (crc->j >= PUT_10) + { + crc->j = 0; + crc->i++; + if (crc->i == ITERATIONS) + crc->phase = RP_DONE; + else + crc->phase = RP_CUT; + } + GNUNET_SCHEDULER_add_continuation (&run_continuation, crc, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); } @@ -153,251 +146,196 @@ check_success (void *cls, * * @param cls closure * @param success GNUNET_SYSERR on failure + * @param min_expiration minimum expiration time required for content to be stored + * by the datacache at this time, zero for unknown * @param msg NULL on success, otherwise an error message */ -static void -remove_next(void *cls, - int success, - const char *msg) +static void +remove_next (void *cls, int success, struct GNUNET_TIME_Absolute min_expiration, const char *msg) { struct CpsRunContext *crc = cls; + if (GNUNET_OK != success) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "remove_next failed: `%s'\n", msg); + crc->phase = RP_ERROR; + GNUNET_SCHEDULER_add_now (&run_continuation, crc); + return; + } #if REPORT_ID - fprintf (stderr, "D"); + FPRINTF (stderr, "%s", "D"); #endif GNUNET_assert (GNUNET_OK == success); - GNUNET_SCHEDULER_add_continuation (crc->sched, - GNUNET_NO, - &run_continuation, - crc, - GNUNET_SCHEDULER_REASON_PREREQ_DONE); + GNUNET_SCHEDULER_add_now (&run_continuation, crc); } - static void -do_delete (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +delete_value (void *cls, const struct GNUNET_HashCode * key, size_t size, + const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, + uint32_t anonymity, struct GNUNET_TIME_Absolute expiration, + uint64_t uid) { struct CpsRunContext *crc = cls; - stored_bytes -= crc->esize; - stored_entries--; + GNUNET_assert (NULL != key); stored_ops++; - GNUNET_DATASTORE_remove (datastore, - &crc->key, - crc->esize, - crc->data, - &remove_next, - crc, - TIMEOUT); -} - - - -static void -delete_value (void *cls, - const GNUNET_HashCode * key, - uint32_t size, - const void *data, - uint32_t type, - uint32_t priority, - uint32_t anonymity, - struct GNUNET_TIME_Absolute - expiration, uint64_t uid) -{ - struct CpsRunContext *crc = cls; - - if (key == NULL) - { - if (stored_bytes < MAX_SIZE) - { - crc->phase = RP_REPORT; - GNUNET_SCHEDULER_add_continuation (crc->sched, - GNUNET_NO, - &run_continuation, - crc, - GNUNET_SCHEDULER_REASON_PREREQ_DONE); - return; - } - GNUNET_SCHEDULER_add_after (crc->sched, - GNUNET_NO, - GNUNET_SCHEDULER_PRIORITY_HIGH, - GNUNET_SCHEDULER_NO_TASK, - &do_delete, - crc); - return; - } + stored_bytes -= size; + stored_entries--; stored_ops++; if (stored_bytes < MAX_SIZE) - { - GNUNET_DATASTORE_get_next (datastore, GNUNET_YES); - return; - } - crc->key = *key; - crc->esize = size; - memcpy (crc->data, data, size); - GNUNET_DATASTORE_get_next (datastore, GNUNET_YES); + crc->phase = RP_PUT; + GNUNET_assert (NULL != + GNUNET_DATASTORE_remove (datastore, key, size, data, 1, 1, + TIMEOUT, &remove_next, crc)); } static void -run_continuation (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +run_continuation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct CpsRunContext *crc = cls; size_t size; - static GNUNET_HashCode key; + static struct GNUNET_HashCode key; static char data[65536]; int i; int k; + char gstr[128]; ok = (int) crc->phase; switch (crc->phase) - { - case RP_PUT: - memset (&key, 256 - crc->i, sizeof (GNUNET_HashCode)); - i = crc->j; - k = crc->i; - /* most content is 32k */ - size = 32 * 1024; - if (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 16) == 0) /* but some of it is less! */ - size = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 32 * 1024); - crc->size = size = size - (size & 7); /* always multiple of 8 */ - GNUNET_CRYPTO_hash (&key, sizeof (GNUNET_HashCode), &key); - memset (data, i, size); - if (i > 255) - memset (data, i - 255, size / 2); - data[0] = k; - GNUNET_DATASTORE_put (datastore, - 0, - &key, - size, - data, - i+1, - GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 100), - i, - GNUNET_TIME_relative_to_absolute - (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, - GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1000))), - TIMEOUT, - &check_success, - crc); - break; - case RP_CUT: - /* trim down below MAX_SIZE again */ - GNUNET_DATASTORE_get_random (datastore, - &delete_value, - crc, - TIMEOUT); - break; - case RP_REPORT: - printf ( + { + case RP_PUT: + memset (&key, 256 - crc->i, sizeof (struct GNUNET_HashCode)); + i = crc->j; + k = crc->i; + /* most content is 32k */ + size = 32 * 1024; + if (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 16) == 0) /* but some of it is less! */ + size = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 32 * 1024); + crc->size = size = size - (size & 7); /* always multiple of 8 */ + GNUNET_CRYPTO_hash (&key, sizeof (struct GNUNET_HashCode), &key); + memset (data, i, size); + if (i > 255) + memset (data, i - 255, size / 2); + data[0] = k; + GNUNET_assert (NULL != + GNUNET_DATASTORE_put (datastore, 0, &key, size, data, i + 1, + GNUNET_CRYPTO_random_u32 + (GNUNET_CRYPTO_QUALITY_WEAK, 100), i, + 0, + GNUNET_TIME_relative_to_absolute + (GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, + GNUNET_CRYPTO_random_u32 + (GNUNET_CRYPTO_QUALITY_WEAK, 1000))), + 1, 1, TIMEOUT, &check_success, crc)); + break; + case RP_CUT: + /* trim down below MAX_SIZE again */ + GNUNET_assert (NULL != + GNUNET_DATASTORE_get_for_replication (datastore, 1, 1, + TIMEOUT, &delete_value, + crc)); + break; + case RP_REPORT: + printf ( #if REPORT_ID - "\n" + "\n" #endif - "Stored %llu kB / %lluk ops / %llu ops/s\n", - stored_bytes / 1024, /* used size in k */ - stored_ops / 1024, /* total operations (in k) */ - 1000 * stored_ops / (1 + GNUNET_TIME_absolute_get_duration(start_time).value)); - crc->phase = RP_PUT; - crc->j = 0; - GNUNET_SCHEDULER_add_continuation (crc->sched, - GNUNET_NO, - &run_continuation, - crc, - GNUNET_SCHEDULER_REASON_PREREQ_DONE); - break; - case RP_DONE: - GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES); - GNUNET_free (crc); - ok = 0; - break; - default: - GNUNET_assert (0); - } + "Stored %llu kB / %lluk ops / %llu ops/s\n", stored_bytes / 1024, /* used size in k */ + stored_ops / 1024, /* total operations (in k) */ + 1000LL * 1000LL * stored_ops / (1 + + GNUNET_TIME_absolute_get_duration + (start_time).rel_value_us)); + crc->phase = RP_PUT; + crc->j = 0; + GNUNET_SCHEDULER_add_continuation (&run_continuation, crc, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); + break; + case RP_DONE: + GNUNET_snprintf (gstr, sizeof (gstr), "DATASTORE-%s", plugin_name); + if ((crc->i == ITERATIONS) && (stored_ops > 0)) + GAUGER (gstr, "PUT operation duration", + GNUNET_TIME_absolute_get_duration (start_time).rel_value_us / 1000LL / + stored_ops, "ms/operation"); + GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES); + GNUNET_free (crc); + ok = 0; + break; + case RP_ERROR: + GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES); + GNUNET_free (crc); + ok = 1; + break; + default: + GNUNET_assert (0); + } +} + + +static void +run_tests (void *cls, int success, struct GNUNET_TIME_Absolute min_expiration, const char *msg) +{ + struct CpsRunContext *crc = cls; + + if (success != GNUNET_YES) + { + FPRINTF (stderr, + "Test 'put' operation failed with error `%s' database likely not setup, skipping test.\n", + msg); + GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES); + GNUNET_free (crc); + return; + } + GNUNET_SCHEDULER_add_continuation (&run_continuation, crc, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); } static void run (void *cls, - struct GNUNET_SCHEDULER_Handle *sched, - char *const *args, - const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Peer *peer) { struct CpsRunContext *crc; + static struct GNUNET_HashCode zkey; - datastore = GNUNET_DATASTORE_connect (cfg, sched); + datastore = GNUNET_DATASTORE_connect (cfg); start_time = GNUNET_TIME_absolute_get (); - crc = GNUNET_malloc(sizeof(struct CpsRunContext)); - crc->sched = sched; + crc = GNUNET_malloc (sizeof (struct CpsRunContext)); crc->cfg = cfg; crc->phase = RP_PUT; - GNUNET_SCHEDULER_add_continuation (crc->sched, - GNUNET_NO, - &run_continuation, - crc, - GNUNET_SCHEDULER_REASON_PREREQ_DONE); -} - - -static int -check () -{ - pid_t pid; - char *const argv[] = { - "perf-datastore-api", - "-c", - "test_datastore_api_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - pid = GNUNET_OS_start_process ("gnunet-service-arm", - "gnunet-service-arm", -#if VERBOSE - "-L", "DEBUG", -#endif - "-c", "test_datastore_api_data.conf", NULL); - sleep (1); - GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, - argv, "perf-datastore-api", "nohelp", - options, &run, NULL); - if (0 != PLIBC_KILL (pid, SIGTERM)) - { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); - ok = 1; - } - GNUNET_OS_process_wait(pid); - return ok; + if (NULL == + GNUNET_DATASTORE_put (datastore, 0, &zkey, 4, "TEST", + GNUNET_BLOCK_TYPE_TEST, 0, 0, 0, + GNUNET_TIME_relative_to_absolute + (GNUNET_TIME_UNIT_SECONDS), 0, 1, + GNUNET_TIME_UNIT_MINUTES, &run_tests, crc)) + { + FPRINTF (stderr, "%s", "Test 'put' operation failed.\n"); + ok = 1; + GNUNET_free (crc); + } } int main (int argc, char *argv[]) { - int ret; - - GNUNET_DISK_directory_remove ("/tmp/test-gnunet-datastore"); - GNUNET_log_setup ("perf-datastore-api", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - ret = check (); -#if REPORT_ID - fprintf (stderr, "\n"); -#endif - GNUNET_DISK_directory_remove ("/tmp/test-gnunet-datastore"); - return ret; + char cfg_name[128]; + + plugin_name = GNUNET_TESTING_get_testname_from_underscore (argv[0]); + GNUNET_snprintf (cfg_name, sizeof (cfg_name), + "test_datastore_api_data_%s.conf", plugin_name); + if (0 != + GNUNET_TESTING_peer_run ("perf-gnunet-datastore", + cfg_name, + &run, + NULL)) + return 1; + FPRINTF (stderr, "%s", "\n"); + return ok; } - /* end of perf_datastore_api.c */