diff options
author | Bertrand Marc <beberking@gmail.com> | 2012-06-06 20:47:48 +0200 |
---|---|---|
committer | Bertrand Marc <beberking@gmail.com> | 2012-06-06 20:47:48 +0200 |
commit | 740b30688bd745a527f96f9116c19acb3480971a (patch) | |
tree | 2709a3f4dba11c174aa9e1ba3612e30c578e76a9 /src/gns/test_gns_max_queries.c | |
parent | 2b81464a43485fcc8ce079fafdee7b7a171835f4 (diff) |
Imported Upstream version 0.9.3upstream/0.9.3
Diffstat (limited to 'src/gns/test_gns_max_queries.c')
-rw-r--r-- | src/gns/test_gns_max_queries.c | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/src/gns/test_gns_max_queries.c b/src/gns/test_gns_max_queries.c new file mode 100644 index 0000000..ad1743c --- /dev/null +++ b/src/gns/test_gns_max_queries.c @@ -0,0 +1,381 @@ +/* + This file is part of GNUnet. + (C) 2009 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 3, 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file gns/test_gns_max_queries.c + * @brief base testcase for testing GNS background queries + * in particular query replacement and clean shutdown + */ +#include "platform.h" +#include "gnunet_testing_lib.h" +#include "gnunet_core_service.h" +#include "block_dns.h" +#include "gns.h" +#include "gnunet_signatures.h" +#include "gnunet_namestore_service.h" +#include "gnunet_dnsparser_lib.h" +#include "gnunet_gns_service.h" + +/* DEFINES */ +#define VERBOSE GNUNET_YES + +/* Timeout for entire testcase */ +#define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 20) + +/* If number of peers not in config file, use this number */ +#define DEFAULT_NUM_PEERS 2 + +/* test records to resolve */ +#define TEST_DOMAIN "www.gnunet" +#define TEST_DOMAIN_NACK "doesnotexist.bob.gnunet" +#define TEST_IP "127.0.0.1" +#define TEST_RECORD_NAME "www" +#define TEST_ADDITIONAL_LOOKUPS 5 +#define TEST_AUTHORITY_NAME "bob" + +#define KEYFILE_BOB "../namestore/zonefiles/HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey" + +/* Globals */ + +/** + * Directory to store temp data in, defined in config file + */ +static char *test_directory; + +static struct GNUNET_TESTING_PeerGroup *pg; + +/* Task handle to use to schedule test failure */ +GNUNET_SCHEDULER_TaskIdentifier die_task; + +/* Global return value (0 for success, anything else for failure) */ +static int ok; + +static struct GNUNET_NAMESTORE_Handle *namestore_handle; + +static struct GNUNET_GNS_Handle *gns_handle; + +const struct GNUNET_CONFIGURATION_Handle *cfg; + +static unsigned long long max_parallel_lookups; + +/** + * Check whether peers successfully shut down. + */ +void +shutdown_callback (void *cls, const char *emsg) +{ + if (emsg != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error on shutdown! ret=%d\n", ok); + if (ok == 0) + ok = 2; + } + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "done(ret=%d)!\n", ok); +} + +static void +on_lookup_result_dummy(void *cls, uint32_t rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + if (rd_count != 0) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + "Got %d results from dummy lookup! Wanted: 0\n", + rd_count); + ok = -1; + } +} + +static void +on_lookup_result(void *cls, uint32_t rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + struct in_addr a; + int i; + char* addr; + + if (rd_count == 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lookup failed, rp_filtering?\n"); + ok = 2; + } + else + { + ok = 1; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "name: %s\n", (char*)cls); + for (i=0; i<rd_count; i++) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "type: %d\n", rd[i].record_type); + if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_A) + { + memcpy(&a, rd[i].data, sizeof(a)); + addr = inet_ntoa(a); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "address: %s\n", addr); + if (0 == strcmp(addr, TEST_IP)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "%s correctly resolved to %s!\n", TEST_DOMAIN, addr); + ok = 0; + } + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No resolution!\n"); + } + } + } + GNUNET_GNS_disconnect(gns_handle); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down peer1!\n"); + //GNUNET_TESTING_daemon_stop (d1, TIMEOUT, &shutdown_callback, NULL, + // GNUNET_YES, GNUNET_NO); + GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); +} + + +/** + * Function scheduled to be run on the successful start of services + * tries to look up the dns record for TEST_DOMAIN + */ +static void +commence_testing (void *cls, int32_t success, const char *emsg) +{ + int i; + char lookup_name[MAX_DNS_NAME_LENGTH]; + + GNUNET_NAMESTORE_disconnect(namestore_handle, GNUNET_YES); + + gns_handle = GNUNET_GNS_connect(cfg); + + if (NULL == gns_handle) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to connect to GNS!\n"); + ok = 2; + } + + + /* Now lookup some non existing records */ + for (i=0; i<max_parallel_lookups+TEST_ADDITIONAL_LOOKUPS; i++) + { + GNUNET_snprintf(lookup_name, + MAX_DNS_NAME_LENGTH, + "www.doesnotexist-%d.bob.gnunet", i); + GNUNET_GNS_lookup(gns_handle, lookup_name, GNUNET_GNS_RECORD_TYPE_A, + &on_lookup_result_dummy, NULL); + } + + GNUNET_GNS_lookup(gns_handle, TEST_DOMAIN, GNUNET_GNS_RECORD_TYPE_A, + &on_lookup_result, TEST_DOMAIN); +} + + +/** + * Continuation for the GNUNET_DHT_get_stop call, so that we don't shut + * down the peers without freeing memory associated with GET request. + */ +static void +end_badly_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + + if (pg != NULL) + GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); + GNUNET_SCHEDULER_cancel (die_task); +} + +/** + * Check if the get_handle is being used, if so stop the request. Either + * way, schedule the end_badly_cont function which actually shuts down the + * test. + */ +static void +end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failing test with error: `%s'!\n", + (char *) cls); + GNUNET_SCHEDULER_add_now (&end_badly_cont, NULL); + ok = 1; +} + +static void +do_lookup(void *cls, const struct GNUNET_PeerIdentity *id, + const struct GNUNET_CONFIGURATION_Handle *_cfg, + struct GNUNET_TESTING_Daemon *d, const char *emsg) +{ + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded alice_pkey; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded bob_pkey; + struct GNUNET_CRYPTO_RsaPrivateKey *alice_key; + struct GNUNET_CRYPTO_RsaPrivateKey *bob_key; + char* alice_keyfile; + struct GNUNET_CRYPTO_ShortHashCode bob_hash; + + cfg = _cfg; + + GNUNET_SCHEDULER_cancel (die_task); + + /* put records into namestore */ + namestore_handle = GNUNET_NAMESTORE_connect(cfg); + if (NULL == namestore_handle) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to namestore\n"); + ok = -1; + return; + } + + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns", + "ZONEKEY", + &alice_keyfile)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n"); + ok = -1; + return; + } + + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, "gns", + "MAX_PARALLEL_BACKGROUND_QUERIES", + &max_parallel_lookups)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get max queries from cfg\n"); + ok = -1; + GNUNET_free (alice_keyfile); + return; + } + + alice_key = GNUNET_CRYPTO_rsa_key_create_from_file (alice_keyfile); + bob_key = GNUNET_CRYPTO_rsa_key_create_from_file (KEYFILE_BOB); + + GNUNET_CRYPTO_rsa_key_get_public (alice_key, &alice_pkey); + GNUNET_CRYPTO_rsa_key_get_public (bob_key, &bob_pkey); + + GNUNET_free(alice_keyfile); + + struct GNUNET_NAMESTORE_RecordData rd; + char* ip = TEST_IP; + struct in_addr *web = GNUNET_malloc(sizeof(struct in_addr)); + rd.expiration = GNUNET_TIME_UNIT_FOREVER_ABS; + GNUNET_assert(1 == inet_pton (AF_INET, ip, web)); + rd.data_size = sizeof(struct in_addr); + rd.data = web; + rd.record_type = GNUNET_DNSPARSER_TYPE_A; + + GNUNET_NAMESTORE_record_create (namestore_handle, + alice_key, + TEST_RECORD_NAME, + &rd, + NULL, + NULL); + + GNUNET_CRYPTO_short_hash(&bob_pkey, sizeof(bob_pkey), &bob_hash); + rd.data_size = sizeof(struct GNUNET_CRYPTO_ShortHashCode); + rd.data = &bob_hash; + rd.record_type = GNUNET_GNS_RECORD_PKEY; + + GNUNET_NAMESTORE_record_create (namestore_handle, + alice_key, + TEST_AUTHORITY_NAME, + &rd, + &commence_testing, + NULL); + + GNUNET_CRYPTO_rsa_key_free(alice_key); + GNUNET_CRYPTO_rsa_key_free(bob_key); + GNUNET_free(web); + +} + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *c) +{ + cfg = c; + /* Get path from configuration file */ + if (GNUNET_YES != + GNUNET_CONFIGURATION_get_value_string (cfg, "paths", "servicehome", + &test_directory)) + { + ok = 404; + return; + } + + + /* Set up a task to end testing if peer start fails */ + die_task = + GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, + "didn't start all daemons in reasonable amount of time!!!"); + + /* Start alice */ + //d1 = GNUNET_TESTING_daemon_start(cfg, TIMEOUT, GNUNET_NO, NULL, NULL, 0, + // NULL, NULL, NULL, &do_lookup, NULL); + pg = GNUNET_TESTING_daemons_start(cfg, 1, 1, 1, TIMEOUT, + NULL, NULL, &do_lookup, NULL, + NULL, NULL, NULL); +} + +static int +check () +{ + int ret; + + /* Arguments for GNUNET_PROGRAM_run */ + char *const argv[] = { "test-gns-max-queries", /* Name to give running binary */ + "-c", + "test_gns_simple_lookup.conf", /* Config file to use */ +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + /* Run the run function as a new program */ + ret = + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, + "test-gns-max-queries", "nohelp", options, &run, + &ok); + if (ret != GNUNET_OK) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "`test-gns-simple-lookup': Failed with error code %d\n", ret); + } + return ok; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + GNUNET_log_setup ("test-gns-simple-lookup", +#if VERBOSE + "DEBUG", +#else + "WARNING", +#endif + NULL); + ret = check (); + /** + * Need to remove base directory, subdirectories taken care + * of by the testing framework. + */ + return ret; +} + +/* end of test_gns_twopeer.c */ |