TEST(Session, ClientsServers) { Timer::GetInstance().UseVirtualTime(); ConnectionManager::UseTimer = false; OverlayNetwork net = ConstructOverlay(10, 20); VerifyStoppedNetwork(net); StartNetwork(net); VerifyNetwork(net); Sessions sessions = BuildSessions(net); qDebug() << "Starting sessions..."; StartSessions(sessions); StartRound(sessions); SendTest(sessions); SendTest(sessions); DisconnectServer(sessions, true); SendTest(sessions); DisconnectServer(sessions, false); SendTest(sessions); SendTest(sessions); StopSessions(sessions); StopNetwork(sessions.network); VerifyStoppedNetwork(sessions.network); ConnectionManager::UseTimer = true; }
void RoundTest_MultiRound(CreateSessionCallback callback, bool keys = false) { Timer::GetInstance().UseVirtualTime(); int count = random(10, 100); int leader = random(0, count); int sender0 = random(0, count); int sender1 = random(0, count); while(sender0 != sender1) { sender1 = random(0, count); } QVector<TestNode *> nodes; Group *group; ConstructOverlay(count, nodes, group, keys); Id leader_id = nodes[leader]->cm.GetId(); Id session_id; CreateSession(nodes, *group, leader_id, session_id, callback); Dissent::Crypto::CppRandom rand; QByteArray msg(512, 0); rand.GenerateBlock(msg); nodes[sender0]->session->Send(msg); for(int idx = 0; idx < count; idx++) { nodes[idx]->session->Start(); } TestNode::calledback = 0; qint64 next = Timer::GetInstance().VirtualRun(); while(next != -1 && TestNode::calledback < count) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } for(int idx = 0; idx < count; idx++) { EXPECT_EQ(msg, nodes[idx]->sink.GetLastData()); } rand.GenerateBlock(msg); nodes[sender1]->session->Send(msg); TestNode::calledback = 0; next = Timer::GetInstance().VirtualRun(); while(next != -1 && TestNode::calledback < count * 2) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } for(int idx = 0; idx < count; idx++) { EXPECT_EQ(msg, nodes[idx]->sink.GetLastData()); } CleanUp(nodes); delete group; }
void RoundTest_Null(CreateSessionCallback callback, bool keys = false) { Timer::GetInstance().UseVirtualTime(); int count = random(10, 100); int leader = random(0, count); QVector<TestNode *> nodes; Group *group; ConstructOverlay(count, nodes, group, keys); for(int idx = 0; idx < count; idx++) { for(int jdx = 0; jdx < count; jdx++) { if(idx == jdx) { continue; } EXPECT_TRUE(nodes[idx]->cm.GetConnectionTable().GetConnection(nodes[jdx]->cm.GetId())); } } for(int idx = 0; idx < count; idx++) { EXPECT_TRUE(nodes[idx]->sink.GetLastData().isEmpty()); } Id leader_id = nodes[leader]->cm.GetId(); Id session_id; CreateSession(nodes, *group, leader_id, session_id, callback); for(int idx = 0; idx < count; idx++) { nodes[idx]->session->Start(); } TestNode::calledback = TestNode::failure = TestNode::success = 0; qint64 next = Timer::GetInstance().VirtualRun(); while(next != -1 && TestNode::calledback < count) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } for(int idx = 0; idx < count; idx++) { EXPECT_TRUE(nodes[idx]->sink.GetLastData().isEmpty()); } EXPECT_EQ(TestNode::success, count); EXPECT_EQ(TestNode::failure, 0); CleanUp(nodes); delete group; }
TEST(NeffKeyShuffle, Disconnect) { SessionCreator callback = SessionCreator(TCreateRound<NeffKeyShuffle>); Group::SubgroupPolicy sg_policy = Group::ManagedSubgroup; ConnectionManager::UseTimer = false; SessionLeader::EnableLogOffMonitor = false; Timer::GetInstance().UseVirtualTime(); int count = Random::GetInstance().GetInt(TEST_RANGE_MIN, TEST_RANGE_MAX); QVector<TestNode *> nodes; Group group; ConstructOverlay(count, nodes, group, sg_policy); CreateSessions(nodes, group, Id(), callback); group = BuildGroup(nodes, group); int leader = group.GetIndex(group.GetLeader()); int disconnector = Random::GetInstance().GetInt(0, count); if(sg_policy == Group::ManagedSubgroup) { while(leader == disconnector || nodes[disconnector]->ident.GetSuperPeer()) { disconnector = Random::GetInstance().GetInt(0, count); } } else { while(leader == disconnector) { disconnector = Random::GetInstance().GetInt(0, count); } } qDebug() << "Node count" << nodes.size(); qDebug() << "Leader" << group.GetLeader(); qDebug() << "Disconnector" << nodes[disconnector]->ident.GetLocalId(); SignalCounter sc, src; RoundCollector rc; foreach(TestNode *node, nodes) { QObject::connect(node->session.data(), SIGNAL(RoundStarting(const QSharedPointer<Round> &)), &sc, SLOT(Counter())); QObject::connect(node->session.data(), SIGNAL(RoundFinished(const QSharedPointer<Round> &)), &src, SLOT(Counter())); QObject::connect(node->session.data(), SIGNAL(RoundFinished(const QSharedPointer<Round> &)), &rc, SLOT(RoundFinished(const QSharedPointer<Round> &))); node->session->Start(); }
void TestRoundBad(CreateRound good_cr, CreateRound bad_cr, const BadGuyCB &callback, bool client, bool will_finish) { int servers = 3, clients = 10; ConnectionManager::UseTimer = false; Timer::GetInstance().UseVirtualTime(); OverlayNetwork net = ConstructOverlay(servers, clients); VerifyStoppedNetwork(net); StartNetwork(net); VerifyNetwork(net); Sessions sessions = BuildSessions(net, good_cr); // Find a bad guy and replace him... int badguy = Random::GetInstance().GetInt(0, clients); Id badid = net.second[badguy]->GetId(); if(!client) { badguy = Random::GetInstance().GetInt(0, servers); badid = net.first[badguy]->GetId(); } qDebug() << "Bad guy at" << badguy << badid; QSharedPointer<AsymmetricKey> key = sessions.private_keys[badid.ToString()]; if(client) { ClientPointer cs = MakeSession<ClientSession>( net.second[badguy], key, sessions.keys, bad_cr); cs->SetSink(sessions.sink_multiplexers[servers + badguy].data()); sessions.clients[badguy] = cs; } else { ServerPointer ss = MakeSession<ServerSession>( net.first[badguy], key, sessions.keys, bad_cr); ss->SetSink(sessions.sink_multiplexers[badguy].data()); sessions.servers[badguy] = ss; } // Find a sender != badguy int sender = Random::GetInstance().GetInt(0, clients); if(client) { while(sender == badguy) { sender = Random::GetInstance().GetInt(0, clients); } } QByteArray msg(64, 0); CryptoRandom().GenerateBlock(msg); sessions.clients[sender]->Send(msg); qDebug() << "Starting sessions..."; StartSessions(sessions); StartRound(sessions); QSharedPointer<Round> bad_round; if(client) { bad_round = sessions.clients[badguy]->GetRound(); } else { bad_round = sessions.servers[badguy]->GetRound(); } SignalCounter sc; for(int idx = 0; idx < servers; idx++) { QObject::connect(sessions.servers[idx].data(), SIGNAL(RoundFinished(const QSharedPointer<Anonymity::Round> &)), &sc, SLOT(Counter())); } for(int idx = 0; idx < clients; idx++) { QObject::connect(sessions.clients[idx].data(), SIGNAL(RoundFinished(const QSharedPointer<Anonymity::Round> &)), &sc, SLOT(Counter())); } RunUntil(sc, clients + servers); if(will_finish) { ASSERT_EQ(sc.GetCount(), clients + servers); ASSERT_EQ(bad_round->GetBadMembers().size(), 1); ASSERT_EQ(badid, bad_round->GetBadMembers()[0]); } if(!callback(bad_round.data())) { std::cout << "RoundTest_BadGuy was never triggered, " "consider rerunning." << std::endl; } StopNetwork(sessions.network); VerifyStoppedNetwork(sessions.network); ConnectionManager::UseTimer = true; }
void RoundTest_PeerDisconnectMiddle(CreateSessionCallback callback, CreateGroupGenerator cgg) { Timer::GetInstance().UseVirtualTime(); int count = Random::GetInstance().GetInt(TEST_RANGE_MIN, TEST_RANGE_MAX); int leader = Random::GetInstance().GetInt(0, count); int sender = Random::GetInstance().GetInt(0, count); int disconnecter = Random::GetInstance().GetInt(0, count); QVector<TestNode *> nodes; Group *group; ConstructOverlay(count, nodes, group); for(int idx = 0; idx < count; idx++) { for(int jdx = 0; jdx < count; jdx++) { if(idx == jdx) { continue; } EXPECT_TRUE(nodes[idx]->cm.GetConnectionTable().GetConnection(nodes[jdx]->cm.GetId())); } } for(int idx = 0; idx < count; idx++) { EXPECT_TRUE(nodes[idx]->sink.Count() == 0); } Id leader_id = nodes[leader]->cm.GetId(); Id session_id; CreateSessions(nodes, *group, leader_id, session_id, callback, cgg); Library *lib = CryptoFactory::GetInstance().GetLibrary(); QScopedPointer<Dissent::Utils::Random> rand(lib->GetRandomNumberGenerator()); QByteArray msg(512, 0); rand->GenerateBlock(msg); nodes[sender]->session->Send(msg); for(int idx = 0; idx < count; idx++) { nodes[idx]->session->Start(); } TestNode::calledback = 0; qint64 next = Timer::GetInstance().VirtualRun(); // XXX This needs to be improved, but what we are doing is issuing a // disconnect approximately 1 to count steps into the Round qint64 run_before_disc = Time::GetInstance().MSecsSinceEpoch() + Random::GetInstance().GetInt(10, 10 * count); while(next != -1 && TestNode::calledback < count && Time::GetInstance().MSecsSinceEpoch() < run_before_disc) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } if(Time::GetInstance().MSecsSinceEpoch() >= run_before_disc) { nodes[disconnecter]->cm.Disconnect(); } while(next != -1 && TestNode::calledback < count) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } if(Time::GetInstance().MSecsSinceEpoch() < run_before_disc) { std::cout << "RoundTest_PeerDisconnectMiddle never caused a disconnect, " "consider rerunning." << std::endl; for(int idx = 0; idx < count; idx++) { EXPECT_EQ(msg, nodes[idx]->sink.Last().first); } } else { foreach(TestNode *node, nodes) { EXPECT_TRUE(node->session->Stopped()); } }
void RoundTest_PeerDisconnectEnd(CreateSessionCallback callback, CreateGroupGenerator cgg) { Timer::GetInstance().UseVirtualTime(); int count = Random::GetInstance().GetInt(TEST_RANGE_MIN, TEST_RANGE_MAX); int leader = Random::GetInstance().GetInt(0, count); int disconnecter = Random::GetInstance().GetInt(0, count); while(leader != disconnecter) { disconnecter = Random::GetInstance().GetInt(0, count); } QVector<TestNode *> nodes; Group *group; ConstructOverlay(count, nodes, group); Id leader_id = nodes[leader]->cm.GetId(); Id session_id; CreateSessions(nodes, *group, leader_id, session_id, callback, cgg); for(int idx = 0; idx < count; idx++) { nodes[idx]->session->Start(); } TestNode::calledback = 0; qint64 next = Timer::GetInstance().VirtualRun(); while(next != -1 && TestNode::calledback < count) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } nodes[disconnecter]->session->Stop(); nodes[disconnecter]->cm.Disconnect(); EXPECT_TRUE(nodes[disconnecter]->session->Stopped()); TestNode::calledback = 0; next = Timer::GetInstance().VirtualRun(); while(next != -1 && TestNode::calledback < count) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } Library *lib = CryptoFactory::GetInstance().GetLibrary(); QScopedPointer<Dissent::Utils::Random> rand(lib->GetRandomNumberGenerator()); QByteArray msg(512, 0); rand->GenerateBlock(msg); nodes[(leader + disconnecter) % count]->session->Send(msg); TestNode::calledback = 0; next = Timer::GetInstance().VirtualRun(); while(next != -1 && TestNode::calledback < count) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } for(int idx = 0; idx < count; idx++) { EXPECT_TRUE(nodes[idx]->sink.Count() == 0); EXPECT_TRUE(nodes[idx]->session->Stopped()); } delete nodes[disconnecter]; nodes.remove(disconnecter); CleanUp(nodes); delete group; }
void RoundTest_MultiRound(CreateSessionCallback callback, CreateGroupGenerator cgg) { Timer::GetInstance().UseVirtualTime(); int count = Random::GetInstance().GetInt(TEST_RANGE_MIN, TEST_RANGE_MAX); int leader = Random::GetInstance().GetInt(0, count); int sender0 = Random::GetInstance().GetInt(0, count); int sender1 = Random::GetInstance().GetInt(0, count); while(sender0 != sender1) { sender1 = Random::GetInstance().GetInt(0, count); } QVector<TestNode *> nodes; Group *group; ConstructOverlay(count, nodes, group); Id leader_id = nodes[leader]->cm.GetId(); Id session_id; CreateSessions(nodes, *group, leader_id, session_id, callback, cgg); Library *lib = CryptoFactory::GetInstance().GetLibrary(); QScopedPointer<Dissent::Utils::Random> rand(lib->GetRandomNumberGenerator()); QByteArray msg(512, 0); rand->GenerateBlock(msg); nodes[sender0]->session->Send(msg); SignalCounter sc; for(int idx = 0; idx < count; idx++) { QObject::connect(&nodes[idx]->sink, SIGNAL(DataReceived()), &sc, SLOT(Counter())); nodes[idx]->session->Start(); } TestNode::calledback = 0; qint64 next = Timer::GetInstance().VirtualRun(); while(next != -1 && sc.GetCount() < count && TestNode::calledback < count) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } sc.Reset(); for(int idx = 0; idx < count; idx++) { EXPECT_EQ(msg, nodes[idx]->sink.Last().first); } rand->GenerateBlock(msg); nodes[sender1]->session->Send(msg); TestNode::calledback = 0; next = Timer::GetInstance().VirtualRun(); while(next != -1 && sc.GetCount() < count && TestNode::calledback < count * 2) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } for(int idx = 0; idx < count; idx++) { EXPECT_EQ(msg, nodes[idx]->sink.Last().first); } CleanUp(nodes); delete group; }
void RoundTest_PeerDisconnect(CreateSessionCallback callback, bool keys = false) { Timer::GetInstance().UseVirtualTime(); int count = random(10, 100); int leader = random(0, count); int disconnecter = random(0, count); while(leader != disconnecter) { disconnecter = random(0, count); } QVector<TestNode *> nodes; Group *group; ConstructOverlay(count, nodes, group, keys); Id leader_id = nodes[leader]->cm.GetId(); Id session_id; CreateSession(nodes, *group, leader_id, session_id, callback); for(int idx = 0; idx < count; idx++) { nodes[idx]->session->Start(); } TestNode::calledback = 0; qint64 next = Timer::GetInstance().VirtualRun(); while(next != -1 && TestNode::calledback < count) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } nodes[disconnecter]->session->Stop(); nodes[disconnecter]->cm.Disconnect(); EXPECT_TRUE(nodes[disconnecter]->session->Closed()); TestNode::calledback = 0; next = Timer::GetInstance().VirtualRun(); while(next != -1 && TestNode::calledback < count) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } Dissent::Crypto::CppRandom rand; QByteArray msg(512, 0); rand.GenerateBlock(msg); nodes[(leader + disconnecter) % count]->session->Send(msg); TestNode::calledback = 0; next = Timer::GetInstance().VirtualRun(); while(next != -1 && TestNode::calledback < count) { Time::GetInstance().IncrementVirtualClock(next); next = Timer::GetInstance().VirtualRun(); } for(int idx = 0; idx < count; idx++) { EXPECT_TRUE(nodes[idx]->sink.GetLastData().isEmpty()); EXPECT_TRUE(nodes[idx]->session->Closed()); } delete nodes[disconnecter]; nodes.remove(disconnecter); CleanUp(nodes); delete group; }