Going through tests, verifying functionality

This commit is contained in:
jmjatlanta 2017-10-09 09:00:48 -05:00
parent 7f89e80d7b
commit c0855c9630
7 changed files with 284 additions and 193 deletions

View file

@ -34,4 +34,12 @@ int ipfs_merkledag_get(const unsigned char* hash, size_t hash_size, struct Hasht
*/
int ipfs_merkledag_get_by_multihash(const unsigned char* multihash, size_t multihash_length, struct HashtableNode** node, const struct FSRepo* fs_repo);
/***
* Convert the data within a block to a HashtableNode
* @param block the block
* @param node_ptr where to put the results
* @returns true(1) on success, false(0) otherwise
*/
int ipfs_merkledag_convert_block_to_node(struct Block* block, struct HashtableNode** node_ptr);
#endif

View file

@ -43,6 +43,16 @@ int ipfs_merkledag_convert_node_to_block(struct HashtableNode* node, struct Bloc
return 1;
}
/***
* Convert the data within a block to a HashtableNode
* @param block the block
* @param node_ptr where to put the results
* @returns true(1) on success, false(0) otherwise
*/
int ipfs_merkledag_convert_block_to_node(struct Block* block, struct HashtableNode** node_ptr) {
return ipfs_hashtable_node_protobuf_decode(block->data, block->data_length, node_ptr);
}
/***
* Adds a node to the dagService and blockService
* @param node the node to add

View file

@ -111,14 +111,46 @@ int ipfs_routing_generic_get_value (ipfs_routing* routing, const unsigned char *
return retVal;
}
int ipfs_routing_offline_find_providers (ipfs_routing* offlineRouting, const unsigned char *key, size_t key_size, struct Libp2pVector** peers)
// forward declaration
int ipfs_routing_online_find_remote_providers(struct IpfsRouting* routing, const unsigned char* key, size_t key_size, struct Libp2pVector** peers);
int ipfs_routing_offline_find_providers (ipfs_routing* routing, const unsigned char *key, size_t key_size, struct Libp2pVector** peers)
{
return ErrOffline;
//if (routing->local_node->mode == MODE_API_AVAILABLE) {
//TODO: we need to ask the api to do this for us
//} else
//{
unsigned char* peer_id;
int peer_id_size;
struct Libp2pPeer *peer;
// see if we can find the key, and retrieve the peer who has it
if (!libp2p_providerstore_get(routing->local_node->providerstore, key, key_size, &peer_id, &peer_id_size)) {
libp2p_logger_debug("offline", "%s: Unable to find provider locally... Asking network\n", libp2p_peer_id_to_string(routing->local_node->identity->peer));
// we need to look remotely
return ipfs_routing_online_find_remote_providers(routing, key, key_size, peers);
}
libp2p_logger_debug("offline", "%s: Found provider locally. Searching for peer.\n", libp2p_peer_id_to_string(routing->local_node->identity->peer));
// now translate the peer id into a peer to get the multiaddresses
peer = libp2p_peerstore_get_peer(routing->local_node->peerstore, peer_id, peer_id_size);
free(peer_id);
if (peer == NULL) {
libp2p_logger_error("offline", "find_providers: We said we had the peer, but then we couldn't find it.\n");
return 0;
}
libp2p_logger_debug("offline", "%s: Found peer %s.\n", libp2p_peer_id_to_string(routing->local_node->identity->peer), libp2p_peer_id_to_string(peer));
*peers = libp2p_utils_vector_new(1);
libp2p_utils_vector_add(*peers, peer);
//}
return 1;
}
int ipfs_routing_offline_find_peer (ipfs_routing* offlineRouting, const unsigned char *peer_id, size_t pid_size, struct Libp2pPeer **result)
{
return ErrOffline;
return 0;
}
/**
@ -163,12 +195,62 @@ int ipfs_routing_offline_ping (ipfs_routing* offlineRouting, struct Libp2pPeer*
}
/**
* For offline, this does nothing
* Attempt to bootstrap, even if there is no API
* @param offlineRouting the interface
* @returns 0
*/
int ipfs_routing_offline_bootstrap (ipfs_routing* offlineRouting)
int ipfs_routing_offline_bootstrap (ipfs_routing* routing)
{
if (routing->local_node->mode == MODE_API_AVAILABLE) {
// do nothing
} else {
char* peer_id = NULL;
int peer_id_size = 0;
struct MultiAddress* address = NULL;
struct Libp2pPeer *peer = NULL;
// for each address in our bootstrap list, add info into the peerstore
struct Libp2pVector* bootstrap_peers = routing->local_node->repo->config->bootstrap_peers;
for(int i = 0; i < bootstrap_peers->total; i++) {
address = (struct MultiAddress*)libp2p_utils_vector_get(bootstrap_peers, i);
// attempt to get the peer ID
peer_id = multiaddress_get_peer_id(address);
if (peer_id != NULL) {
peer_id_size = strlen(peer_id);
peer = libp2p_peer_new();
peer->id_size = peer_id_size;
peer->id = malloc(peer->id_size + 1);
if (peer->id == NULL) { // out of memory?
libp2p_peer_free(peer);
free(peer_id);
return -1;
}
memcpy(peer->id, peer_id, peer->id_size);
peer->id[peer->id_size] = 0;
peer->addr_head = libp2p_utils_linked_list_new();
if (peer->addr_head == NULL) { // out of memory?
libp2p_peer_free(peer);
free(peer_id);
return -1;
}
peer->addr_head->item = multiaddress_copy(address);
libp2p_peerstore_add_peer(routing->local_node->peerstore, peer);
libp2p_peer_free(peer);
// now find it and attempt to connect
peer = libp2p_peerstore_get_peer(routing->local_node->peerstore, (const unsigned char*)peer_id, peer_id_size);
free(peer_id);
if (peer == NULL) {
return -1; // this should never happen
}
if (peer->sessionContext == NULL) { // should always be true unless we added it twice (TODO: we should prevent that earlier)
if (!libp2p_peer_connect(&routing->local_node->identity->private_key, peer, routing->local_node->peerstore, routing->local_node->repo->config->datastore, 2)) {
libp2p_logger_debug("online", "Attempted to bootstrap and connect to %s but failed. Continuing.\n", libp2p_peer_id_to_string(peer));
}
}
}
}
}
return 0;
}

2
test/blocks/test_block.h Normal file
View file

@ -0,0 +1,2 @@
#include "../test_helper.h"

View file

@ -4,6 +4,7 @@
#include "../routing/test_routing.h" // for test_routing_daemon_start
#include "libp2p/utils/vector.h"
#include "libp2p/utils/logger.h"
#include "ipfs/merkledag/merkledag.h" // for block to node conversion
#include "ipfs/exchange/bitswap/bitswap.h"
#include "ipfs/exchange/bitswap/message.h"
#include "ipfs/importer/importer.h"
@ -127,13 +128,14 @@ int test_bitswap_retrieve_file()
struct Cid* cid = NULL;
// build and open the new IPFS repository with no bootstrap peers
os_utils_setenv("IPFS_PATH", ipfs_path, 1);
drop_and_build_repository(ipfs_path, 4001, NULL, NULL);
ipfs_node_online_new(ipfs_path, &localNode);
ipfs_node_offline_new(ipfs_path, &localNode);
// add a file
localNode->routing->Bootstrap(localNode->routing);
ipfs_import_file(NULL, "/home/parallels/ipfstest/hello_world.txt", &node, localNode, &bytes_written, 0);
unsigned char bytes[256];
create_bytes(&bytes[0], 256);
create_file("/tmp/test_file.bin", &bytes[0], 256);
ipfs_import_file(NULL, "/tmp/test_file.bin", &node, localNode, &bytes_written, 0);
// build the Cid from the node information
cid = ipfs_cid_new(0, node->hash, node->hash_size, CID_DAG_PROTOBUF);
@ -184,8 +186,9 @@ int test_bitswap_retrieve_file_remote() {
int thread1_started = 0;
struct MultiAddress* ma_peer1 = NULL;
struct Libp2pVector* ma_vector2 = NULL;
struct HashtableNode* node = NULL;
struct Block* result = NULL;
struct HashtableNode* node = NULL; // the file that was put in
struct Block* result = NULL; // the block that comes back
struct HashtableNode* result_node = NULL; // the HashtableNode of the block that comes back
struct Cid* cid = NULL;
// create peer 1
@ -196,8 +199,11 @@ int test_bitswap_retrieve_file_remote() {
ma_peer1 = multiaddress_new_from_string(multiaddress_string);
// add a file
size_t bytes_written = 0;
ipfs_node_online_new(ipfs_path, &ipfs_node1);
ipfs_import_file(NULL, "/home/parallels/ipfstest/hello_world.txt", &node, ipfs_node1, &bytes_written, 0);
ipfs_node_offline_new(ipfs_path, &ipfs_node1);
unsigned char bytes[256];
create_bytes(bytes, 256);
create_file("/tmp/hello.bin", bytes, 256);
ipfs_import_file(NULL, "/tmp/hello.bin", &node, ipfs_node1, &bytes_written, 0);
// start the daemon in a separate thread
if (pthread_create(&thread1, NULL, test_daemon_start, (void*)ipfs_path) < 0) {
libp2p_logger_error("test_bitswap", "Unable to start thread 1\n");
@ -208,15 +214,14 @@ int test_bitswap_retrieve_file_remote() {
sleep(3);
// create my peer, peer 2
libp2p_logger_debug("test_routing", "Firing up the client\n");
libp2p_logger_debug("test_bitswap", "Firing up the client\n");
ipfs_path = "/tmp/test2";
ma_peer1 = multiaddress_new_from_string(multiaddress_string);
ma_vector2 = libp2p_utils_vector_new(1);
libp2p_utils_vector_add(ma_vector2, ma_peer1);
drop_and_build_repository(ipfs_path, 4002, ma_vector2, &peer_id_2);
multiaddress_free(ma_peer1);
ipfs_node_online_new(ipfs_path, &ipfs_node2);
ipfs_node_offline_new(ipfs_path, &ipfs_node2);
ipfs_node2->routing->Bootstrap(ipfs_node2->routing);
// this does the heavy lifting...
@ -231,7 +236,9 @@ int test_bitswap_retrieve_file_remote() {
goto exit;
}
if (node->data_size != result->data_length) {
// to compare sizes, we must convert the block back to a hashtable node
ipfs_merkledag_convert_block_to_node(result, &result_node);
if (node->data_size != result_node->data_size) {
libp2p_logger_error("test_bitswap", "Result sizes do not match. Should be %lu but is %lu\n", node->data_size, result->data_length);
goto exit;
}
@ -250,6 +257,8 @@ int test_bitswap_retrieve_file_remote() {
}
if (node != NULL)
ipfs_hashtable_node_free(node);
if (result_node != NULL)
ipfs_hashtable_node_free(result_node);
if (result != NULL)
ipfs_block_free(result);
if (cid != NULL)
@ -421,7 +430,10 @@ int test_bitswap_retrieve_file_third_party() {
if (!ipfs_node_online_new(ipfs_path, &ipfs_node2))
goto exit;
ipfs_node2->routing->Bootstrap(ipfs_node2->routing);
ipfs_import_file(NULL, "/home/parallels/ipfstest/hello_world.txt", &node, ipfs_node2, &bytes_written, 0);
unsigned char bytes[256];
create_bytes(&bytes[0], 256);
create_file("/tmp/hello.bin", &bytes[0], 256);
ipfs_import_file(NULL, "/tmp/hello.bin", &node, ipfs_node2, &bytes_written, 0);
ipfs_node_free(ipfs_node2);
// start the daemon in a separate thread
if (pthread_create(&thread2, NULL, test_daemon_start, (void*)ipfs_path) < 0) {
@ -440,7 +452,7 @@ int test_bitswap_retrieve_file_third_party() {
libp2p_utils_vector_add(ma_vector3, ma_peer1);
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_offline_new(ipfs_path, &ipfs_node3);
ipfs_node3->routing->Bootstrap(ipfs_node3->routing);

View file

@ -5,3 +5,4 @@
./run_test.sh test_3.sh
./run_test.sh test_4.sh
./run_test.sh test_5.sh
./run_test.sh test_6.sh

View file

@ -28,6 +28,17 @@
#include "libp2p/utils/logger.h"
#include "namesys/test_namesys.h"
struct test {
int index;
const char* name;
int (*func)(void);
int part_of_suite;
struct test* next;
};
struct test* first_test = NULL;
struct test* last_test = NULL;
int testit(const char* name, int (*func)(void)) {
fprintf(stderr, "TESTING %s...\n", name);
int retVal = func();
@ -38,145 +49,99 @@ int testit(const char* name, int (*func)(void)) {
return retVal == 0;
}
const char* names[] = {
"test_bitswap_new_free",
"test_bitswap_peer_request_queue_new",
"test_bitswap_retrieve_file",
"test_bitswap_retrieve_file_known_remote",
"test_bitswap_retrieve_file_remote",
"test_bitswap_retrieve_file_third_party",
"test_cid_new_free",
"test_cid_cast_multihash",
"test_cid_cast_non_multihash",
"test_cid_protobuf_encode_decode",
"test_core_api_startup_shutdown",
"test_core_api_object_cat",
"test_core_api_name_resolve",
"test_core_api_name_resolve_1",
"test_core_api_name_resolve_2",
"test_core_api_name_resolve_3",
"test_daemon_startup_shutdown",
"test_datastore_list_journal",
"test_journal_db",
"test_journal_encode_decode",
"test_journal_server_1",
"test_journal_server_2",
"test_repo_config_new",
"test_repo_config_init",
"test_repo_config_write",
"test_repo_config_identity_new",
"test_repo_config_identity_private_key",
"test_repo_fsrepo_write_read_block",
"test_repo_fsrepo_build",
"test_routing_supernode_start",
"test_get_init_command",
"test_import_small_file",
"test_import_large_file",
"test_repo_fsrepo_open_config",
"test_flatfs_get_directory",
"test_flatfs_get_filename",
"test_flatfs_get_full_filename",
"test_ds_key_from_binary",
"test_blocks_new",
"test_repo_bootstrap_peers_init",
"test_ipfs_datastore_put",
"test_node",
"test_node_link_encode_decode",
"test_node_encode_decode",
"test_node_peerstore",
"test_merkledag_add_data",
"test_merkledag_get_data",
"test_merkledag_add_node",
"test_merkledag_add_node_with_links",
// 50 below
"test_namesys_publisher_publish",
"test_namesys_resolver_resolve",
"test_resolver_get",
"test_routing_find_peer",
"test_routing_provide",
"test_routing_find_providers",
"test_routing_put_value",
"test_routing_supernode_get_value",
"test_routing_supernode_get_remote_value",
"test_routing_retrieve_file_third_party",
"test_routing_retrieve_large_file",
"test_unixfs_encode_decode",
"test_unixfs_encode_smallfile",
"test_ping",
"test_ping_remote",
"test_null_add_provider",
"test_resolver_remote_get"
};
int add_test(const char* name, int (*func)(void), int part_of_suite) {
// create a new test
struct test* t = (struct test*) malloc(sizeof(struct test));
t->name = name;
t->func = func;
t->part_of_suite = part_of_suite;
t->next = NULL;
if (last_test == NULL)
t->index = 0;
else
t->index = last_test->index + 1;
// place it in the collection
if (first_test == NULL) {
first_test = t;
} else {
last_test->next = t;
}
last_test = t;
int (*funcs[])(void) = {
test_bitswap_new_free,
test_bitswap_peer_request_queue_new,
test_bitswap_retrieve_file,
test_bitswap_retrieve_file_known_remote,
test_bitswap_retrieve_file_remote,
test_bitswap_retrieve_file_third_party,
test_cid_new_free,
test_cid_cast_multihash,
test_cid_cast_non_multihash,
test_cid_protobuf_encode_decode,
test_core_api_startup_shutdown,
test_core_api_object_cat,
test_core_api_name_resolve,
test_core_api_name_resolve_1,
test_core_api_name_resolve_2,
test_core_api_name_resolve_3,
test_daemon_startup_shutdown,
test_datastore_list_journal,
test_journal_db,
test_journal_encode_decode,
test_journal_server_1,
test_journal_server_2,
test_repo_config_new,
test_repo_config_init,
test_repo_config_write,
test_repo_config_identity_new,
test_repo_config_identity_private_key,
test_repo_fsrepo_write_read_block,
test_repo_fsrepo_build,
test_routing_supernode_start,
test_get_init_command,
test_import_small_file,
test_import_large_file,
test_repo_fsrepo_open_config,
test_flatfs_get_directory,
test_flatfs_get_filename,
test_flatfs_get_full_filename,
test_ds_key_from_binary,
test_blocks_new,
test_repo_bootstrap_peers_init,
test_ipfs_datastore_put,
test_node,
test_node_link_encode_decode,
test_node_encode_decode,
test_node_peerstore,
test_merkledag_add_data,
test_merkledag_get_data,
test_merkledag_add_node,
test_merkledag_add_node_with_links,
if (last_test == NULL)
return 0;
return last_test->index;
}
int build_test_collection() {
add_test("test_bitswap_new_free", test_bitswap_new_free, 1);
add_test("test_bitswap_peer_request_queue_new", test_bitswap_peer_request_queue_new, 1);
add_test("test_bitswap_retrieve_file", test_bitswap_retrieve_file, 1);
add_test("test_bitswap_retrieve_file_known_remote", test_bitswap_retrieve_file_known_remote, 0);
add_test("test_bitswap_retrieve_file_remote", test_bitswap_retrieve_file_remote, 1);
add_test("test_bitswap_retrieve_file_third_party", test_bitswap_retrieve_file_third_party, 1);
add_test("test_cid_new_free", test_cid_new_free, 1);
add_test("test_cid_cast_multihash", test_cid_cast_multihash, 1);
add_test("test_cid_cast_non_multihash", test_cid_cast_non_multihash, 1);
add_test("test_cid_protobuf_encode_decode", test_cid_protobuf_encode_decode, 1);
add_test("test_core_api_startup_shutdown", test_core_api_startup_shutdown, 1);
add_test("test_core_api_object_cat", test_core_api_object_cat, 1);
add_test("test_core_api_name_resolve", test_core_api_name_resolve, 1);
add_test("test_core_api_name_resolve_1", test_core_api_name_resolve_1, 1);
add_test("test_core_api_name_resolve_2", test_core_api_name_resolve_2, 1);
add_test("test_core_api_name_resolve_3", test_core_api_name_resolve_3, 1);
add_test("test_daemon_startup_shutdown", test_daemon_startup_shutdown, 1);
add_test("test_datastore_list_journal", test_datastore_list_journal, 1);
add_test("test_journal_db", test_journal_db, 1);
add_test("test_journal_encode_decode", test_journal_encode_decode, 1);
add_test("test_journal_server_1", test_journal_server_1, 1);
add_test("test_journal_server_2", test_journal_server_2, 1);
add_test("test_repo_config_new", test_repo_config_new, 1);
add_test("test_repo_config_init", test_repo_config_init, 1);
add_test("test_repo_config_write", test_repo_config_write, 1);
add_test("test_repo_config_identity_new", test_repo_config_identity_new, 1);
add_test("test_repo_config_identity_private_key", test_repo_config_identity_private_key, 1);
add_test("test_repo_fsrepo_write_read_block", test_repo_fsrepo_write_read_block, 1);
add_test("test_repo_fsrepo_build", test_repo_fsrepo_build, 1);
add_test("test_routing_supernode_start", test_routing_supernode_start, 1);
add_test("test_get_init_command", test_get_init_command, 1);
add_test("test_import_small_file", test_import_small_file, 1);
add_test("test_import_large_file", test_import_large_file, 1);
add_test("test_repo_fsrepo_open_config", test_repo_fsrepo_open_config, 1);
add_test("test_flatfs_get_directory", test_flatfs_get_directory, 1);
add_test("test_flatfs_get_filename", test_flatfs_get_filename, 1);
add_test("test_flatfs_get_full_filename", test_flatfs_get_full_filename, 1);
add_test("test_ds_key_from_binary", test_ds_key_from_binary, 1);
add_test("test_blocks_new", test_blocks_new, 1);
add_test("test_repo_bootstrap_peers_init", test_repo_bootstrap_peers_init, 1);
add_test("test_ipfs_datastore_put", test_ipfs_datastore_put, 1);
add_test("test_node", test_node, 1);
add_test("test_node_link_encode_decode", test_node_link_encode_decode, 1);
add_test("test_node_encode_decode", test_node_encode_decode, 1);
add_test("test_node_peerstore", test_node_peerstore, 1);
add_test("test_merkledag_add_data", test_merkledag_add_data, 1);
add_test("test_merkledag_get_data", test_merkledag_get_data, 1);
add_test("test_merkledag_add_node", test_merkledag_add_node, 1);
add_test("test_merkledag_add_node_with_links", test_merkledag_add_node_with_links, 1);
// 50 below
test_namesys_publisher_publish,
test_namesys_resolver_resolve,
test_resolver_get,
test_routing_find_peer,
test_routing_provide,
test_routing_find_providers,
test_routing_put_value,
test_routing_supernode_get_value,
test_routing_supernode_get_remote_value,
test_routing_retrieve_file_third_party,
test_routing_retrieve_large_file,
test_unixfs_encode_decode,
test_unixfs_encode_smallfile,
test_ping,
test_ping_remote,
test_null_add_provider,
test_resolver_remote_get
};
add_test("test_namesys_publisher_publish", test_namesys_publisher_publish, 1);
add_test("test_namesys_resolver_resolve", test_namesys_resolver_resolve, 1);
add_test("test_resolver_get", test_resolver_get, 1);
add_test("test_routing_find_peer", test_routing_find_peer, 1);
add_test("test_routing_provide", test_routing_provide, 1);
add_test("test_routing_find_providers", test_routing_find_providers, 1);
add_test("test_routing_put_value", test_routing_put_value, 1);
add_test("test_routing_supernode_get_value", test_routing_supernode_get_value, 1);
add_test("test_routing_supernode_get_remote_value", test_routing_supernode_get_remote_value, 1);
add_test("test_routing_retrieve_file_third_party", test_routing_retrieve_file_third_party, 1);
add_test("test_routing_retrieve_large_file", test_routing_retrieve_large_file, 1);
add_test("test_unixfs_encode_decode", test_unixfs_encode_decode, 1);
add_test("test_unixfs_encode_smallfile", test_unixfs_encode_smallfile, 1);
add_test("test_ping", test_ping, 1);
add_test("test_ping_remote", test_ping_remote, 1);
add_test("test_null_add_provider", test_null_add_provider, 1);
return add_test("test_resolver_remote_get", test_resolver_remote_get, 1);
}
/**
* Pull the next test name from the command line
@ -192,8 +157,7 @@ char* get_test(int argc, char** argv, int arg_number) {
ptr = argv[arg_number];
if (ptr[0] == '\'')
ptr++;
retVal = malloc(strlen(ptr) + 1);
strcpy(retVal, ptr);
retVal = ptr;
ptr = strchr(retVal, '\'');
if (ptr != NULL)
ptr[0] = 0;
@ -201,44 +165,56 @@ char* get_test(int argc, char** argv, int arg_number) {
return retVal;
}
struct test* get_test_by_index(int index) {
struct test* current = first_test;
while (current != NULL && current->index != index) {
current = current->next;
}
return current;
}
struct test* get_test_by_name(const char* name) {
struct test* current = first_test;
while (current != NULL && strcmp(current->name, name) != 0) {
current = current->next;
}
return current;
}
/**
* run certain tests or run all
*/
int main(int argc, char** argv) {
int counter = 0;
int tests_ran = 0;
char* test_wanted = NULL;
char* test_name_wanted = NULL;
int certain_tests = 0;
int current_test_arg = 1;
if(argc > 1) {
certain_tests = 1;
}
int array_length = sizeof(funcs) / sizeof(funcs[0]);
int array2_length = sizeof(names) / sizeof(names[0]);
if (array_length != array2_length) {
fprintf(stderr, "Test arrays are not of the same length. Funcs: %d, Names: %d\n", array_length, array2_length);
}
test_wanted = get_test(argc, argv, current_test_arg);
while (!certain_tests || test_wanted != NULL) {
for (int i = 0; i < array_length; i++) {
build_test_collection();
if (certain_tests) {
// get the test we currently want from the command line
const char* currName = names[i];
if (strcmp(currName, test_wanted) == 0) {
// certain tests were passed on the command line
test_name_wanted = get_test(argc, argv, current_test_arg);
while (test_name_wanted != NULL) {
struct test* t = get_test_by_name(test_name_wanted);
if (t != NULL) {
tests_ran++;
counter += testit(names[i], funcs[i]);
counter += testit(t->name, t->func);
}
test_name_wanted = get_test(argc, argv, ++current_test_arg);
}
else
if (!certain_tests) {
} else {
// run all tests that are part of this test suite
struct test* current = first_test;
while (current != NULL) {
if (current->part_of_suite) {
tests_ran++;
counter += testit(names[i], funcs[i]);
counter += testit(current->name, current->func);
}
current = current->next;
}
if (!certain_tests) // we did them all, not certain ones
break;
free(test_wanted);
test_wanted = get_test(argc, argv, ++current_test_arg);
}
if (tests_ran == 0)
fprintf(stderr, "***** No tests found *****\n");