/* * Accept a new TCP connection. */ void AdvancedTCPConnectorTest::AcceptedConnection(TCPSocket *new_socket) { OLA_ASSERT_NOT_NULL(new_socket); GenericSocketAddress address = new_socket->GetPeerAddress(); OLA_ASSERT_TRUE(address.Family() == AF_INET); OLA_INFO << "Connection from " << address; // terminate the ss when this connection is closed new_socket->SetOnClose( ola::NewSingleCallback(this, &AdvancedTCPConnectorTest::TerminateOnClose)); m_ss->AddReadDescriptor(new_socket, true); }
/* * Accept a new TCP connection. */ void AdvancedTCPConnectorTest::AcceptedConnection(TcpSocket *new_socket) { CPPUNIT_ASSERT(new_socket); IPV4Address address; uint16_t port; CPPUNIT_ASSERT(new_socket->GetPeer(&address, &port)); OLA_INFO << "Connection from " << address << ":" << port; // terminate the ss when this connection is closed new_socket->SetOnClose( ola::NewSingleCallback(this, &AdvancedTCPConnectorTest::TerminateOnClose)); m_ss->AddReadDescriptor(new_socket, true); }
void LogicReader::DeviceDisconnected(U64 device) { OLA_FATAL << "Device " << device << " disconnected"; MutexLocker lock(&m_mu); if (device != m_device_id) { return; } m_device_id = 0; m_logic = NULL; m_ss->Terminate(); }
/* * Setup the select server */ void AdvancedTCPConnectorTest::setUp() { m_tcp_socket_factory.reset(new ola::network::TCPSocketFactory( ola::NewCallback(this, &AdvancedTCPConnectorTest::OnConnect))); m_connected_socket = NULL; ola::InitLogging(ola::OLA_LOG_INFO, ola::OLA_LOG_STDERR); m_ss = new SelectServer(NULL, &m_clock); m_timeout_id = m_ss->RegisterSingleTimeout( ABORT_TIMEOUT_IN_MS, ola::NewSingleCallback(this, &AdvancedTCPConnectorTest::Timeout)); OLA_ASSERT_TRUE(m_timeout_id); }
/* * Check that RemoveWriteDescriptor is reentrant. * We use the Execute() method to close a write descriptor during the same * cycle in which it becomes writeable. See * https://github.com/OpenLightingProject/ola/pull/429 for details. */ void SelectServerTest::testRemoveWriteWhenOtherReadable() { Descriptors read_set, write_set, delete_set; LoopbackDescriptor *loopback = new LoopbackDescriptor(); loopback->Init(); loopback->SetOnWritable(NewCallback(this, &SelectServerTest::NullHandler)); write_set.insert(loopback); delete_set.insert(loopback); OLA_ASSERT_TRUE(m_ss->AddWriteDescriptor(loopback)); OLA_ASSERT_EQ(1, write_descriptor_count->Get()); OLA_ASSERT_EQ(0, read_descriptor_count->Get()); m_ss->Execute(NewSingleCallback( this, &SelectServerTest::RemoveAndDeleteDescriptors, read_set, write_set, delete_set)); m_ss->Run(); OLA_ASSERT_EQ(0, write_descriptor_count->Get()); OLA_ASSERT_EQ(1, connected_read_descriptor_count->Get()); OLA_ASSERT_EQ(0, read_descriptor_count->Get()); }
/* * Setup the select server */ void SocketTest::setUp() { m_ss = new SelectServer(); m_timeout_closure = ola::NewSingleCallback(this, &SocketTest::Timeout); OLA_ASSERT_TRUE(m_ss->RegisterSingleTimeout(ABORT_TIMEOUT_IN_MS, m_timeout_closure)); #if _WIN32 WSADATA wsa_data; int result = WSAStartup(MAKEWORD(2, 0), &wsa_data); OLA_ASSERT_EQ(result, 0); #endif // _WIN32 }
/* * Confirm we can't add the same descriptor twice. */ void SelectServerTest::testDoubleAddAndRemove() { OLA_ASSERT_EQ(1, connected_read_descriptor_count->Get()); // internal socket OLA_ASSERT_EQ(0, read_descriptor_count->Get()); OLA_ASSERT_EQ(0, write_descriptor_count->Get()); LoopbackDescriptor loopback_socket; loopback_socket.Init(); OLA_ASSERT_TRUE(m_ss->AddReadDescriptor(&loopback_socket)); OLA_ASSERT_EQ(2, connected_read_descriptor_count->Get()); OLA_ASSERT_EQ(0, read_descriptor_count->Get()); OLA_ASSERT_EQ(0, write_descriptor_count->Get()); OLA_ASSERT_TRUE(m_ss->AddWriteDescriptor(&loopback_socket)); OLA_ASSERT_EQ(2, connected_read_descriptor_count->Get()); OLA_ASSERT_EQ(0, read_descriptor_count->Get()); OLA_ASSERT_EQ(1, write_descriptor_count->Get()); m_ss->RemoveReadDescriptor(&loopback_socket); OLA_ASSERT_EQ(1, connected_read_descriptor_count->Get()); OLA_ASSERT_EQ(0, read_descriptor_count->Get()); OLA_ASSERT_EQ(1, write_descriptor_count->Get()); m_ss->RemoveWriteDescriptor(&loopback_socket); OLA_ASSERT_EQ(1, connected_read_descriptor_count->Get()); OLA_ASSERT_EQ(0, read_descriptor_count->Get()); OLA_ASSERT_EQ(0, write_descriptor_count->Get()); // Trying to remove a second time shouldn't crash m_ss->RemoveReadDescriptor(&loopback_socket); m_ss->RemoveWriteDescriptor(&loopback_socket); }
/* * Receive some data and check it. */ void SocketTest::UDPReceiveAndTerminate(UDPSocket *socket) { IPV4Address expected_address; OLA_ASSERT_TRUE(IPV4Address::FromString("127.0.0.1", &expected_address)); IPV4SocketAddress source; uint8_t buffer[sizeof(test_cstring) + 10]; ssize_t data_read = sizeof(buffer); socket->RecvFrom(buffer, &data_read, &source); OLA_ASSERT_EQ(static_cast<ssize_t>(sizeof(test_cstring)), data_read); OLA_ASSERT_EQ(expected_address, source.Host()); m_ss->Terminate(); }
/* * Confirm we correctly detect the remote end closing the connection. */ void SelectServerTest::testRemoteEndClose() { Descriptors read_set, write_set, delete_set; LoopbackDescriptor loopback; loopback.Init(); read_set.insert(&loopback); loopback.SetOnClose(NewSingleCallback( this, &SelectServerTest::RemoveAndDeleteDescriptors, read_set, write_set, delete_set)); OLA_ASSERT_TRUE(m_ss->AddReadDescriptor(&loopback)); OLA_ASSERT_EQ(2, connected_read_descriptor_count->Get()); OLA_ASSERT_EQ(0, read_descriptor_count->Get()); // now the Write end closes loopback.CloseClient(); m_ss->Run(); OLA_ASSERT_EQ(1, connected_read_descriptor_count->Get()); OLA_ASSERT_EQ(0, read_descriptor_count->Get()); }
/* * Check the delete_on_close feature handles the case where the descriptor * being closed is removed from the on_close handler. */ void SelectServerTest::testRemoteEndCloseWithRemoveAndDelete() { Descriptors read_set, write_set, delete_set; LoopbackDescriptor *loopback = new LoopbackDescriptor(); loopback->Init(); read_set.insert(loopback); loopback->SetOnClose(NewSingleCallback( this, &SelectServerTest::RemoveAndDeleteDescriptors, read_set, write_set, delete_set)); // Ownership is transferred. OLA_ASSERT_TRUE(m_ss->AddReadDescriptor(loopback, true)); OLA_ASSERT_EQ(2, connected_read_descriptor_count->Get()); OLA_ASSERT_EQ(0, read_descriptor_count->Get()); // Close the write end of the descriptor. loopback->CloseClient(); m_ss->Run(); OLA_ASSERT_EQ(1, connected_read_descriptor_count->Get()); OLA_ASSERT_EQ(0, read_descriptor_count->Get()); }
void SocketClosed(TCPSocket *socket) { OLA_INFO << "Socket @ " << socket << " was closed"; vector<TCPSocket*>::iterator iter = m_sockets.begin(); for (; iter != m_sockets.end(); ++iter) { if (*iter == socket) { m_ss.RemoveReadDescriptor(socket); socket->Close(); delete socket; m_sockets.erase(iter); break; } } }
/* * Accept a new connection and send some test data */ void SocketTest::NewConnectionSend(TCPSocket *new_socket) { OLA_ASSERT_TRUE(new_socket); GenericSocketAddress address = new_socket->GetPeerAddress(); OLA_ASSERT_TRUE(address.Family() == AF_INET); OLA_INFO << "Connection from " << address; ssize_t bytes_sent = new_socket->Send( static_cast<const uint8_t*>(test_cstring), sizeof(test_cstring)); OLA_ASSERT_EQ(static_cast<ssize_t>(sizeof(test_cstring)), bytes_sent); new_socket->SetOnClose(ola::NewSingleCallback(this, &SocketTest::TerminateOnClose)); m_ss->AddReadDescriptor(new_socket, true); }
/* * Main */ int main(int argc, char *argv[]) { ola::InitLogging(ola::OLA_LOG_INFO, ola::OLA_LOG_STDERR); udp_socket.SetOnData(ola::NewCallback(&SocketReady)); if (!udp_socket.Init()) { OLA_WARN << "Failed to init"; return 1; } if (!udp_socket.Bind(6038)) { OLA_WARN << "Failed to bind"; return 1; } if (!udp_socket.EnableBroadcast()) { OLA_WARN << "Failed to enabl bcast"; return 1; } ss.AddSocket(&udp_socket); ss.Run(); return 0; }
/* * Test that a TCP Connect works. */ void AdvancedTCPConnectorTest::testConnect() { ola::network::TCPSocketFactory socket_factory( ola::NewCallback(this, &AdvancedTCPConnectorTest::AcceptedConnection)); TcpAcceptingSocket listening_socket(&socket_factory); SetupListeningSocket(&listening_socket); AdvancedTCPConnector connector( m_ss, m_tcp_socket_factory.get(), TimeInterval(0, CONNECT_TIMEOUT_IN_MS * 1000)); // 5 per attempt, up to a max of 30 LinearBackoffPolicy policy(TimeInterval(5, 0), TimeInterval(30, 0)); connector.AddEndpoint(m_localhost, SERVER_PORT, &policy); CPPUNIT_ASSERT_EQUAL(1u, connector.EndpointCount()); m_ss->Run(); CPPUNIT_ASSERT_EQUAL(1u, connector.EndpointCount()); // confirm the status is correct ConfirmState(__LINE__, connector, m_localhost, SERVER_PORT, AdvancedTCPConnector::CONNECTED, 0); // check our socket exists CPPUNIT_ASSERT(m_connected_socket); m_connected_socket->Close(); delete m_connected_socket; OLA_INFO << "disconnecting"; connector.Disconnect(m_localhost, SERVER_PORT, true); // state should be updated ConfirmState(__LINE__, connector, m_localhost, SERVER_PORT, AdvancedTCPConnector::PAUSED, 0); // remove & shutdown connector.RemoveEndpoint(m_localhost, SERVER_PORT); CPPUNIT_ASSERT_EQUAL(0u, connector.EndpointCount()); m_ss->RemoveReadDescriptor(&listening_socket); }
/** * Setup a TCP socket that accepts connections */ void AdvancedTCPConnectorTest::SetupListeningSocket( TCPAcceptingSocket *listening_socket) { IPV4SocketAddress listen_address(m_localhost, 0); OLA_ASSERT_TRUE_MSG(listening_socket->Listen(listen_address), "Failed to listen"); // calling listen a second time should fail OLA_ASSERT_FALSE(listening_socket->Listen(listen_address)); GenericSocketAddress addr = listening_socket->GetLocalAddress(); OLA_ASSERT_TRUE(addr.IsValid()); m_server_address = addr.V4Addr(); OLA_INFO << "listening on " << m_server_address; OLA_ASSERT_TRUE(m_ss->AddReadDescriptor(listening_socket)); }
/* * Setup the select server */ void AdvancedTCPConnectorTest::setUp() { m_tcp_socket_factory.reset(new ola::network::TCPSocketFactory( ola::NewCallback(this, &AdvancedTCPConnectorTest::OnConnect))); m_connected_socket = NULL; ola::InitLogging(ola::OLA_LOG_INFO, ola::OLA_LOG_STDERR); string localhost_str = "127.0.0.1"; CPPUNIT_ASSERT(IPV4Address::FromString(localhost_str, &m_localhost)); m_ss = new SelectServer(NULL, &m_clock); m_timeout_id = m_ss->RegisterSingleTimeout( ABORT_TIMEOUT_IN_MS, ola::NewSingleCallback(this, &AdvancedTCPConnectorTest::Timeout)); CPPUNIT_ASSERT(m_timeout_id); }
/* * Check AddReadDescriptor/RemoveReadDescriptor works correctly and that the * export map is updated. */ void SelectServerTest::testAddRemoveReadDescriptor() { LoopbackDescriptor bad_socket; IntegerVariable *connected_socket_count = m_map->GetIntegerVar(PollerInterface::K_CONNECTED_DESCRIPTORS_VAR); IntegerVariable *socket_count = m_map->GetIntegerVar(PollerInterface::K_READ_DESCRIPTOR_VAR); OLA_ASSERT_EQ(1, connected_socket_count->Get()); // internal socket OLA_ASSERT_EQ(0, socket_count->Get()); // adding and removin a non-connected socket should fail OLA_ASSERT_FALSE(m_ss->AddReadDescriptor(&bad_socket)); OLA_ASSERT_FALSE(m_ss->RemoveReadDescriptor(&bad_socket)); LoopbackDescriptor loopback_socket; loopback_socket.Init(); OLA_ASSERT_EQ(1, connected_socket_count->Get()); OLA_ASSERT_EQ(0, socket_count->Get()); OLA_ASSERT_TRUE(m_ss->AddReadDescriptor(&loopback_socket)); // Adding a second time should fail OLA_ASSERT_FALSE(m_ss->AddReadDescriptor(&loopback_socket)); OLA_ASSERT_EQ(2, connected_socket_count->Get()); OLA_ASSERT_EQ(0, socket_count->Get()); // Add a udp socket UDPSocket udp_socket; OLA_ASSERT_TRUE(udp_socket.Init()); OLA_ASSERT_TRUE(m_ss->AddReadDescriptor(&udp_socket)); OLA_ASSERT_FALSE(m_ss->AddReadDescriptor(&udp_socket)); OLA_ASSERT_EQ(2, connected_socket_count->Get()); OLA_ASSERT_EQ(1, socket_count->Get()); // Check remove works OLA_ASSERT_TRUE(m_ss->RemoveReadDescriptor(&loopback_socket)); OLA_ASSERT_EQ(1, connected_socket_count->Get()); OLA_ASSERT_EQ(1, socket_count->Get()); OLA_ASSERT_TRUE(m_ss->RemoveReadDescriptor(&udp_socket)); OLA_ASSERT_EQ(1, connected_socket_count->Get()); OLA_ASSERT_EQ(0, socket_count->Get()); // Remove again should fail OLA_ASSERT_FALSE(m_ss->RemoveReadDescriptor(&loopback_socket)); }
/* * Test that we can destroy the Connector and everything will work. */ void AdvancedTCPConnectorTest::testEarlyDestruction() { // 5 per attempt, up to a max of 30 LinearBackoffPolicy policy(TimeInterval(5, 0), TimeInterval(30, 0)); { AdvancedTCPConnector connector( m_ss, m_tcp_socket_factory.get(), TimeInterval(0, CONNECT_TIMEOUT_IN_MS * 1000)); connector.AddEndpoint(m_localhost, SERVER_PORT, &policy); CPPUNIT_ASSERT_EQUAL(1u, connector.EndpointCount()); } m_ss->RunOnce(); }
/* * Setup the select server */ void AdvancedTCPConnectorTest::setUp() { m_tcp_socket_factory.reset(new ola::network::TCPSocketFactory( ola::NewCallback(this, &AdvancedTCPConnectorTest::OnConnect))); m_connected_socket = NULL; m_ss = new SelectServer(NULL, &m_clock); m_timeout_id = m_ss->RegisterSingleTimeout( ABORT_TIMEOUT_IN_MS, ola::NewSingleCallback(this, &AdvancedTCPConnectorTest::Timeout)); OLA_ASSERT_TRUE(m_timeout_id); #if _WIN32 WSADATA wsa_data; int result = WSAStartup(MAKEWORD(2, 0), &wsa_data); OLA_ASSERT_EQ(result, 0); #endif }
/* * Test a non-blocking TCP connect fails. */ void TCPConnectorTest::testNonBlockingConnectFailure() { uint16_t port = ReservePort(); OLA_ASSERT_NE(0, port); IPV4SocketAddress target(m_localhost, port); // attempt a non-blocking connect, hopefully nothing is running on port 9010 TCPConnector connector(m_ss); TimeInterval connect_timeout(0, CONNECT_TIMEOUT_IN_MS * 1000); TCPConnector::TCPConnectionID id = connector.Connect( target, connect_timeout, ola::NewSingleCallback(this, &TCPConnectorTest::OnConnectFailure)); OLA_ASSERT_TRUE(id); m_ss->Run(); OLA_ASSERT_EQ(0u, connector.ConnectionsPending()); }
/* * Test that we can destroy the Connector and everything will work. */ void AdvancedTCPConnectorTest::testEarlyDestruction() { uint16_t port = ReservePort(); OLA_ASSERT_NE(0, port); IPV4SocketAddress target(m_localhost, port); // 5 per attempt, up to a max of 30 LinearBackoffPolicy policy(TimeInterval(5, 0), TimeInterval(30, 0)); { AdvancedTCPConnector connector( m_ss, m_tcp_socket_factory.get(), TimeInterval(0, CONNECT_TIMEOUT_IN_MS * 1000)); connector.AddEndpoint(target, &policy); OLA_ASSERT_EQ(1u, connector.EndpointCount()); } m_ss->RunOnce(); }
/** * Called by the receive thread when new data arrives * @param device the device id which produced the data * @param data pointer to the data, ownership is transferred, use * DeleteU8ArrayPtr to free. * @param data_length the size of the data */ void LogicReader::DataReceived(U64 device, U8 *data, uint32_t data_length) { { MutexLocker lock(&m_mu); if (device != m_device_id) { DevicesManagerInterface::DeleteU8ArrayPtr(data); return; } } m_ss->Execute( NewSingleCallback(this, &LogicReader::ProcessData, data, data_length)); { MutexLocker lock(&m_data_mu); while (!m_free_data.empty()) { U8 *data = m_free_data.front(); DevicesManagerInterface::DeleteU8ArrayPtr(data); m_free_data.pop(); } } }
/* * Test the interaction between read and write descriptor. */ void SelectServerTest::testReadWriteInteraction() { UnixSocket socket; socket.Init(); socket.SetOnClose(NewSingleCallback(this, &SelectServerTest::Terminate)); OLA_ASSERT_TRUE(m_ss->AddReadDescriptor(&socket)); OLA_ASSERT_TRUE(m_ss->AddWriteDescriptor(&socket)); m_ss->RemoveWriteDescriptor(&socket); // now the Write end closes auto_ptr<UnixSocket> other_end(socket.OppositeEnd()); other_end->CloseClient(); m_ss->RegisterSingleTimeout( 100, ola::NewSingleCallback(this, &SelectServerTest::FatalTimeout)); m_ss->Run(); m_ss->RemoveReadDescriptor(&socket); OLA_ASSERT_EQ(1, connected_read_descriptor_count->Get()); OLA_ASSERT_EQ(0, read_descriptor_count->Get()); }
/* * Check AddReadDescriptor/RemoveReadDescriptor works correctly and that the * export map is updated. */ void SelectServerTest::testAddRemoveReadDescriptor() { OLA_ASSERT_EQ(1, connected_read_descriptor_count->Get()); OLA_ASSERT_EQ(0, read_descriptor_count->Get()); OLA_ASSERT_EQ(0, write_descriptor_count->Get()); LoopbackDescriptor bad_socket; // adding and removing a non-connected socket should fail OLA_ASSERT_FALSE(m_ss->AddReadDescriptor(&bad_socket)); m_ss->RemoveReadDescriptor(&bad_socket); LoopbackDescriptor loopback_socket; loopback_socket.Init(); OLA_ASSERT_TRUE(m_ss->AddReadDescriptor(&loopback_socket)); OLA_ASSERT_EQ(2, connected_read_descriptor_count->Get()); OLA_ASSERT_EQ(0, read_descriptor_count->Get()); OLA_ASSERT_EQ(0, write_descriptor_count->Get()); // Add a udp socket UDPSocket udp_socket; OLA_ASSERT_TRUE(udp_socket.Init()); OLA_ASSERT_TRUE(m_ss->AddReadDescriptor(&udp_socket)); OLA_ASSERT_EQ(2, connected_read_descriptor_count->Get()); OLA_ASSERT_EQ(1, read_descriptor_count->Get()); OLA_ASSERT_EQ(0, write_descriptor_count->Get()); // Check remove works m_ss->RemoveReadDescriptor(&loopback_socket); OLA_ASSERT_EQ(1, connected_read_descriptor_count->Get()); OLA_ASSERT_EQ(1, read_descriptor_count->Get()); OLA_ASSERT_EQ(0, write_descriptor_count->Get()); m_ss->RemoveReadDescriptor(&udp_socket); OLA_ASSERT_EQ(1, connected_read_descriptor_count->Get()); OLA_ASSERT_EQ(0, read_descriptor_count->Get()); OLA_ASSERT_EQ(0, write_descriptor_count->Get()); }
/** * Called when a connection completes or times out. */ void TCPConnectorTest::OnConnectFailure(int fd, int error) { // The error could be one of many things, right now we just check it's non-0 OLA_ASSERT_NE(0, error); OLA_ASSERT_EQ(-1, fd); m_ss->Terminate(); }
/* * Timeout tests */ void SelectServerTest::testTimeout() { // Check a single timeout m_ss->RegisterSingleTimeout( 10, ola::NewSingleCallback(this, &SelectServerTest::SingleIncrementTimeout)); m_ss->RegisterSingleTimeout( 20, ola::NewSingleCallback(this, &SelectServerTest::Terminate)); m_ss->Run(); OLA_ASSERT_EQ(1u, m_timeout_counter); // Now check a timeout that adds another timeout m_timeout_counter = 0; m_ss->RegisterSingleTimeout( 10, ola::NewSingleCallback(this, &SelectServerTest::ReentrantTimeout, m_ss)); m_ss->RegisterSingleTimeout( 20, ola::NewSingleCallback(this, &SelectServerTest::Terminate)); m_ss->Run(); OLA_ASSERT_EQ(2u, m_timeout_counter); // Check repeating timeouts // Some systems (VMs in particular) can't do 10ms resolution so we go for // larger numbers here. m_timeout_counter = 0; m_ss->RegisterRepeatingTimeout( 100, ola::NewCallback(this, &SelectServerTest::IncrementTimeout)); m_ss->RegisterSingleTimeout( 980, ola::NewSingleCallback(this, &SelectServerTest::Terminate)); m_ss->Run(); // This seems to go as low as 7 std::ostringstream str; str << "Timeout counter was " << m_timeout_counter; OLA_ASSERT_TRUE_MSG(m_timeout_counter >= 5 && m_timeout_counter <= 9, str.str()); // Confirm timeouts are removed correctly ola::thread::timeout_id timeout1 = m_ss->RegisterSingleTimeout( 10, ola::NewSingleCallback(this, &SelectServerTest::FatalTimeout)); m_ss->RegisterSingleTimeout( 20, ola::NewSingleCallback(this, &SelectServerTest::Terminate)); m_ss->RemoveTimeout(timeout1); m_ss->Run(); }
void RpcChannelTest::FailedEchoComplete() { m_ss.Terminate(); OLA_ASSERT_TRUE(m_controller.Failed()); }
/* * Check stream requests work */ void RpcChannelTest::testStreamRequest() { m_request.set_data("foo"); m_stub->Stream(NULL, &m_request, NULL, NULL); m_ss.Run(); }
/* * Receive some data and terminate */ void SocketTest::ReceiveAndTerminate(ConnectedDescriptor *socket) { Receive(socket); m_ss->Terminate(); }
/* * Receive some data, send the same data and close */ void SocketTest::ReceiveSendAndClose(ConnectedDescriptor *socket) { ReceiveAndSend(socket); m_ss->RemoveReadDescriptor(socket); socket->Close(); }