void DataRequirementsTest::test_hash() { // Use Case: // Ensure hash returns a non-zero value. { DataRequirements d; d.addRequired(QString("hello")); CPPUNIT_ASSERT(d.hash() != 0); } // Use Case: // Ensure different DataRequirement objects return different hash values. { DataRequirements d1; d1.addRequired(QString("one")); DataRequirements d2; d2.addRequired(QString("two")); CPPUNIT_ASSERT(d1.hash() != d2.hash()); } // Use Case: // Ensure different ordering returns the same hash. { DataRequirements d1; d1.addRequired("one"); d1.addRequired("two"); DataRequirements d2; d2.addRequired("two"); d2.addRequired("one"); CPPUNIT_ASSERT(d1.hash() == d2.hash()); } }
/** * @details * Tests two chunkers, starting them multiple times (test for random segfaults * and threading problems). */ void DirectStreamDataClientTest::test_twoChunkersMultipleStarts() { for (int i = 0; i < 100; ++i) { //std::cout << "---------------------------------- " << i << std::endl; try { // Start two telescope emulators. EmulatorDriver emulator1(new RealUdpEmulator(*_emulatorConfig1)); EmulatorDriver emulator2(new RealUdpEmulator(*_emulatorConfig2)); // Create the adapter factory. AbstractAdapterFactory adapterFactory(_config, "pipeline", "adapters"); // Create the data client factory. DataClientFactory clientFactory(_config, "pipeline", "clients", &adapterFactory); // Create the data blob factory. FactoryGeneric<DataBlob> blobFactory(true); // Create a list of data requirements. QString dataType = "DoubleData"; DataRequirements req; QList<DataRequirements> requirements; req.addStreamData(dataType); requirements.append(req); // Create the client. DirectStreamDataClient* client = static_cast<DirectStreamDataClient*>( clientFactory.create("DirectStreamDataClient", requirements)); CPPUNIT_ASSERT(DataClientFactory::whatIs(client) == "DirectStreamDataClient"); client->addStreamChunker("TestUdpChunker", "a"); client->addStreamChunker("TestUdpChunker", "b"); // Set up the data hash. QHash<QString, DataBlob*> dataHash; dataHash.insert(dataType, blobFactory.create(dataType)); for (int j = 0; j < 2; j++) { // Get the data. QHash<QString, DataBlob*> validData = client->getData(dataHash); // Check the content of the data blob. DoubleData* data = (DoubleData*)validData.value("DoubleData"); _printData(data); } } catch (QString e) { CPPUNIT_FAIL("Unexpected exception: " + e.toStdString()); } } }
/** * @details */ void PelicanTCPBlobServerTest::test_connection() { // Use Case: // ?????? TODO // Expect: TODO // // Create and configure TCP server QString xml = "<PelicanTCPBlobServer>" " <connection port=\"0\"/>" // 0 = find unused system port "</PelicanTCPBlobServer>"; ConfigNode config(xml); PelicanTCPBlobServer server(config); sleep(1); // Create a client and connect it to the server QTcpSocket tcpSocket; tcpSocket.connectToHost( QHostAddress::LocalHost, server.serverPort() ); if (!tcpSocket.waitForConnected(5000) || tcpSocket.state() == QAbstractSocket::UnconnectedState) CPPUNIT_FAIL("Client could not connect to server"); // Define the data type which the client will except and send request StreamDataRequest req; DataRequirements require; require.setStreamData("testData"); req.addDataOption(require); PelicanClientProtocol clientProtocol; QByteArray data = clientProtocol.serialise(req); tcpSocket.write(data); tcpSocket.waitForBytesWritten(data.size()); tcpSocket.flush(); /// ensure we are registered before continuing while( server.clientsForStream("testData") == 0 ) { sleep(1); } { // Test Server send TestDataBlob blob; blob.setData("Testing TCPServer"); server.send("testData", &blob); // Evaluate the response from the server tcpSocket.waitForReadyRead(); boost::shared_ptr<ServerResponse> r = clientProtocol.receive(tcpSocket); CPPUNIT_ASSERT( r->type() == ServerResponse::Blob ); TestDataBlob blobResult; blobResult.deserialise(tcpSocket, ((DataBlobResponse*)r.get())->byteOrder()); CPPUNIT_ASSERT(blobResult == blob); } { // Test Server send TestDataBlob blob; blob.setData("Testing TCPServer again"); server.send("testData", &blob); // Evaluate the response from the server tcpSocket.waitForReadyRead(); boost::shared_ptr<ServerResponse> r = clientProtocol.receive(tcpSocket); CPPUNIT_ASSERT( r->type() == ServerResponse::Blob ); TestDataBlob blobResult; blobResult.deserialise(tcpSocket, ((DataBlobResponse*)r.get())->byteOrder()); CPPUNIT_ASSERT(blobResult == blob); } }
void PelicanServerClientTestMT::test_getData() { try{ // set up the test server TestServiceAdapter serviceAdapter; TestStreamAdapter streamAdapter; TestServer server; QString stream1("stream1"); QString service1("service1"); QString version1("version1"); QString version2("version2"); DataRequirements reqStream1; reqStream1.addStreamData(stream1); QByteArray data1("pelican/data1"); QByteArray data2("pelican/data2"); unsigned int port = server.port(); // common client configuration Config config; config.setFromString( "", "<testconfig>" " <server host=\"127.0.0.1\"/>" "</testconfig>" ); Config::TreeAddress address; address << Config::NodeId("server", ""); address << Config::NodeId("testconfig", ""); ConfigNode configNode = config.get(address); { // Use Case: // request for Service Data only // Expect : // throw DataChunk sd(service1, version1, data1 ); CPPUNIT_ASSERT_EQUAL( (long)data1.size(), (long)sd.size() ); // setup the test DataRequirements req; req.addServiceData(service1); QList<DataRequirements> lreq; lreq.append(req); DataTypes dt; dt.addData(lreq); dt.setAdapter(service1, &serviceAdapter); PelicanServerClient client(configNode, dt, 0); client.setPort(port); QHash<QString, DataBlob*> dataHash; DataBlob db("DataBlob"); dataHash.insert(service1, &db); CPPUNIT_ASSERT_THROW( client.getData(dataHash), QString ); } { // Use Case: // Single Request for an existing stream dataset // no service data // Expect: // return the required data stream StreamData sd(stream1, version1, data1 ); CPPUNIT_ASSERT_EQUAL( (long)data1.size(), (long)sd.size() ); server.serveStreamData(sd); // setup the test QList<DataRequirements> lreq; lreq.append(reqStream1); DataTypes dt; dt.addData(lreq); dt.setAdapter(stream1, &streamAdapter); PelicanServerClient client(configNode, dt, 0); client.setPort(port); QHash<QString, DataBlob*> dataHash; TestDataBlob db; dataHash.insert(stream1, &db); client.getData(dataHash); CPPUNIT_ASSERT_EQUAL(version1.toStdString(), db.version().toStdString() ); CPPUNIT_ASSERT_EQUAL( std::string(data1.data()), std::string(db.data()) ); } { // Use Case: // Single Request for an existing stream dataset // with existing service data // Expect: // return the required data stream DataChunk servd(service1, version2, data2 ); server.serveServiceData(servd); StreamData sd(stream1, version1, data1 ); CPPUNIT_ASSERT_EQUAL( (long)data1.size(), (long)sd.size() ); server.serveStreamData(sd); // setup the test DataRequirements req; req.addServiceData(service1); req.addStreamData(stream1); QList<DataRequirements> lreq; lreq.append(req); DataTypes dt; dt.addData(lreq); dt.setAdapter(stream1, &streamAdapter); dt.setAdapter(service1, &serviceAdapter); PelicanServerClient client(configNode, dt, 0); client.setPort(port); QHash<QString, DataBlob*> dataHash; TestDataBlob db; TestDataBlob db_service; dataHash.insert(stream1, &db); dataHash.insert(service1, &db_service); client.getData(dataHash); CPPUNIT_ASSERT_EQUAL( version1.toStdString(), db.version().toStdString() ); CPPUNIT_ASSERT_EQUAL( version2.toStdString(), db_service.version().toStdString() ); CPPUNIT_ASSERT_EQUAL( std::string(data2.data()), std::string(db_service.data()) ); CPPUNIT_ASSERT_EQUAL( std::string(data1.data()), std::string(db.data()) ); } } catch(const QString& e) { std::cerr << "error: uncaught exception" << e.toStdString(); throw e; } }
int main(int argc, char** argv) { try { QCoreApplication app(argc, argv); // Get command line arguments. if (argc != 5) { std::cerr << "Usage: directClient <port> <host> <chunk size, bytes> <iterations>" << std::endl; return 1; } int port = atoi(argv[1]); QString host(argv[2]); int chunkSize = atoi(argv[3]); int iterations = atoi(argv[4]); QString pipelineXml = "" "<buffers>" " <DoubleData>" " <buffer maxSize=\"2000000\" maxChunkSize=\"2000000\"/>" " </DoubleData>" "</buffers>" "<chunkers>" " <TestUdpChunker name=\"a\">" " <connection host=\"" + host + "\" port=\"" + QString::number(port) + "\"/>" " <data type=\"DoubleData\" chunkSize=\"" + QString::number(chunkSize) + "\"/>" " </TestUdpChunker>" "</chunkers>" "<clients>" " <DirectStreamDataClient>" " <data type=\"DoubleData\" adapter=\"AdapterRealData\"/>" " </DirectStreamDataClient>" "</clients>" "<adapters>" "</adapters>"; Config config; config.setFromString(pipelineXml); // Create the adapter factory. AbstractAdapterFactory adapterFactory(&config, "pipeline", "adapters"); // Create the data client factory. DataClientFactory clientFactory(&config, "pipeline", "clients", &adapterFactory); // Create the data blob factory. //FactoryGeneric<DataBlob> blobFactory; // Create a list of data requirements. QString dataType = "DoubleData"; DataRequirements req; QList<DataRequirements> requirements; req.addStreamData(dataType); requirements.append(req); // Create the client. DirectStreamDataClient* client = static_cast<DirectStreamDataClient*>( clientFactory.create("DirectStreamDataClient", requirements)); client->addStreamChunker("TestUdpChunker", "a"); // Set up the data hash. //QHash<QString, DataBlob*> dataHash; //dataHash.insert(dataType, blobFactory.create(dataType)); // Initialise loop counter. QTime timer; timer.start(); int counter = 0; double initValue = 0, value = 0; for (counter = 0; counter < iterations; counter++) { // Get the data. // QHash<QString, DataBlob*> validData = client->getData(dataHash); // Check the content of the data blob. // DoubleData* realData = (DoubleData*)validData.value(dataType); // //printData(realData); // value = realData->ptr()[0]; // if (counter == 0) // initValue = value; } // Check for lost packets. double dataRange = value - initValue; double lostPackets = dataRange + 1 - iterations; // Compute bandwidth. double sec = (double)timer.elapsed() / 1e3; long double megaBytesReceived = (long double)chunkSize * iterations / (1024 * 1024); // Print summary. std::cout << "---------------------------------------------------------\n"; std::cout << "Data range " << dataRange << " over " << iterations << " iterations. (Missed " << lostPackets << " packets.)\n"; std::cout << "Received " << megaBytesReceived << " MiB in " << sec << " seconds.\n"; std::cout << "Bandwidth: " << ((megaBytesReceived * 8) / sec) << " Mb/sec" << std::endl; std::cout << "---------------------------------------------------------\n"; } catch (QString error) { std::cerr << error.toStdString() << std::endl; } return 0; }