From b3af783f4e0ec940f09c19d945374371ab86e2e3 Mon Sep 17 00:00:00 2001 From: jmjatlanta Date: Mon, 28 Aug 2017 13:04:27 -0500 Subject: [PATCH] Building tests for journaling and backup --- test/config.test1 | 76 +++++++++++++++++++++ test/config.test2 | 76 +++++++++++++++++++++ test/core/test_daemon.h | 5 -- test/journal/test_journal.h | 72 ++++++++++++++++++++ test/test_helper.c | 129 +++++++++++++++++++++++++++++------- test/test_helper.h | 22 ++++++ test/testit.c | 4 ++ 7 files changed, 356 insertions(+), 28 deletions(-) create mode 100644 test/config.test1 create mode 100644 test/config.test2 diff --git a/test/config.test1 b/test/config.test1 new file mode 100644 index 0000000..e51b19d --- /dev/null +++ b/test/config.test1 @@ -0,0 +1,76 @@ +{ + "Identity": { + "PeerID": "QmZVoAZGFfinB7MQQiDzB84kWaDPQ95GLuXdemJFM2r9b4", + "PrivKey": "CAASpgkwggSiAgEAAoIBAQCApYAN/RWPZqfuLp96dB7wyR11r58Yy2v7l0ebAW/Sq5zBtg6Jrvmg5Nwx9lLUWa75VmwC6B+70cbdE7g+668VknjkyDxODYimGMsMeAcr0IKRludPjSYThbP3UOmeQdu+5ifSBcJ9Atsr/b1kNSntEyixm33boUIv+m2VI5rU9I81bzbPsnBEx4I4BDduJB/tJ0SSCQs3SQJdFtj+XoypZeShtPW/L2p8K9q/GI6dLNxHIKqJwaED6gBhmlRHAA9hqV3RJZ1Hh9ztYa9IM1k13A7SjvedDIdqrAIlAAUW2uKO1HiAEyLCykPqZsm/y8f4tfsHjnSk3RpDhaNlRGX5AgMBAAECggEAKWcaQ2ZEXhaHzVwr71kX7B6N4KZY6b3uTtZtMTHRL1gT5zQUkbNCm8mMJHhGSBlk+tIZiQXz0Jq/Cb+i+H0ZqDOvvNHEtsocRHiOQMEQbcV5gCm04CFpM7dAKEReK5S+iD3CaxF3eoxExW+wWGPTznzwB9knNFw91Psf8XO4DPkBAZfe3prmiKBDg74Cy1hAzBHGp15/4oU9gyaZop0Oe1UA+NEeGCTZgDcIOLYbPjH6tRF0xw2Usuh2IiwkUqrdRWwO0ZlaBD9jSCxQ4evbgIAOtni0+qbbeIlXQGPn3XFSZjwsdS7b/CPe8Gbtoy+akuoHOV9Rje/0ZAJTN4KjQQKBgQDgH76D7yr57Tcga18EoWJcGJvvvt/m0NfjtSoz901uK60qf5MnNbUXYKF33j5XW9V9+WRde0IqxZkwDIAuk6Bx/oYqI/DgvQ/Me/8np4R7K6Tjb3PNtHCGNtuGU2qJthCcCZ629lej3y5bwLtwfhjUwHSRzwQXlnJnHa49KZ1AvQKBgQCS8XY9aA6cBaCk8WDoTxMVSrr5P0QMKWbgHqylsUvZsTCj07+Ob87gnZjyGgPfIn9pF9gMeuExyHj/+c1P54Z0dPBeL4KQx1UpvgyJTLuFe1csR2Q8qAp6GOiEojXJ0Tc4yUsVwSKmCCsW9f2EiXCP24TqwedllfKoazvbaJZD7QKBgCjugzvTNTUZ1qSMF3lgA/ev4uLBKGEeKR+EGaYN9000mtaVIAncLCuN0U9z/ky0D+SG5IaSGT54ggadcdePzJClHFmb4MUaokUFLE9Qr8hS6zVCSJL77kUExcjdeSqXXqcwtpTRnqXl/7BwHYto7B4G3AM5HJU2O8SLTiQLcpW9AoGASXYl4rUu+Jlnoo56ICnIJJDjwM/8OQhJwioTrhJhFUgcRQsLbS5AgtLHL+IJpXgdsnCVNkgIZVcQBwjft97LvVTpBm1CHRdKYD//DHUsGqN7BUv7tMdd1YS2WfiuY2MQ9HbN7uZLaC4VPLlmMOh1ObZJUQP3pzW7xq81kY9L8FECgYA92LvEamYLzbisdb6XvA6d5+jUXtt3v8/2e1tNKSUuvBCLxWy5IqObgHTCaCHJH8E/bAEmOVaxXdzpS484Q8Hbai+NBVjnPB/yINCN4WgScBRFr3691HeQ1ejeEKSzELg1QDau7jo7CSZFO1ZHCR01T7HZCrcuLaG7DxAx/Y+i8A==" + }, + "Datastore": { + "Type": "lmdb", + "Path": "/Users/JohnJones/.ipfs/datastore", + "StorageMax": "10GB", + "StorageGCWatermark": 90, + "GCPeriod": "1h", + "Params": null, + "NoSync": false, + "HashOnRead": false, + "BloomFilterSize": 0 + }, + "Addresses": { + "Swarm": [ + "/ip4/0.0.0.0/tcp/4001", + "/ip6/::/tcp/4001" + ], + "API": "(null)", + "Gateway": "(null)" + }, + "Mounts": { + "IPFS": "/ipfs", + "IPNS": "/ipns", + "FuseAllowOther": false + }, + "Discovery": { + "MDNS": { + "Enabled": true, + "Interval": 10 + } + }, + "Ipns": { + "RepublishedPeriod": "", + "RecordLifetime": "", + "ResolveCacheSize": 128 + }, + "Bootstrap": [ + ], + "Tour": { + "Last": "" + }, + "Gateway": { + "HTTPHeaders": { + "Access-Control-Allow-Origin": [ + "*" + ], + "Access-Control-Allow-Methods": [ + "GET" + ], + "Access-Control-Allow-Headers": [ + "X-Requested-With" + ] + }, + "RootRedirect": "" + "Writable": false + "PathPrefixes": [] + }, + "SupernodeRouting": { + "Servers": null + }, "API": { + "HTTPHeaders": null + }, + "Swarm": { + "AddrFilters": null + }, + "Replication": { + "AnnounceMinutes": "60", + "Nodes": [ + "/ip4/127.0.0.1/tcp/4002/ipfs/QmcDW1t4QQBGAs2HSig8xkUhPxFZzmewAeFdsmp6q6nyY5" + ] + } +} diff --git a/test/config.test2 b/test/config.test2 new file mode 100644 index 0000000..d1abdcf --- /dev/null +++ b/test/config.test2 @@ -0,0 +1,76 @@ +{ + "Identity": { + "PeerID": "QmcDW1t4QQBGAs2HSig8xkUhPxFZzmewAeFdsmp6q6nyY5", + "PrivKey": "CAASqQkwggSlAgEAAoIBAQDqghv+79zy4dcP+8GCSa9kfoD9zF1gpOO/gnfjLUd9BTzY1MXX7pzGsztRnLOFtuSAqZmg9iEgnrNbLpGqYdHxSRU7taHv2+aAjE4yU6epP9NWaS3kC06NRzpcH4M+sIXYheioEJrOb4OGnz5KZuAAmRu/0gg+HSHeZTVNz3cRgg1fvpeG68UGSjLhIXg4jYjCso0KOdTZDTKkVqFqDyKJOgDPEGF5sS024Z33Wpkn6+MTX0xIUfn4eKIJztmt7g7/2zi3OnsKmfj7lmh77R93F88hGN5i2g6/GYY6qfQ4HJ/RxEGzXtt+r+jNlV4zGFSAWfR7vBklkGnyL041ewRpAgMBAAECggEAQ/C8AakmfyuU7imHD6MfcGMCJgWOTBCZdwNqjmOw4XSiA0PpqbyUqTCGEAfxLt0k6G26d5q3UEcKOXGNfCpo85mz0B+4MdCowDdl9EiuO2elZ9SDGh14fY/URZpPoNrtfCSXmhFteD9wgJEkL9QMM8An/PPxtWUlSdRSlB92JJjWI5RiPx8u9jVNqsjp/t/Pe3oQ4HvuFXBmSjdRQh7uIvgKC28DMcuROZPRhCAcUcWSp8plYjXmEV1yxip+Bt/oFqS7+LivFc4GdoxdOHTqDE731EjQ3UqKas7CJCjpFE+dy7QnUQr2oN/teXVuNgSO82xZkkk514IrqymOB2mQHQKBgQD2O6ZYpygpcUJ2NeOuPbhHkGreRK3ms2H1n+AgSjHd9SGbaip133S8fMnlv2/4FPaav3/N1wNUR01Cgf6nENj8bUR8n4M0esr7GozN7ACKS1jnPU9vIWDSZMoiV1bhA8rsUSmG4NSS966mW9Gf4R8vGGMffKyFfWdGNBlurag+zwKBgQDzz2bJMDzfNQdA1zb7qs0UR+0ZiRCboHOEYz1UmRYs/409ILbbQ4fdC/JiWLZE4SdaMAVyKjwojbq4uaR7x8iZFYz6cehiC/wTMBOf6tZsaLcY7HmBgpqjCK6lyyYiHQ0/PCON1z3vHGNXz0GjR+sHqb5Fct5IE0TN3Ym+IkMXRwKBgQCpIOmuZQpyBMiI15UOvngQN8Mf7n6gQsBbbTgOFchQ06oEzRRjKFxPh0tKUob/GK8WNcj8Qt6Xie4oa4/Vgv33zLnI++usJVe8yEzEuIDafMyQ8IzaIUwW14H7upADOI6uaUUjztRUKmo8/D5tGb1IpPCY1RLPEgbYsrpxSjiRAwKBgQDpcSY7cIJ4PW/qd6ZfpZSi3JN6pbBPMnwowFSS0dlX0IBNjStIGgrWbX/xBnvOy75ALkaonyPmuH2WLbn+ArZhTS8lBTe52TvMq3W+4r3YIxNdO97DUGf7vm5qtG6YrzRl3ZE1WGgmsAm2o+13B39UYQSbvnZykHCKpJokgO24NQKBgQDbb3U0Xy5gceTR5XbYUkdkPj0kxEMtYzTXh30dztTld2dKDIbAtVe8t2zinNuLUCqpu5+lCCN3qiYCNWEB5NZp6jAra6wzz483clw30sMYdtwh1NnTqP+i6WbxXagSamwp2555Xc7n3BpnX68BpoTi2cmPjWHhBGFjoOTLxI4ZQQ==" + }, + "Datastore": { + "Type": "lmdb", + "Path": "/tmp/ipfstest1/datastore", + "StorageMax": "10GB", + "StorageGCWatermark": 90, + "GCPeriod": "1h", + "Params": null, + "NoSync": false, + "HashOnRead": false, + "BloomFilterSize": 0 + }, + "Addresses": { + "Swarm": [ + "/ip4/0.0.0.0/tcp/4002", + "/ip6/::/tcp/4002" + ], + "API": "(null)", + "Gateway": "(null)" + }, + "Mounts": { + "IPFS": "/ipfs", + "IPNS": "/ipns", + "FuseAllowOther": false + }, + "Discovery": { + "MDNS": { + "Enabled": true, + "Interval": 10 + } + }, + "Ipns": { + "RepublishedPeriod": "", + "RecordLifetime": "", + "ResolveCacheSize": 128 + }, + "Bootstrap": [ + ], + "Tour": { + "Last": "" + }, + "Gateway": { + "HTTPHeaders": { + "Access-Control-Allow-Origin": [ + "*" + ], + "Access-Control-Allow-Methods": [ + "GET" + ], + "Access-Control-Allow-Headers": [ + "X-Requested-With" + ] + }, + "RootRedirect": "" + "Writable": false + "PathPrefixes": [] + }, + "SupernodeRouting": { + "Servers": null + }, "API": { + "HTTPHeaders": null + }, + "Swarm": { + "AddrFilters": null + }, + "Replication": { + "AnnounceMinutes": "60", + "Nodes": [ + "/ip4/127.0.0.1/tcp/4001/ipfs/QmZVoAZGFfinB7MQQiDzB84kWaDPQ95GLuXdemJFM2r9b4" + ] + } +} \ No newline at end of file diff --git a/test/core/test_daemon.h b/test/core/test_daemon.h index aad7e3b..f825d25 100644 --- a/test/core/test_daemon.h +++ b/test/core/test_daemon.h @@ -6,11 +6,6 @@ #include "../test_helper.h" #include "libp2p/utils/logger.h" -void* test_daemon_start(void* arg) { - ipfs_daemon_start((char*)arg); - return NULL; -} - int test_daemon_startup_shutdown() { int retVal = 0; pthread_t daemon_thread; diff --git a/test/journal/test_journal.h b/test/journal/test_journal.h index 5818543..3883f0a 100644 --- a/test/journal/test_journal.h +++ b/test/journal/test_journal.h @@ -67,3 +67,75 @@ int test_journal_encode_decode() { //ipfs_journal_entry_free(result_entry); return retVal; } + +/*** + * Starts a server with a file in it with a specific set of files. + * It also has a specific address, with a config file of another + * known peer to replicate between + */ +int test_journal_server_1() { + int retVal = 0; + pthread_t daemon_thread; + int thread_started = 0; + char* ipfs_path = "/tmp/ipfs_1"; + char* config_file = "config.test1"; + struct FSRepo* fs_repo = NULL; + + libp2p_logger_add_class("test_journal"); + + if (!drop_build_open_repo(ipfs_path, &fs_repo, config_file)) { + ipfs_repo_fsrepo_free(fs_repo); + libp2p_logger_error("test_journal", "Unable to drop and build repository at %s\n", ipfs_path); + goto exit; + } + + libp2p_logger_debug("test_journal", "Changed the server id to %s.\n", fs_repo->config->identity->peer->id); + + ipfs_repo_fsrepo_free(fs_repo); + + pthread_create(&daemon_thread, NULL, test_daemon_start, (void*)ipfs_path); + thread_started = 1; + + retVal = 1; + exit: + ipfs_daemon_stop(); + if (thread_started) + pthread_join(daemon_thread, NULL); + return retVal; +} + +/*** + * Starts a server with a specific set of files. + * It also has a specific address, with a config file of another + * known peer to replicate between + */ +int test_journal_server_2() { + int retVal = 0; + pthread_t daemon_thread; + int thread_started = 0; + char* ipfs_path = "/tmp/ipfs_2"; + char* config_file = "config.test2"; + struct FSRepo* fs_repo = NULL; + + libp2p_logger_add_class("test_journal"); + + if (!drop_build_open_repo(ipfs_path, &fs_repo, config_file)) { + ipfs_repo_fsrepo_free(fs_repo); + libp2p_logger_error("test_journal", "Unable to drop and build repository at %s\n", ipfs_path); + goto exit; + } + + libp2p_logger_debug("test_journal", "Changed the server id to %s.\n", fs_repo->config->identity->peer->id); + + ipfs_repo_fsrepo_free(fs_repo); + + pthread_create(&daemon_thread, NULL, test_daemon_start, (void*)ipfs_path); + thread_started = 1; + + retVal = 1; + exit: + ipfs_daemon_stop(); + if (thread_started) + pthread_join(daemon_thread, NULL); + return retVal; +} diff --git a/test/test_helper.c b/test/test_helper.c index 203ac88..ab99848 100644 --- a/test/test_helper.c +++ b/test/test_helper.c @@ -1,11 +1,74 @@ #include #include #include +#include +#include +#include #include "ipfs/repo/init.h" #include "ipfs/repo/fsrepo/fs_repo.h" +#include "ipfs/core/daemon.h" #include "libp2p/os/utils.h" +int cp(const char *to, const char *from) +{ + int fd_to, fd_from; + char buf[4096]; + ssize_t nread; + int saved_errno; + + fd_from = open(from, O_RDONLY); + if (fd_from < 0) + return -1; + + fd_to = open(to, O_WRONLY | O_CREAT | O_EXCL, 0666); + if (fd_to < 0) + goto out_error; + + while (nread = read(fd_from, buf, sizeof buf), nread > 0) + { + char *out_ptr = buf; + ssize_t nwritten; + + do { + nwritten = write(fd_to, out_ptr, nread); + + if (nwritten >= 0) + { + nread -= nwritten; + out_ptr += nwritten; + } + else if (errno != EINTR) + { + goto out_error; + } + } while (nread > 0); + } + + if (nread == 0) + { + if (close(fd_to) < 0) + { + fd_to = -1; + goto out_error; + } + close(fd_from); + + /* Success! */ + return 0; + } + + out_error: + saved_errno = errno; + + close(fd_from); + if (fd_to >= 0) + close(fd_to); + + errno = saved_errno; + return -1; +} + /*** * Helper to create a test file in the OS */ @@ -104,26 +167,6 @@ int drop_repository(const char* path) { if (os_utils_file_exists(path)) { return remove_directory(path); - /* - // the config file - if (!os_utils_filepath_join(path, "config", currDirectory, 1024)) - return 0; - unlink(currDirectory); - - // the datastore directory - if (!os_utils_filepath_join(path, "datastore", currDirectory, 1024)) - return 0; - if (!remove_directory(currDirectory)) - return 0; - - // the blockstore directory - if (!os_utils_filepath_join(path, "blockstore", currDirectory, 1024)) - return 0; - if (!remove_directory(currDirectory)) - return 0; - - return remove_directory(path); - */ } return 1; @@ -149,12 +192,33 @@ int drop_and_build_repository(const char* path, int swarm_port, struct Libp2pVec return make_ipfs_repository(path, swarm_port, bootstrap_peers, peer_id); } - -int drop_build_and_open_repo(const char* path, struct FSRepo** fs_repo) { - +/*** + * Drop a repository and build a new one with the specified config file + * @param path where to create it + * @param fs_repo the results + * @param config_file_to_copy where to find the config file to copy + * @returns true(1) on success, otherwise false(0) + */ +int drop_build_open_repo(const char* path, struct FSRepo** fs_repo, const char* config_filename_to_copy) { if (!drop_and_build_repository(path, 4001, NULL, NULL)) return 0; + if (config_filename_to_copy != NULL) { + // attach config filename to path + char config[strlen(path) + 7]; + strcpy(config, path); + // erase slash if there is one + if (config[strlen(path)-1] == '/') + config[strlen(path)-1] = 0; + strcat(config, "/config"); + // delete the old + if (unlink(config) != 0) + return 0; + // copy pre-built config file into directory + if (cp(config, config_filename_to_copy) < 0) + return 0; + } + if (!ipfs_repo_fsrepo_new(path, NULL, fs_repo)) return 0; @@ -166,3 +230,22 @@ int drop_build_and_open_repo(const char* path, struct FSRepo** fs_repo) { return 1; } +/*** + * Drop a repository and build a new one + * @param path where to create it + * @param fs_repo the results + * @returns true(1) on success, otherwise false(0) + */ +int drop_build_and_open_repo(const char* path, struct FSRepo** fs_repo) { + return drop_build_open_repo(path, fs_repo, NULL); +} + +/*** + * Start a daemon (usefull in a separate thread) + * @param arg a char string of the repo path + * @returns NULL + */ +void* test_daemon_start(void* arg) { + ipfs_daemon_start((char*)arg); + return NULL; +} diff --git a/test/test_helper.h b/test/test_helper.h index 586e998..cf2557a 100644 --- a/test/test_helper.h +++ b/test/test_helper.h @@ -15,8 +15,23 @@ int drop_repository(const char* path); */ int drop_and_build_repository(const char* dir, int swarm_port, struct Libp2pVector* bootstrap_peers, char** peer_id); +/*** + * Drop a repository and build a new one + * @param path where to create it + * @param fs_repo the results + * @returns true(1) on success, otherwise false(0) + */ int drop_build_and_open_repo(const char* path, struct FSRepo** fs_repo); +/*** + * Drop a repository and build a new one with the specified config file + * @param path where to create it + * @param fs_repo the results + * @param config_file_to_copy where to find the config file to copy + * @returns true(1) on success, otherwise false(0) + */ +int drop_build_open_repo(const char* path, struct FSRepo** fs_repo, const char* config_file_to_copy); + /*** * Helper to create a test file in the OS * @pram fileName the resultant file name @@ -31,3 +46,10 @@ int create_file(const char* fileName, unsigned char* bytes, size_t num_bytes); * @param num_bytes how much to fill of the buffer */ int create_bytes(unsigned char* buffer, size_t num_bytes); + +/*** + * Start a daemon (usefull in a separate thread) + * @param arg a char string of the repo path + * @returns NULL + */ +void* test_daemon_start(void* arg); diff --git a/test/testit.c b/test/testit.c index c655413..38560ac 100644 --- a/test/testit.c +++ b/test/testit.c @@ -48,6 +48,8 @@ const char* names[] = { "test_daemon_startup_shutdown", "test_datastore_list_journal", "test_journal_encode_decode", + "test_journal_server_1", + "test_journal_server_2", "test_repo_config_new", "test_repo_config_init", "test_repo_config_write", @@ -106,6 +108,8 @@ int (*funcs[])(void) = { test_daemon_startup_shutdown, test_datastore_list_journal, test_journal_encode_decode, + test_journal_server_1, + test_journal_server_2, test_repo_config_new, test_repo_config_init, test_repo_config_write,