From f9d927f3758ce28290f837852f3276957e6b7941 Mon Sep 17 00:00:00 2001 From: jmjatlanta Date: Mon, 5 Dec 2016 13:11:22 -0500 Subject: [PATCH] Beginnings of testing for MerkleDag --- include/ipfs/node/node.h | 3 +- node/node.c | 6 +- test/Makefile | 2 +- test/merkledag/test_merkledag.h | 66 +++++++++++++++-- test/storage/test_datastore.h | 102 ++------------------------- test/test_helper.c | 121 ++++++++++++++++++++++++++++++++ test/test_helper.h | 5 ++ test/testit.c | 35 ++++++--- 8 files changed, 223 insertions(+), 117 deletions(-) create mode 100644 test/test_helper.c create mode 100644 test/test_helper.h diff --git a/include/ipfs/node/node.h b/include/ipfs/node/node.h index 5690252..5bd4578 100644 --- a/include/ipfs/node/node.h +++ b/include/ipfs/node/node.h @@ -130,9 +130,10 @@ struct Node * N_Create_From_Link(struct Link * mylink); /*N_Create_From_Data * @param data: bytes buffer you want to create the node from + * @param data_size length of buffer * returns a node with the data you inputted. */ -struct Node * N_Create_From_Data(unsigned char * data); +struct Node * N_Create_From_Data(unsigned char * data, size_t data_size); /*Node_Resolve_Max_Size * !!!This shouldn't concern you! diff --git a/node/node.c b/node/node.c index 6fa180e..7b48359 100644 --- a/node/node.c +++ b/node/node.c @@ -223,14 +223,16 @@ struct Node * N_Create_From_Link(struct Link * mylink) } /*N_Create_From_Data - * @param data: bytes buffer you want to create the node from + * @param data bytes buffer you want to create the node from + * @param data_size the length of the buffer * returns a node with the data you inputted. */ -struct Node * N_Create_From_Data(unsigned char * data) +struct Node * N_Create_From_Data(unsigned char * data, size_t data_size) { struct Node * mynode; mynode = (struct Node *) malloc(sizeof(struct Node)); mynode->data = data; + mynode->data_size = data_size; mynode->cached = NULL; return mynode; } diff --git a/test/Makefile b/test/Makefile index 48697e5..9a247e6 100644 --- a/test/Makefile +++ b/test/Makefile @@ -2,7 +2,7 @@ CC = gcc CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-multihash/include -I../../c-multiaddr/ -g3 -Wall LFLAGS = -L../../c-libp2p -L../../c-multihash -L../../c-multiaddr -lp2p -lm -lmultihash -lmultiaddr -lpthread DEPS = cmd/ipfs/test_init.h repo/test_repo_bootstrap_peers.h repo/test_repo_config.h repo/test_repo_identity.h cid/test_cid.h -OBJS = testit.o \ +OBJS = testit.o test_helper.o \ ../blocks/block.o ../blocks/blockstore.o \ ../cid/cid.o \ ../cmd/ipfs/init.o \ diff --git a/test/merkledag/test_merkledag.h b/test/merkledag/test_merkledag.h index 0bba851..ce33b02 100644 --- a/test/merkledag/test_merkledag.h +++ b/test/merkledag/test_merkledag.h @@ -1,11 +1,17 @@ #include "ipfs/merkledag/merkledag.h" #include "ipfs/node/node.h" +#include "../test_helper.h" int test_merkledag_add_data() { int retVal = 0; + // create a fresh repo + retVal = drop_and_build_repository("/tmp/.ipfs"); + if (retVal == 0) + return 0; + // open the fs repo - struct RepoConfig* repo_config; + struct RepoConfig* repo_config = NULL; struct FSRepo* fs_repo; const char* path = "/tmp/.ipfs"; @@ -21,6 +27,9 @@ int test_merkledag_add_data() { return 0; } + // get the size of the database + int start_file_size = os_utils_file_size("/tmp/.ipfs/datastore/data.mdb"); + // create data for node size_t binary_data_size = 255; unsigned char binary_data[binary_data_size]; @@ -29,17 +38,64 @@ int test_merkledag_add_data() { } // create a node - struct Node* node = N_Create_From_Data(binary_data); + struct Node* node1 = N_Create_From_Data(binary_data, 255); - retVal = ipfs_merkledag_add(node, fs_repo); + retVal = ipfs_merkledag_add(node1, fs_repo); if (retVal == 0) return 0; // make sure everything is correct - if (node->cached == NULL) + if (node1->cached == NULL) return 0; - Node_Delete(node); + int first_add_size = os_utils_file_size("/tmp/.ipfs/datastore/data.mdb"); + if (first_add_size == start_file_size) { // uh oh, database should have increased in size + return 0; + } + + // adding the same binary again should do nothing (the hash should be the same) + struct Node* node2 = N_Create_From_Data(binary_data, 255); + retVal = ipfs_merkledag_add(node2, fs_repo); + if (retVal == 0) + return 0; + + // make sure everything is correct + if (node2->cached == NULL) + return 0; + for(int i = 0; i < node1->cached->hash_length; i++) { + if (node1->cached->hash[i] != node2->cached->hash[i]) { + printf("hash of node1 does not match node2 at position %d\n", i); + return 0; + } + } + + int second_add_size = os_utils_file_size("/tmp/.ipfs/datastore/data.mdb"); + if (first_add_size != second_add_size) { // uh oh, the database shouldn't have changed size + fprintf("looks as if a new record was added when it shouldn't have. Old file size: %d, new file size: %d\n", first_add_size, second_add_size); + return 0; + } + + // now change 1 byte, which should change the hash + binary_data[10] = 0; + // create a node + struct Node* node3 = N_Create_From_Data(binary_data, 255); + + retVal = ipfs_merkledag_add(node3, fs_repo); + if (retVal == 0) + return 0; + + // make sure everything is correct + if (node3->cached == NULL) + return 0; + + Node_Delete(node1); + Node_Delete(node2); + Node_Delete(node3); + int third_add_size = os_utils_file_size("/tmp/.ipfs/datastore/data.mdb"); + if (third_add_size == second_add_size || third_add_size < second_add_size) {// uh oh, it didn't add it + printf("Node 3 should have been added, but the file size did not change from %d.\n", third_add_size); + return 0; + } return 1; } diff --git a/test/storage/test_datastore.h b/test/storage/test_datastore.h index a04b692..e6c49d9 100644 --- a/test/storage/test_datastore.h +++ b/test/storage/test_datastore.h @@ -4,105 +4,11 @@ #include "ipfs/repo/config/config.h" #include "ipfs/repo/fsrepo/fs_repo.h" +#include "../test_helper.h" + #include #include -int remove_directory(const char *path) -{ - DIR *d = opendir(path); - size_t path_len = strlen(path); - int r = -1; - - if (d) - { - struct dirent *p; - - r = 0; - - while (!r && (p=readdir(d))) - { - int r2 = -1; - char *buf; - size_t len; - - /* Skip the names "." and ".." as we don't want to recurse on them. */ - if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) - { - continue; - } - - len = path_len + strlen(p->d_name) + 2; - buf = malloc(len); - - if (buf) - { - struct stat statbuf; - - snprintf(buf, len, "%s/%s", path, p->d_name); - - if (!stat(buf, &statbuf)) - { - if (S_ISDIR(statbuf.st_mode)) - { - r2 = remove_directory(buf); - } - else - { - r2 = unlink(buf); - } - } - - free(buf); - } - - r = r2; - } - - closedir(d); - } - - if (!r) - { - r = rmdir(path); - } - - return r; -} - -int make_ipfs_repository(struct FSRepo* fs_repo) { - int retVal; - struct RepoConfig* repo_config; - - unlink("/tmp/.ipfs/config"); - remove_directory("/tmp/.ipfs/datastore"); - remove_directory("/tmp/.ipfs/blockstore"); - - // build a default repo config - retVal = ipfs_repo_config_new(&repo_config); - if (retVal == 0) - return 0; - retVal = ipfs_repo_config_init(repo_config, 2048, "/tmp/.ipfs"); - if (retVal == 0) - return 0; - // now the fs_repo - retVal = ipfs_repo_fsrepo_new("/tmp/.ipfs", repo_config, &fs_repo); - if (retVal == 0) - return 0; - // this builds a new repo - retVal = ipfs_repo_fsrepo_init(fs_repo); - if (retVal == 0) - return 0; - - // clean up - ipfs_repo_fsrepo_free(fs_repo); - // this is cleaned up by fsrepo_free - //ipfs_repo_config_free(repo_config); - - // make sure the repository exists - retVal = os_utils_file_exists("/tmp/.ipfs/config"); - return retVal; -} - /** * create a repository and put a record in the datastore and a block in the blockstore */ @@ -112,8 +18,7 @@ int test_ipfs_datastore_put() { const unsigned char* input = "Hello, world!"; // build the ipfs repository, then shut it down, so we can start fresh - struct FSRepo* fs_repo; - retVal = make_ipfs_repository(fs_repo); + drop_and_build_repository("/tmp/.ipfs"); if (retVal == 0) return 0; @@ -130,6 +35,7 @@ int test_ipfs_datastore_put() { return 0; // open the repository + struct FSRepo* fs_repo; retVal = ipfs_repo_fsrepo_new("/tmp/.ipfs", NULL, &fs_repo); if (retVal == 0) return 0; diff --git a/test/test_helper.c b/test/test_helper.c new file mode 100644 index 0000000..09a178b --- /dev/null +++ b/test/test_helper.c @@ -0,0 +1,121 @@ +#include +#include + +#include "ipfs/repo/fsrepo/fs_repo.h" + +int remove_directory(const char *path) +{ + DIR *d = opendir(path); + size_t path_len = strlen(path); + int r = -1; + + if (d) + { + struct dirent *p; + + r = 0; + + while (!r && (p=readdir(d))) + { + int r2 = -1; + char *buf; + size_t len; + + /* Skip the names "." and ".." as we don't want to recurse on them. */ + if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) + { + continue; + } + + len = path_len + strlen(p->d_name) + 2; + buf = malloc(len); + + if (buf) + { + struct stat statbuf; + + snprintf(buf, len, "%s/%s", path, p->d_name); + + if (!stat(buf, &statbuf)) + { + if (S_ISDIR(statbuf.st_mode)) + { + r2 = remove_directory(buf); + } + else + { + r2 = unlink(buf); + } + } + + free(buf); + } + + r = r2; + } + + closedir(d); + } + + if (!r) + { + r = rmdir(path); + } + + return r; +} + +int make_ipfs_repository(struct FSRepo* fs_repo) { + int retVal; + struct RepoConfig* repo_config; + + char currDirectory[1024]; + retVal = os_utils_filepath_join(fs_repo->path, "config", currDirectory, 1024); + if (retVal == 0) + return 0; + unlink(currDirectory); + retVal = os_utils_filepath_join(fs_repo->path, "datastore", currDirectory, 1024); + if (retVal == 0) + return 0; + remove_directory(currDirectory); + retVal = os_utils_filepath_join(fs_repo->path, "blockstore", currDirectory, 1024); + if (retVal == 0) + return 0; + remove_directory(currDirectory); + + // build a default repo config + retVal = ipfs_repo_config_new(&repo_config); + if (retVal == 0) + return 0; + retVal = ipfs_repo_config_init(repo_config, 2048, fs_repo->path); + if (retVal == 0) + return 0; + // now the fs_repo + retVal = ipfs_repo_fsrepo_new(fs_repo->path, repo_config, &fs_repo); + if (retVal == 0) + return 0; + // this builds a new repo + retVal = ipfs_repo_fsrepo_init(fs_repo); + if (retVal == 0) + return 0; + + // clean up + char* path[strlen(fs_repo->path) + 1]; + strcpy(path, fs_repo->path); + ipfs_repo_fsrepo_free(fs_repo); + // this is cleaned up by fsrepo_free + //ipfs_repo_config_free(repo_config); + + // make sure the repository exists + retVal = os_utils_filepath_join(path, "config", currDirectory, 1024); + if (retVal == 0) + return 0; + retVal = os_utils_file_exists(currDirectory); + return retVal; +} + +int drop_and_build_repository(const char* path) { + struct FSRepo fs_repo; + fs_repo.path = path; + return make_ipfs_repository(&fs_repo); +} diff --git a/test/test_helper.h b/test/test_helper.h new file mode 100644 index 0000000..1d5b8ce --- /dev/null +++ b/test/test_helper.h @@ -0,0 +1,5 @@ +/** + * Create a new repository in the directory, erasing old one + * NOTE: base directory must already exist + */ +int drop_and_build_repository(const char* dir); diff --git a/test/testit.c b/test/testit.c index 36cab72..d1ff6d1 100644 --- a/test/testit.c +++ b/test/testit.c @@ -72,25 +72,40 @@ int (*funcs[])(void) = { */ int main(int argc, char** argv) { int counter = 0; + int tests_ran = 0; char* test_wanted; int only_one = 0; if(argc > 1) { only_one = 1; - test_wanted = argv[1]; - } - for (int i = 0; i < sizeof(names) / sizeof(names[0]); i++) { - if (only_one && strcmp(names[i], test_wanted) == 0) - counter += testit(names[i], funcs[i]); + if (argv[1][0] == '\'') { // some shells put quotes around arguments + argv[1][strlen(argv[1])-1] = 0; + test_wanted = &(argv[1][1]); + } else - if (!only_one) + test_wanted = argv[1]; + } + int array_length = sizeof(funcs) / sizeof(funcs[0]); + for (int i = 0; i < array_length; i++) { + if (only_one && strcmp(names[i], test_wanted) == 0) { + tests_ran++; + counter += testit(names[i], funcs[i]); + } + else + if (!only_one) { + tests_ran++; counter += testit(names[i], funcs[i]); + } } - if (counter > 0) { - printf("***** There were %d failed test(s) *****\n", counter); - } else { - printf("All tests passed\n"); + if (tests_ran == 0) + printf("***** No tests found *****\n"); + else { + if (counter > 0) { + printf("***** There were %d failed test(s) *****\n", counter); + } else { + printf("All %d tests passed\n", tests_ran); + } } return 1; }