Beginnings of testing for MerkleDag

This commit is contained in:
jmjatlanta 2016-12-05 13:11:22 -05:00
parent 0245aa6549
commit f9d927f375
8 changed files with 223 additions and 117 deletions

View file

@ -130,9 +130,10 @@ struct Node * N_Create_From_Link(struct Link * mylink);
/*N_Create_From_Data /*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 length of buffer
* returns a node with the data you inputted. * 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 /*Node_Resolve_Max_Size
* !!!This shouldn't concern you! * !!!This shouldn't concern you!

View file

@ -223,14 +223,16 @@ struct Node * N_Create_From_Link(struct Link * mylink)
} }
/*N_Create_From_Data /*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. * 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; struct Node * mynode;
mynode = (struct Node *) malloc(sizeof(struct Node)); mynode = (struct Node *) malloc(sizeof(struct Node));
mynode->data = data; mynode->data = data;
mynode->data_size = data_size;
mynode->cached = NULL; mynode->cached = NULL;
return mynode; return mynode;
} }

View file

@ -2,7 +2,7 @@ CC = gcc
CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-multihash/include -I../../c-multiaddr/ -g3 -Wall 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 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 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 \ ../blocks/block.o ../blocks/blockstore.o \
../cid/cid.o \ ../cid/cid.o \
../cmd/ipfs/init.o \ ../cmd/ipfs/init.o \

View file

@ -1,11 +1,17 @@
#include "ipfs/merkledag/merkledag.h" #include "ipfs/merkledag/merkledag.h"
#include "ipfs/node/node.h" #include "ipfs/node/node.h"
#include "../test_helper.h"
int test_merkledag_add_data() { int test_merkledag_add_data() {
int retVal = 0; int retVal = 0;
// create a fresh repo
retVal = drop_and_build_repository("/tmp/.ipfs");
if (retVal == 0)
return 0;
// open the fs repo // open the fs repo
struct RepoConfig* repo_config; struct RepoConfig* repo_config = NULL;
struct FSRepo* fs_repo; struct FSRepo* fs_repo;
const char* path = "/tmp/.ipfs"; const char* path = "/tmp/.ipfs";
@ -21,6 +27,9 @@ int test_merkledag_add_data() {
return 0; 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 // create data for node
size_t binary_data_size = 255; size_t binary_data_size = 255;
unsigned char binary_data[binary_data_size]; unsigned char binary_data[binary_data_size];
@ -29,17 +38,64 @@ int test_merkledag_add_data() {
} }
// create a node // 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) if (retVal == 0)
return 0; return 0;
// make sure everything is correct // make sure everything is correct
if (node->cached == NULL) if (node1->cached == NULL)
return 0; 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; return 1;
} }

View file

@ -4,105 +4,11 @@
#include "ipfs/repo/config/config.h" #include "ipfs/repo/config/config.h"
#include "ipfs/repo/fsrepo/fs_repo.h" #include "ipfs/repo/fsrepo/fs_repo.h"
#include "../test_helper.h"
#include <dirent.h> #include <dirent.h>
#include <sys/stat.h> #include <sys/stat.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;
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 * 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!"; const unsigned char* input = "Hello, world!";
// build the ipfs repository, then shut it down, so we can start fresh // build the ipfs repository, then shut it down, so we can start fresh
struct FSRepo* fs_repo; drop_and_build_repository("/tmp/.ipfs");
retVal = make_ipfs_repository(fs_repo);
if (retVal == 0) if (retVal == 0)
return 0; return 0;
@ -130,6 +35,7 @@ int test_ipfs_datastore_put() {
return 0; return 0;
// open the repository // open the repository
struct FSRepo* fs_repo;
retVal = ipfs_repo_fsrepo_new("/tmp/.ipfs", NULL, &fs_repo); retVal = ipfs_repo_fsrepo_new("/tmp/.ipfs", NULL, &fs_repo);
if (retVal == 0) if (retVal == 0)
return 0; return 0;

121
test/test_helper.c Normal file
View file

@ -0,0 +1,121 @@
#include <dirent.h>
#include <sys/stat.h>
#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);
}

5
test/test_helper.h Normal file
View file

@ -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);

View file

@ -72,25 +72,40 @@ int (*funcs[])(void) = {
*/ */
int main(int argc, char** argv) { int main(int argc, char** argv) {
int counter = 0; int counter = 0;
int tests_ran = 0;
char* test_wanted; char* test_wanted;
int only_one = 0; int only_one = 0;
if(argc > 1) { if(argc > 1) {
only_one = 1; only_one = 1;
if (argv[1][0] == '\'') { // some shells put quotes around arguments
argv[1][strlen(argv[1])-1] = 0;
test_wanted = &(argv[1][1]);
}
else
test_wanted = argv[1]; test_wanted = argv[1];
} }
for (int i = 0; i < sizeof(names) / sizeof(names[0]); i++) { int array_length = sizeof(funcs) / sizeof(funcs[0]);
if (only_one && strcmp(names[i], test_wanted) == 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]); counter += testit(names[i], funcs[i]);
}
else else
if (!only_one) if (!only_one) {
tests_ran++;
counter += testit(names[i], funcs[i]); counter += testit(names[i], funcs[i]);
}
} }
if (tests_ran == 0)
printf("***** No tests found *****\n");
else {
if (counter > 0) { if (counter > 0) {
printf("***** There were %d failed test(s) *****\n", counter); printf("***** There were %d failed test(s) *****\n", counter);
} else { } else {
printf("All tests passed\n"); printf("All %d tests passed\n", tests_ran);
}
} }
return 1; return 1;
} }