add unit test to check for multiple calls to done()

This commit is contained in:
Steven Siloti 2015-11-09 20:05:05 -08:00
parent c2277b3ea5
commit 08632aa5f7
1 changed files with 86 additions and 0 deletions

View File

@ -1920,6 +1920,92 @@ TORRENT_TEST(dht)
g_put_count = 0;
} while (false);
// verify that done() is only invoked once
// See PR 252
g_sent_packets.clear();
do
{
// set the branching factor to k to make this a little easier
int old_branching = sett.search_branching;
sett.search_branching = 8;
dht::node node(&s, sett, (node_id::min)(), &observer, cnt);
sha1_hash target = hasher(public_key, item_pk_len).final();
enum { num_test_nodes = 9 }; // we need K + 1 nodes to create the failing sequence
node_entry nodes[num_test_nodes] =
{ node_entry(target, udp::endpoint(address_v4::from_string("1.1.1.1"), 1231))
, node_entry(target, udp::endpoint(address_v4::from_string("2.2.2.2"), 1232))
, node_entry(target, udp::endpoint(address_v4::from_string("3.3.3.3"), 1233))
, node_entry(target, udp::endpoint(address_v4::from_string("4.4.4.4"), 1234))
, node_entry(target, udp::endpoint(address_v4::from_string("5.5.5.5"), 1235))
, node_entry(target, udp::endpoint(address_v4::from_string("6.6.6.6"), 1236))
, node_entry(target, udp::endpoint(address_v4::from_string("7.7.7.7"), 1237))
, node_entry(target, udp::endpoint(address_v4::from_string("8.8.8.8"), 1238))
, node_entry(target, udp::endpoint(address_v4::from_string("9.9.9.9"), 1239)) };
// invert the ith most significant byte so that the test nodes are
// progressivly closer to the target item
for (int i = 0; i < num_test_nodes; ++i)
nodes[i].id[i] = ~nodes[i].id[i];
// add the first k nodes to the subject's routing table
for (int i = 0; i < 8; ++i)
node.m_table.add_node(nodes[i]);
// kick off a mutable get request
g_put_item.assign(items[0].ent, empty_salt, seq, public_key, private_key);
node.get_item(target, get_item_cb);
TEST_EQUAL(g_sent_packets.size(), 8);
if (g_sent_packets.size() != 8) break;
// first send responses for the k closest nodes
for (int i = 1;; ++i)
{
// once the k closest nodes have responded, send the final response
// from the farthest node, this shouldn't trigger a second call to
// get_item_cb
if (i == num_test_nodes) i = 0;
std::list<std::pair<udp::endpoint, entry> >::iterator packet = find_packet(nodes[i].ep());
TEST_CHECK(packet != g_sent_packets.end());
if (packet == g_sent_packets.end()) continue;
lazy_from_entry(packet->second, response);
ret = verify_message(response, get_item_desc, parsed, 6, error_string
, sizeof(error_string));
if (!ret)
{
fprintf(stderr, " invalid get request: %s\n", print_entry(response).c_str());
TEST_ERROR(error_string);
continue;
}
char t[10];
snprintf(t, sizeof(t), "%02d", i);
msg_args args;
args.token(t).port(1234).nid(nodes[i].id);
// add the address of the closest node to the first response
if (i == 1)
args.nodes(nodes_t(1, nodes[8]));
send_dht_response(node, response, nodes[i].ep(), args);
g_sent_packets.erase(packet);
// once we've sent the response from the farthest node, we're done
if (i == 0) break;
}
TEST_EQUAL(g_put_count, 1);
// k nodes should now have outstanding put requests
TEST_EQUAL(g_sent_packets.size(), 8);
g_sent_packets.clear();
g_put_item.clear();
g_put_count = 0;
sett.search_branching = old_branching;
} while (false);
}
void get_test_keypair(char* public_key, char* private_key)