/** * Generic method to test server initiated close */ void SocketTest::SocketServerClose(ConnectedDescriptor *socket, ConnectedDescriptor *socket2) { OLA_ASSERT_NOT_NULL(socket); socket->SetOnData(ola::NewCallback( this, &SocketTest::Receive, static_cast<ConnectedDescriptor*>(socket))); socket->SetOnClose( ola::NewSingleCallback(this, &SocketTest::TerminateOnClose)); OLA_ASSERT_TRUE(m_ss->AddReadDescriptor(socket)); OLA_ASSERT_TRUE(socket2); socket2->SetOnData(ola::NewCallback( this, &SocketTest::ReceiveSendAndClose, static_cast<ConnectedDescriptor*>(socket2))); OLA_ASSERT_TRUE(m_ss->AddReadDescriptor(socket2)); ssize_t bytes_sent = socket->Send( static_cast<const uint8_t*>(test_cstring), sizeof(test_cstring)); OLA_ASSERT_EQ(static_cast<ssize_t>(sizeof(test_cstring)), bytes_sent); m_ss->Run(); m_ss->RemoveReadDescriptor(socket); m_ss->RemoveReadDescriptor(socket2); delete socket2; }
/* * Test UDP sockets with an IOQueue work correctly. * The client connects and the server sends some data. The client checks the * data matches and then closes the connection. */ void SocketTest::testIOQueueUDPSend() { IPV4SocketAddress socket_address(IPV4Address::Loopback(), 9010); UDPSocket socket; OLA_ASSERT_TRUE(socket.Init()); OLA_ASSERT_FALSE(socket.Init()); OLA_ASSERT_TRUE(socket.Bind(socket_address)); OLA_ASSERT_FALSE(socket.Bind(socket_address)); socket.SetOnData( ola::NewCallback(this, &SocketTest::UDPReceiveAndSend, &socket)); OLA_ASSERT_TRUE(m_ss->AddReadDescriptor(&socket)); UDPSocket client_socket; OLA_ASSERT_TRUE(client_socket.Init()); OLA_ASSERT_FALSE(client_socket.Init()); client_socket.SetOnData( ola::NewCallback( this, &SocketTest::UDPReceiveAndTerminate, static_cast<UDPSocket*>(&client_socket))); OLA_ASSERT_TRUE(m_ss->AddReadDescriptor(&client_socket)); IOQueue output; output.Write(static_cast<const uint8_t*>(test_cstring), sizeof(test_cstring)); ssize_t bytes_sent = client_socket.SendTo(&output, socket_address); OLA_ASSERT_EQ(static_cast<ssize_t>(sizeof(test_cstring)), bytes_sent); m_ss->Run(); m_ss->RemoveReadDescriptor(&socket); m_ss->RemoveReadDescriptor(&client_socket); }
/* * 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); }
/* * Test TCP sockets work correctly. * The client connects and the server then sends some data and closes the * connection. */ void SocketTest::testTCPSocketServerClose() { IPV4SocketAddress socket_address(IPV4Address::Loopback(), 0); ola::network::TCPSocketFactory socket_factory( ola::NewCallback(this, &SocketTest::NewConnectionSendAndClose)); TCPAcceptingSocket socket(&socket_factory); OLA_ASSERT_TRUE_MSG(socket.Listen(socket_address), "Check for another instance of olad running"); OLA_ASSERT_FALSE(socket.Listen(socket_address)); GenericSocketAddress local_address = socket.GetLocalAddress(); OLA_ASSERT_EQ(static_cast<uint16_t>(AF_INET), local_address.Family()); OLA_ASSERT_TRUE(m_ss->AddReadDescriptor(&socket)); // The client socket checks the response and terminates on close TCPSocket *client_socket = TCPSocket::Connect(local_address); OLA_ASSERT_NOT_NULL(client_socket); client_socket->SetOnData(ola::NewCallback( this, &SocketTest::Receive, static_cast<ConnectedDescriptor*>(client_socket))); client_socket->SetOnClose( ola::NewSingleCallback(this, &SocketTest::TerminateOnClose)); OLA_ASSERT_TRUE(m_ss->AddReadDescriptor(client_socket)); m_ss->Run(); m_ss->RemoveReadDescriptor(&socket); m_ss->RemoveReadDescriptor(client_socket); delete client_socket; }
/* * Test UDP sockets work correctly. * The client connects and the server sends some data. The client checks the * data matches and then closes the connection. */ void SocketTest::testUDPSocket() { IPV4SocketAddress socket_address(IPV4Address::Loopback(), 0); UDPSocket socket; OLA_ASSERT_TRUE(socket.Init()); OLA_ASSERT_FALSE(socket.Init()); OLA_ASSERT_TRUE(socket.Bind(socket_address)); OLA_ASSERT_FALSE(socket.Bind(socket_address)); IPV4SocketAddress local_address; OLA_ASSERT_TRUE(socket.GetSocketAddress(&local_address)); OLA_ASSERT_EQ(static_cast<uint16_t>(AF_INET), local_address.Family()); socket.SetOnData( ola::NewCallback(this, &SocketTest::UDPReceiveAndSend, &socket)); OLA_ASSERT_TRUE(m_ss->AddReadDescriptor(&socket)); UDPSocket client_socket; OLA_ASSERT_TRUE(client_socket.Init()); OLA_ASSERT_FALSE(client_socket.Init()); client_socket.SetOnData( ola::NewCallback( this, &SocketTest::UDPReceiveAndTerminate, static_cast<UDPSocket*>(&client_socket))); OLA_ASSERT_TRUE(m_ss->AddReadDescriptor(&client_socket)); ssize_t bytes_sent = client_socket.SendTo( static_cast<const uint8_t*>(test_cstring), sizeof(test_cstring), local_address); OLA_ASSERT_EQ(static_cast<ssize_t>(sizeof(test_cstring)), bytes_sent); m_ss->Run(); m_ss->RemoveReadDescriptor(&socket); m_ss->RemoveReadDescriptor(&client_socket); }
/* * 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 loopback; loopback.Init(); OLA_ASSERT_TRUE(m_ss->AddReadDescriptor(&loopback)); 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); 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()); }
/* * Test non-blocking TCP connects work correctly. */ void TCPConnectorTest::testNonBlockingConnect() { ola::network::TCPSocketFactory socket_factory( ola::NewCallback(this, &TCPConnectorTest::AcceptedConnection)); TCPAcceptingSocket listening_socket(&socket_factory); IPV4SocketAddress listen_address(m_localhost, 0); OLA_ASSERT_TRUE_MSG(listening_socket.Listen(listen_address), "Failed to listen"); GenericSocketAddress addr = listening_socket.GetLocalAddress(); OLA_ASSERT_TRUE(addr.IsValid()); // calling listen a second time should fail OLA_ASSERT_FALSE(listening_socket.Listen(listen_address)); OLA_ASSERT_TRUE(m_ss->AddReadDescriptor(&listening_socket)); // now attempt a non-blocking connect // because we're connecting to the localhost this may run this callback // immediately. TCPConnector connector(m_ss); TimeInterval connect_timeout(0, CONNECT_TIMEOUT_IN_MS * 1000); TCPConnector::TCPConnectionID id = connector.Connect( addr.V4Addr(), connect_timeout, ola::NewSingleCallback(this, &TCPConnectorTest::OnConnect)); OLA_ASSERT_TRUE(id); m_ss->Run(); OLA_ASSERT_EQ(0u, connector.ConnectionsPending()); m_ss->RemoveReadDescriptor(&listening_socket); }
void RpcChannelTest::tearDown() { m_ss.RemoveReadDescriptor(m_socket); delete m_socket; delete m_stub; delete m_channel; delete m_service; }
/* * 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)); }
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; } } }
/** * Test that pausing a connection works. */ void AdvancedTCPConnectorTest::testPause() { 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)); // add endpoint, but make sure it's paused connector.AddEndpoint(m_server_address, &policy, true); OLA_ASSERT_EQ(1u, connector.EndpointCount()); ConfirmState(__LINE__, connector, m_server_address, AdvancedTCPConnector::PAUSED, 0); m_ss->RunOnce(TimeInterval(0, 500000)); // now unpause connector.Resume(m_server_address); // The socket may be connected immediately depending on the platform. AdvancedTCPConnector::ConnectionState state; unsigned int failed_attempts; connector.GetEndpointState(m_server_address, &state, &failed_attempts); if (state == AdvancedTCPConnector::DISCONNECTED) { m_ss->Run(); } OLA_ASSERT_EQ(1u, connector.EndpointCount()); ConfirmState(__LINE__, connector, m_server_address, AdvancedTCPConnector::CONNECTED, 0); // check our socket exists OLA_ASSERT_TRUE(m_connected_socket); m_connected_socket->Close(); delete m_connected_socket; connector.Disconnect(m_server_address, true); // state should be updated ConfirmState(__LINE__, connector, m_server_address, AdvancedTCPConnector::PAUSED, 0); // clean up connector.RemoveEndpoint(m_server_address); OLA_ASSERT_EQ(0u, connector.EndpointCount()); m_ss->RemoveReadDescriptor(&listening_socket); }
/** * Test that pausing a connection works. */ void AdvancedTCPConnectorTest::testPause() { 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)); // add endpoint, but make sure it's paused connector.AddEndpoint(m_localhost, SERVER_PORT, &policy, true); CPPUNIT_ASSERT_EQUAL(1u, connector.EndpointCount()); ConfirmState(__LINE__, connector, m_localhost, SERVER_PORT, AdvancedTCPConnector::PAUSED, 0); m_ss->RunOnce(0, 500000); // now unpause connector.Resume(m_localhost, SERVER_PORT); ConfirmState(__LINE__, connector, m_localhost, SERVER_PORT, AdvancedTCPConnector::DISCONNECTED, 0); m_ss->Run(); CPPUNIT_ASSERT_EQUAL(1u, connector.EndpointCount()); 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); // clean up connector.RemoveEndpoint(m_localhost, SERVER_PORT); CPPUNIT_ASSERT_EQUAL(0u, connector.EndpointCount()); m_ss->RemoveReadDescriptor(&listening_socket); }
/* * 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()); }
/* * Confirm we can't add invalid descriptors to the SelectServer */ void SelectServerTest::testAddInvalidDescriptor() { 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()); // Adding and removing a uninitialized socket should fail LoopbackDescriptor bad_socket; OLA_ASSERT_FALSE(m_ss->AddReadDescriptor(&bad_socket)); OLA_ASSERT_FALSE(m_ss->AddWriteDescriptor(&bad_socket)); m_ss->RemoveReadDescriptor(&bad_socket); m_ss->RemoveWriteDescriptor(&bad_socket); 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()); }
/* * 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()); }
/* * 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_server_address, &policy); OLA_ASSERT_EQ(1u, connector.EndpointCount()); m_ss->Run(); OLA_ASSERT_EQ(1u, connector.EndpointCount()); // confirm the status is correct ConfirmState(__LINE__, connector, m_server_address, AdvancedTCPConnector::CONNECTED, 0); // check our socket exists OLA_ASSERT_TRUE(m_connected_socket); m_connected_socket->Close(); delete m_connected_socket; OLA_INFO << "disconnecting"; connector.Disconnect(m_server_address, true); // state should be updated ConfirmState(__LINE__, connector, m_server_address, AdvancedTCPConnector::PAUSED, 0); // remove & shutdown connector.RemoveEndpoint(m_server_address); OLA_ASSERT_EQ(0u, connector.EndpointCount()); m_ss->RemoveReadDescriptor(&listening_socket); }
/* * Receive some data, send the same data and close */ void SocketTest::ReceiveSendAndClose(ConnectedDescriptor *socket) { ReceiveAndSend(socket); m_ss->RemoveReadDescriptor(socket); socket->Close(); }