Fixes for various memory leaks
This commit is contained in:
parent
d6ee0f7d5d
commit
a5e5a71ddd
9 changed files with 123 additions and 40 deletions
|
@ -38,7 +38,7 @@ int ipfs_daemon_start(char* repo_path) {
|
||||||
|
|
||||||
//ipfs_bootstrap_routing(local_node);
|
//ipfs_bootstrap_routing(local_node);
|
||||||
|
|
||||||
libp2p_logger_info("daemon", "Daemon is ready\n");
|
libp2p_logger_info("daemon", "Daemon for %s is ready on port %d\n", listen_param.local_node->identity->peer_id, listen_param.port);
|
||||||
|
|
||||||
// Wait for pthreads to finish.
|
// Wait for pthreads to finish.
|
||||||
while (count_pths) {
|
while (count_pths) {
|
||||||
|
|
15
core/null.c
15
core/null.c
|
@ -23,6 +23,9 @@
|
||||||
|
|
||||||
#define BUF_SIZE 4096
|
#define BUF_SIZE 4096
|
||||||
|
|
||||||
|
// this should be set to 5 for normal operation, perhaps higher for debugging purposes
|
||||||
|
#define DEFAULT_NETWORK_TIMEOUT 5
|
||||||
|
|
||||||
static int null_shutting_down = 0;
|
static int null_shutting_down = 0;
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
@ -64,7 +67,7 @@ void ipfs_null_connection (void *ptr)
|
||||||
// check if they're looking for an upgrade (i.e. secio)
|
// check if they're looking for an upgrade (i.e. secio)
|
||||||
unsigned char* results = NULL;
|
unsigned char* results = NULL;
|
||||||
size_t bytes_read = 0;
|
size_t bytes_read = 0;
|
||||||
if (!session.default_stream->read(&session, &results, &bytes_read, 5) ) {
|
if (!session.default_stream->read(&session, &results, &bytes_read, DEFAULT_NETWORK_TIMEOUT) ) {
|
||||||
libp2p_logger_debug("null", "stream transaction read returned false\n");
|
libp2p_logger_debug("null", "stream transaction read returned false\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -94,7 +97,7 @@ void ipfs_null_connection (void *ptr)
|
||||||
while(_continue) {
|
while(_continue) {
|
||||||
unsigned char* hash;
|
unsigned char* hash;
|
||||||
size_t hash_length = 0;
|
size_t hash_length = 0;
|
||||||
_continue = session.default_stream->read(&session, &hash, &hash_length, 5);
|
_continue = session.default_stream->read(&session, &hash, &hash_length, DEFAULT_NETWORK_TIMEOUT);
|
||||||
if (hash_length < 20) {
|
if (hash_length < 20) {
|
||||||
_continue = 0;
|
_continue = 0;
|
||||||
continue;
|
continue;
|
||||||
|
@ -161,13 +164,13 @@ void *ipfs_null_listen (void *ptr)
|
||||||
|
|
||||||
if ((socketfd = socket_listen(socket_tcp4(), &(listen_param->ipv4), &(listen_param->port))) <= 0) {
|
if ((socketfd = socket_listen(socket_tcp4(), &(listen_param->ipv4), &(listen_param->port))) <= 0) {
|
||||||
libp2p_logger_error("null", "Failed to init null router. Address: %d, Port: %d\n", listen_param->ipv4, listen_param->port);
|
libp2p_logger_error("null", "Failed to init null router. Address: %d, Port: %d\n", listen_param->ipv4, listen_param->port);
|
||||||
exit (1);
|
return (void*) 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
libp2p_logger_log("null", LOGLEVEL_ERROR, "Ipfs listening on %d\n", listen_param->port);
|
libp2p_logger_error("null", "Ipfs listening on %d\n", listen_param->port);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int numDescriptors = socket_read_select4(socketfd, 5);
|
int numDescriptors = socket_read_select4(socketfd, 2);
|
||||||
if (null_shutting_down) {
|
if (null_shutting_down) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -197,6 +200,8 @@ void *ipfs_null_listen (void *ptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
close(socketfd);
|
||||||
|
|
||||||
thpool_destroy(thpool);
|
thpool_destroy(thpool);
|
||||||
|
|
||||||
return (void*) 2;
|
return (void*) 2;
|
||||||
|
|
|
@ -95,10 +95,20 @@ int ipfs_repo_config_init(struct RepoConfig* config, unsigned int num_bits_for_k
|
||||||
// identity
|
// identity
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
while (counter < 5) {
|
while (counter < 5) {
|
||||||
|
if (counter > 0) {
|
||||||
|
//TODO: This shouldn't be here, but it was the only way to cleanup. Need to find a better way...
|
||||||
|
if (config->identity->private_key.public_key_der != NULL)
|
||||||
|
free(config->identity->private_key.public_key_der);
|
||||||
|
if (config->identity->private_key.der != NULL)
|
||||||
|
free(config->identity->private_key.der);
|
||||||
|
if (config->identity->peer_id != NULL)
|
||||||
|
free(config->identity->peer_id);
|
||||||
|
}
|
||||||
if (!repo_config_identity_init(config->identity, num_bits_for_keypair))
|
if (!repo_config_identity_init(config->identity, num_bits_for_keypair))
|
||||||
return 0;
|
return 0;
|
||||||
if (ipfs_repo_config_is_valid_identity(config->identity))
|
if (ipfs_repo_config_is_valid_identity(config->identity))
|
||||||
break;
|
break;
|
||||||
|
// we didn't get it right, try again
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -318,7 +318,7 @@ int _get_json_string_value(char* data, const jsmntok_t* tokens, int tok_length,
|
||||||
return 0;
|
return 0;
|
||||||
// allocate memory
|
// allocate memory
|
||||||
int str_len = curr_token->end - curr_token->start;
|
int str_len = curr_token->end - curr_token->start;
|
||||||
*result = malloc(sizeof(char) * str_len + 1);
|
*result = malloc(str_len + 1);
|
||||||
if (*result == NULL)
|
if (*result == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
// copy in the string
|
// copy in the string
|
||||||
|
|
|
@ -42,7 +42,7 @@ int ipfs_routing_kademlia_get_value(struct IpfsRouting* routing, const unsigned
|
||||||
* @param routing the context
|
* @param routing the context
|
||||||
* @param key the key to what we're looking for
|
* @param key the key to what we're looking for
|
||||||
* @param key_size the size of the key
|
* @param key_size the size of the key
|
||||||
* @param results the results
|
* @param results the results, which is a vector of MultiAddress*
|
||||||
* @param results_size the size of the results buffer
|
* @param results_size the size of the results buffer
|
||||||
* @returns true(1) on success, otherwise false(0)
|
* @returns true(1) on success, otherwise false(0)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -134,7 +134,7 @@ int ipfs_routing_online_find_providers(struct IpfsRouting* routing, const unsign
|
||||||
}
|
}
|
||||||
|
|
||||||
*peers = libp2p_utils_vector_new(1);
|
*peers = libp2p_utils_vector_new(1);
|
||||||
libp2p_utils_vector_add(*peers, libp2p_peer_copy(peer));
|
libp2p_utils_vector_add(*peers, peer);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,9 +158,22 @@ int ipfs_routing_online_ask_peer_for_peer(struct Libp2pPeer* whoToAsk, const uns
|
||||||
memcpy(message->key, peer_id, peer_id_size);
|
memcpy(message->key, peer_id, peer_id_size);
|
||||||
|
|
||||||
return_message = ipfs_routing_online_send_receive_message(whoToAsk->connection, message);
|
return_message = ipfs_routing_online_send_receive_message(whoToAsk->connection, message);
|
||||||
if (return_message == NULL || return_message->provider_peer_head == NULL || return_message->provider_peer_head->item == NULL)
|
if (return_message == NULL) {
|
||||||
|
// some kind of network error
|
||||||
|
whoToAsk->connection_type = CONNECTION_TYPE_NOT_CONNECTED;
|
||||||
|
char* id[whoToAsk->id_size + 1];
|
||||||
|
memcpy(id, whoToAsk->id, whoToAsk->id_size);
|
||||||
|
id[whoToAsk->id_size] = 0;
|
||||||
|
libp2p_logger_error("online", "Connection to %s is broken\n", id);
|
||||||
goto exit;
|
goto exit;
|
||||||
|
}
|
||||||
|
if ( return_message->provider_peer_head == NULL || return_message->provider_peer_head->item == NULL)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
*result = libp2p_peer_copy(return_message->provider_peer_head->item);
|
*result = libp2p_peer_copy(return_message->provider_peer_head->item);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
retVal = 1;
|
retVal = 1;
|
||||||
|
@ -406,10 +419,12 @@ int ipfs_routing_online_get_value (ipfs_routing* routing, const unsigned char *k
|
||||||
retVal = 1;
|
retVal = 1;
|
||||||
exit:
|
exit:
|
||||||
if (peers != NULL) {
|
if (peers != NULL) {
|
||||||
|
/* Free the vector, not the items
|
||||||
for (int i = 0; i < peers->total; i++) {
|
for (int i = 0; i < peers->total; i++) {
|
||||||
struct Libp2pPeer* current = libp2p_utils_vector_get(peers, i);
|
struct Libp2pPeer* current = libp2p_utils_vector_get(peers, i);
|
||||||
libp2p_peer_free(current);
|
libp2p_peer_free(current);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
libp2p_utils_vector_free(peers);
|
libp2p_utils_vector_free(peers);
|
||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
|
|
|
@ -35,6 +35,12 @@ int test_routing_find_peer() {
|
||||||
struct Libp2pPeer* result = NULL;
|
struct Libp2pPeer* result = NULL;
|
||||||
struct HashtableNode *node = NULL;
|
struct HashtableNode *node = NULL;
|
||||||
|
|
||||||
|
//libp2p_logger_add_class("online");
|
||||||
|
//libp2p_logger_add_class("null");
|
||||||
|
//libp2p_logger_add_class("daemon");
|
||||||
|
//libp2p_logger_add_class("dht_protocol");
|
||||||
|
//libp2p_logger_add_class("peerstore");
|
||||||
|
|
||||||
// create peer 1
|
// create peer 1
|
||||||
os_utils_setenv("IPFS_PATH", ipfs_path, 1);
|
os_utils_setenv("IPFS_PATH", ipfs_path, 1);
|
||||||
drop_and_build_repository(ipfs_path, 4001, NULL, &peer_id_1);
|
drop_and_build_repository(ipfs_path, 4001, NULL, &peer_id_1);
|
||||||
|
@ -46,6 +52,8 @@ int test_routing_find_peer() {
|
||||||
goto exit;
|
goto exit;
|
||||||
thread1_started = 1;
|
thread1_started = 1;
|
||||||
|
|
||||||
|
sleep(3);
|
||||||
|
|
||||||
// create peer 2
|
// create peer 2
|
||||||
ipfs_path = "/tmp/test2";
|
ipfs_path = "/tmp/test2";
|
||||||
os_utils_setenv("IPFS_PATH", ipfs_path, 1);
|
os_utils_setenv("IPFS_PATH", ipfs_path, 1);
|
||||||
|
@ -56,6 +64,7 @@ int test_routing_find_peer() {
|
||||||
//TODO: Find a better way to do this...
|
//TODO: Find a better way to do this...
|
||||||
size_t bytes_written = 0;
|
size_t bytes_written = 0;
|
||||||
ipfs_node_online_new(ipfs_path, &local_node2);
|
ipfs_node_online_new(ipfs_path, &local_node2);
|
||||||
|
local_node2->routing->Bootstrap(local_node2->routing);
|
||||||
ipfs_import_file(NULL, "/home/parallels/ipfstest/hello_world.txt", &node, local_node2, &bytes_written, 0);
|
ipfs_import_file(NULL, "/home/parallels/ipfstest/hello_world.txt", &node, local_node2, &bytes_written, 0);
|
||||||
ipfs_node_free(local_node2);
|
ipfs_node_free(local_node2);
|
||||||
// start the daemon in a separate thread
|
// start the daemon in a separate thread
|
||||||
|
@ -63,7 +72,10 @@ int test_routing_find_peer() {
|
||||||
goto exit;
|
goto exit;
|
||||||
thread2_started = 1;
|
thread2_started = 1;
|
||||||
|
|
||||||
// create my peer, peer 3
|
// JMJ wait for everything to start up
|
||||||
|
sleep(3);
|
||||||
|
|
||||||
|
// create my peer, peer 3
|
||||||
ipfs_path = "/tmp/test3";
|
ipfs_path = "/tmp/test3";
|
||||||
os_utils_setenv("IPFS_PATH", ipfs_path, 1);
|
os_utils_setenv("IPFS_PATH", ipfs_path, 1);
|
||||||
libp2p_utils_vector_add(ma_vector, ma_peer1);
|
libp2p_utils_vector_add(ma_vector, ma_peer1);
|
||||||
|
@ -82,10 +94,13 @@ int test_routing_find_peer() {
|
||||||
|
|
||||||
local_node.routing->Bootstrap(local_node.routing);
|
local_node.routing->Bootstrap(local_node.routing);
|
||||||
|
|
||||||
if (!local_node.routing->FindPeer(local_node.routing, (unsigned char*)peer_id_2, strlen(peer_id_2), &result))
|
if (!local_node.routing->FindPeer(local_node.routing, (unsigned char*)peer_id_2, strlen(peer_id_2), &result)) {
|
||||||
|
fprintf(stderr, "Unable to find peer %s by asking %s\n", peer_id_2, peer_id_1);
|
||||||
goto exit;
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
|
fprintf(stderr, "Result was NULL\n");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,6 +132,8 @@ int test_routing_find_peer() {
|
||||||
libp2p_peerstore_free(local_node.peerstore);
|
libp2p_peerstore_free(local_node.peerstore);
|
||||||
if (local_node.routing != NULL)
|
if (local_node.routing != NULL)
|
||||||
ipfs_routing_online_free(local_node.routing);
|
ipfs_routing_online_free(local_node.routing);
|
||||||
|
if (result != NULL)
|
||||||
|
libp2p_peer_free(result);
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
|
|
||||||
|
@ -264,10 +281,12 @@ int test_routing_find_providers() {
|
||||||
ipfs_hashtable_node_free(node);
|
ipfs_hashtable_node_free(node);
|
||||||
if (result != NULL) {
|
if (result != NULL) {
|
||||||
// we have a vector of peers. Clean 'em up:
|
// we have a vector of peers. Clean 'em up:
|
||||||
|
/* free the vector, not the peers.
|
||||||
for(int i = 0; i < result->total; i++) {
|
for(int i = 0; i < result->total; i++) {
|
||||||
struct Libp2pPeer* p = (struct Libp2pPeer*)libp2p_utils_vector_get(result, i);
|
struct Libp2pPeer* p = (struct Libp2pPeer*)libp2p_utils_vector_get(result, i);
|
||||||
libp2p_peer_free(p);
|
libp2p_peer_free(p);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
libp2p_utils_vector_free(result);
|
libp2p_utils_vector_free(result);
|
||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
|
@ -398,8 +417,9 @@ int test_routing_retrieve_file_third_party() {
|
||||||
// create a vector to hold peer1's multiaddress so we can connect as a peer
|
// create a vector to hold peer1's multiaddress so we can connect as a peer
|
||||||
ma_vector2 = libp2p_utils_vector_new(1);
|
ma_vector2 = libp2p_utils_vector_new(1);
|
||||||
libp2p_utils_vector_add(ma_vector2, ma_peer1);
|
libp2p_utils_vector_add(ma_vector2, ma_peer1);
|
||||||
// note: this distroys some things, as it frees the fs_repo_3:
|
// note: this destroys some things, as it frees the fs_repo_3:
|
||||||
drop_and_build_repository(ipfs_path, 4002, ma_vector2, &peer_id_2);
|
drop_and_build_repository(ipfs_path, 4002, ma_vector2, &peer_id_2);
|
||||||
|
multiaddress_free(ma_peer1);
|
||||||
// add a file, to prime the connection to peer 1
|
// add a file, to prime the connection to peer 1
|
||||||
//TODO: Find a better way to do this...
|
//TODO: Find a better way to do this...
|
||||||
size_t bytes_written = 0;
|
size_t bytes_written = 0;
|
||||||
|
@ -427,6 +447,7 @@ int test_routing_retrieve_file_third_party() {
|
||||||
ma_vector3 = libp2p_utils_vector_new(1);
|
ma_vector3 = libp2p_utils_vector_new(1);
|
||||||
libp2p_utils_vector_add(ma_vector3, ma_peer1);
|
libp2p_utils_vector_add(ma_vector3, ma_peer1);
|
||||||
drop_and_build_repository(ipfs_path, 4003, ma_vector3, &peer_id_3);
|
drop_and_build_repository(ipfs_path, 4003, ma_vector3, &peer_id_3);
|
||||||
|
multiaddress_free(ma_peer1);
|
||||||
ipfs_node_online_new(ipfs_path, &ipfs_node3);
|
ipfs_node_online_new(ipfs_path, &ipfs_node3);
|
||||||
|
|
||||||
ipfs_node3->routing->Bootstrap(ipfs_node3->routing);
|
ipfs_node3->routing->Bootstrap(ipfs_node3->routing);
|
||||||
|
@ -532,6 +553,7 @@ int test_routing_retrieve_large_file() {
|
||||||
libp2p_utils_vector_add(ma_vector2, ma_peer1);
|
libp2p_utils_vector_add(ma_vector2, ma_peer1);
|
||||||
// note: this distroys some things, as it frees the fs_repo_3:
|
// note: this distroys some things, as it frees the fs_repo_3:
|
||||||
drop_and_build_repository(ipfs_path, 4002, ma_vector2, &peer_id_2);
|
drop_and_build_repository(ipfs_path, 4002, ma_vector2, &peer_id_2);
|
||||||
|
multiaddress_free(ma_peer1);
|
||||||
// add a file, to prime the connection to peer 1
|
// add a file, to prime the connection to peer 1
|
||||||
//TODO: Find a better way to do this...
|
//TODO: Find a better way to do this...
|
||||||
size_t bytes_written = 0;
|
size_t bytes_written = 0;
|
||||||
|
@ -560,6 +582,7 @@ int test_routing_retrieve_large_file() {
|
||||||
ma_vector3 = libp2p_utils_vector_new(1);
|
ma_vector3 = libp2p_utils_vector_new(1);
|
||||||
libp2p_utils_vector_add(ma_vector3, ma_peer1);
|
libp2p_utils_vector_add(ma_vector3, ma_peer1);
|
||||||
drop_and_build_repository(ipfs_path, 4003, ma_vector3, &peer_id_3);
|
drop_and_build_repository(ipfs_path, 4003, ma_vector3, &peer_id_3);
|
||||||
|
multiaddress_free(ma_peer1);
|
||||||
ipfs_node_online_new(ipfs_path, &ipfs_node3);
|
ipfs_node_online_new(ipfs_path, &ipfs_node3);
|
||||||
|
|
||||||
ipfs_node3->routing->Bootstrap(ipfs_node3->routing);
|
ipfs_node3->routing->Bootstrap(ipfs_node3->routing);
|
||||||
|
|
|
@ -150,6 +150,8 @@ int test_routing_supernode_get_remote_value() {
|
||||||
ipfs_repo_fsrepo_free(fs_repo);
|
ipfs_repo_fsrepo_free(fs_repo);
|
||||||
if (ipfs_node != NULL)
|
if (ipfs_node != NULL)
|
||||||
free(ipfs_node);
|
free(ipfs_node);
|
||||||
|
if (multiaddresses != NULL)
|
||||||
|
libp2p_utils_vector_free(multiaddresses);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,6 +264,8 @@ int test_routing_supernode_get_value() {
|
||||||
stop_kademlia();
|
stop_kademlia();
|
||||||
if (fs_repo != NULL)
|
if (fs_repo != NULL)
|
||||||
ipfs_repo_fsrepo_free(fs_repo);
|
ipfs_repo_fsrepo_free(fs_repo);
|
||||||
|
if (multiaddresses != NULL)
|
||||||
|
libp2p_utils_vector_free(multiaddresses);
|
||||||
return retVal;
|
return retVal;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,8 +64,8 @@ const char* names[] = {
|
||||||
"test_merkledag_get_data",
|
"test_merkledag_get_data",
|
||||||
"test_merkledag_add_node",
|
"test_merkledag_add_node",
|
||||||
"test_merkledag_add_node_with_links",
|
"test_merkledag_add_node_with_links",
|
||||||
"test_resolver_get" /*,
|
"test_resolver_get",
|
||||||
"test_routing_find_peer",
|
"test_routing_find_peer"/*,
|
||||||
"test_routing_find_providers",
|
"test_routing_find_providers",
|
||||||
"test_routing_provide",
|
"test_routing_provide",
|
||||||
"test_routing_supernode_get_value",
|
"test_routing_supernode_get_value",
|
||||||
|
@ -114,8 +114,8 @@ int (*funcs[])(void) = {
|
||||||
test_merkledag_get_data,
|
test_merkledag_get_data,
|
||||||
test_merkledag_add_node,
|
test_merkledag_add_node,
|
||||||
test_merkledag_add_node_with_links,
|
test_merkledag_add_node_with_links,
|
||||||
test_resolver_get /*,
|
test_resolver_get,
|
||||||
test_routing_find_peer,
|
test_routing_find_peer/*,
|
||||||
test_routing_find_providers,
|
test_routing_find_providers,
|
||||||
test_routing_provide,
|
test_routing_provide,
|
||||||
test_routing_supernode_get_value,
|
test_routing_supernode_get_value,
|
||||||
|
@ -127,46 +127,72 @@ int (*funcs[])(void) = {
|
||||||
test_ping,
|
test_ping,
|
||||||
test_ping_remote,
|
test_ping_remote,
|
||||||
test_null_add_provider,
|
test_null_add_provider,
|
||||||
test_resolver_remote_get*/
|
test_resolver_remote_get
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* run 1 test or run all
|
* Pull the next test name from the command line
|
||||||
|
* @param the count of arguments on the command line
|
||||||
|
* @param argv the command line arguments
|
||||||
|
* @param arg_number the current argument we want
|
||||||
|
* @returns a null terminated string of the next test or NULL
|
||||||
|
*/
|
||||||
|
char* get_test(int argc, char** argv, int arg_number) {
|
||||||
|
char* retVal = NULL;
|
||||||
|
char* ptr = NULL;
|
||||||
|
if (argc > arg_number) {
|
||||||
|
ptr = argv[arg_number];
|
||||||
|
if (ptr[0] == '\'')
|
||||||
|
ptr++;
|
||||||
|
retVal = malloc(strlen(ptr) + 1);
|
||||||
|
strcpy(retVal, ptr);
|
||||||
|
ptr = strchr(ptr, '\'');
|
||||||
|
if (ptr != NULL)
|
||||||
|
ptr[0] = 0;
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* run certain tests or run all
|
||||||
*/
|
*/
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
int tests_ran = 0;
|
int tests_ran = 0;
|
||||||
char* test_wanted;
|
char* test_wanted = NULL;
|
||||||
int only_one = 0;
|
int certain_tests = 0;
|
||||||
|
int current_test_arg = 1;
|
||||||
if(argc > 1) {
|
if(argc > 1) {
|
||||||
only_one = 1;
|
certain_tests = 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];
|
|
||||||
}
|
}
|
||||||
int array_length = sizeof(funcs) / sizeof(funcs[0]);
|
int array_length = sizeof(funcs) / sizeof(funcs[0]);
|
||||||
int array2_length = sizeof(names) / sizeof(names[0]);
|
int array2_length = sizeof(names) / sizeof(names[0]);
|
||||||
if (array_length != array2_length) {
|
if (array_length != array2_length) {
|
||||||
printf("Test arrays are not of the same length. Funcs: %d, Names: %d\n", array_length, array2_length);
|
printf("Test arrays are not of the same length. Funcs: %d, Names: %d\n", array_length, array2_length);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < array_length; i++) {
|
test_wanted = get_test(argc, argv, current_test_arg);
|
||||||
if (only_one) {
|
while (!certain_tests || test_wanted != NULL) {
|
||||||
const char* currName = names[i];
|
for (int i = 0; i < array_length; i++) {
|
||||||
if (strcmp(currName, test_wanted) == 0) {
|
if (certain_tests) {
|
||||||
tests_ran++;
|
// get the test we currently want from the command line
|
||||||
counter += testit(names[i], funcs[i]);
|
const char* currName = names[i];
|
||||||
|
if (strcmp(currName, test_wanted) == 0) {
|
||||||
|
tests_ran++;
|
||||||
|
counter += testit(names[i], funcs[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
if (!certain_tests) {
|
||||||
|
tests_ran++;
|
||||||
|
counter += testit(names[i], funcs[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
if (!certain_tests) // we did them all, not certain ones
|
||||||
if (!only_one) {
|
break;
|
||||||
tests_ran++;
|
free(test_wanted);
|
||||||
counter += testit(names[i], funcs[i]);
|
test_wanted = get_test(argc, argv, ++current_test_arg);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tests_ran == 0)
|
if (tests_ran == 0)
|
||||||
printf("***** No tests found *****\n");
|
printf("***** No tests found *****\n");
|
||||||
else {
|
else {
|
||||||
|
|
Loading…
Reference in a new issue