void SocketTest::testSelect() { Timespan timeout(250000); EchoServer echoServer; StreamSocket ss; ss.connect(SocketAddress("localhost", echoServer.port())); Socket::SocketList readList; Socket::SocketList writeList; Socket::SocketList exceptList; readList.push_back(ss); assert (Socket::select(readList, writeList, exceptList, timeout) == 0); assert (readList.empty()); assert (writeList.empty()); assert (exceptList.empty()); ss.sendBytes("hello", 5); ss.poll(timeout, Socket::SELECT_READ); readList.push_back(ss); writeList.push_back(ss); assert (Socket::select(readList, writeList, exceptList, timeout) == 2); assert (!readList.empty()); assert (!writeList.empty()); assert (exceptList.empty()); char buffer[256]; int n = ss.receiveBytes(buffer, sizeof(buffer)); assert (n == 5); assert (std::string(buffer, n) == "hello"); ss.close(); }
void SocketTest::testOptions() { EchoServer echoServer; StreamSocket ss; ss.connect(SocketAddress("localhost", echoServer.port())); ss.setLinger(true, 20); bool f; int t; ss.getLinger(f, t); assert (f && t == 20); ss.setLinger(false, 0); ss.getLinger(f, t); assert (!f); ss.setNoDelay(true); assert (ss.getNoDelay()); ss.setNoDelay(false); assert (!ss.getNoDelay()); ss.setKeepAlive(true); assert (ss.getKeepAlive()); ss.setKeepAlive(false); assert (!ss.getKeepAlive()); ss.setOOBInline(true); assert (ss.getOOBInline()); ss.setOOBInline(false); assert (!ss.getOOBInline()); }
void SocketStreamTest::testEOF() { StreamSocket ss; SocketStream str(ss); { EchoServer echoServer; ss.connect(SocketAddress("localhost", echoServer.port())); str << "hello"; assert (str.good()); str.flush(); assert (str.good()); ss.shutdownSend(); char buffer[5]; str.read(buffer, sizeof(buffer)); assert (str.good()); assert (str.gcount() == 5); assert (std::string(buffer, 5) == "hello"); } int c = str.get(); assert (c == -1); assert (str.eof()); ss.close(); }
/** * @brief Performs several send of messages in a sync way. * @param GSpotTestUT The test case name. * @param TestSpotSessionSyncSend The test name. * @since 1.0.0 */ TEST(GSpotTestUT, TestSpotSessionSyncSend) { std::cout << std::endl << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; std::cout << "////// TestSpotSessionSyncSend ////////" << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; EchoServer echoServer; SpotChannel spotChannel("localhost", echoServer.port()); MockSpotSessionCancelTimers spotSession; spotSession.start(spotChannel); EXPECT_EQ(spotSession.isConnected(), true); // First synchronous send and response evaluation ... ////////////////////////////////////////////////////////////////////// SpotMessagePing firstSpotPingMessageRq; spotSession.sendSync(firstSpotPingMessageRq, firstSpotPingMessageRq); EXPECT_EQ(spotSession.getError(), SpotSession::SpotSessionError::CNoError); ////////////////////////////////////////////////////////////////////// // Second synchronous send and response evaluation ... ////////////////////////////////////////////////////////////////////// SpotMessagePing secondSpotPingMessageRq; spotSession.sendSync(secondSpotPingMessageRq, secondSpotPingMessageRq, 1000); EXPECT_EQ(spotSession.getError(), SpotSession::SpotSessionError::CNoError); ////////////////////////////////////////////////////////////////////// // Third synchronous send and response evaluation ... ////////////////////////////////////////////////////////////////////// SpotMessagePing thirdSpotPingMessageRq; // Wait for another type of message to generate the desire condition, the timeout condition. SpotMessageLogin thirdSpotPingMessageRs; spotSession.sendSync(thirdSpotPingMessageRq, thirdSpotPingMessageRs, 10); EXPECT_EQ(spotSession.getError(), SpotSession::SpotSessionError::CErrorTimeoutSendingMessage); ////////////////////////////////////////////////////////////////////// // Fourth synchronous send and response evaluation ... ////////////////////////////////////////////////////////////////////// SpotMessagePing fourthSpotPingMessageRq; spotSession.sendSync(fourthSpotPingMessageRq, fourthSpotPingMessageRq, 1000); EXPECT_EQ(spotSession.getError(), SpotSession::SpotSessionError::CNoError); ////////////////////////////////////////////////////////////////////// EXPECT_EQ(spotSession.getError(), SpotSession::SpotSessionError::CNoError); spotSession.stop(); EXPECT_EQ(spotSession.isConnected(), false); std::cout << "SpotSession was stopped..." << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; std::cout << std::endl << std::endl; }
void SocketTest::testFIFOBuffer() { Buffer<char> b(5); b[0] = 'h'; b[1] = 'e'; b[2] = 'l'; b[3] = 'l'; b[4] = 'o'; FIFOBuffer f(5, true); f.readable += delegate(this, &SocketTest::onReadable); f.writable += delegate(this, &SocketTest::onWritable); assert(0 == _notToReadable); assert(0 == _readableToNot); assert(0 == _notToWritable); assert(0 == _writableToNot); f.write(b); assert(1 == _notToReadable); assert(0 == _readableToNot); assert(0 == _notToWritable); assert(1 == _writableToNot); EchoServer echoServer; StreamSocket ss; ss.connect(SocketAddress("localhost", echoServer.port())); int n = ss.sendBytes(f); assert (n == 5); assert(1 == _notToReadable); assert(1 == _readableToNot); assert(1 == _notToWritable); assert(1 == _writableToNot); assert (f.isEmpty()); n = ss.receiveBytes(f); assert (n == 5); assert(2 == _notToReadable); assert(1 == _readableToNot); assert(1 == _notToWritable); assert(2 == _writableToNot); assert (f[0] == 'h'); assert (f[1] == 'e'); assert (f[2] == 'l'); assert (f[3] == 'l'); assert (f[4] == 'o'); f.readable -= delegate(this, &SocketTest::onReadable); f.writable -= delegate(this, &SocketTest::onWritable); ss.close(); }
/** * @brief Performs connection throw a SpotChannel. * @param GSpotTestUT The test case name. * @param TestSpotChannel The test name. * @since 1.0.0 */ TEST(GSpotTestUT, TestSpotChannel) { std::cout << std::endl << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; std::cout << "////// TestSpotChannel ////////" << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; EchoServer echoServer; ChannelListenerWorker listenerOne("Listener One"); SpotChannel spotChannel("localhost", echoServer.port()); spotChannel.start(); spotChannel.subscribe( listenerOne ); listenerOne.setChannel(spotChannel); EXPECT_EQ(spotChannel.getError(), SpotChannel::SpotChannelError::CNoError); if( spotChannel.getStatus() == SpotChannel::SpotChannelStatus::CStatusConnected ) { std::string str = "hello"; gvr::communication::IChannel::BufferType data(str.begin(), str.end()); spotChannel.send(data); EXPECT_EQ(spotChannel.getError(), SpotChannel::SpotChannelError::CNoError); // Check the condition in a maximum elased time ... /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Timestamp initialTime; const unsigned long usTimeout = 800000; // timeout in microseconds... 1000 microseconds are 1 millisecond. while ( ( listenerOne.getLastBufferReceived().empty() ) && ( Timestamp::TimeDiff((Timestamp()-initialTime)) < usTimeout ) ) { Thread::sleep(1); } std::cout << "Elapsed time ...[" << std::dec << Timestamp::TimeDiff( (Timestamp()-initialTime) ) << " us]." << std::endl; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// EXPECT_EQ(listenerOne.getLastBufferReceived(), "hello"); } spotChannel.stop(); std::cout << "SpotChannel was stopped..." << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; std::cout << std::endl << std::endl; }
void SocketTest::testEcho() { EchoServer echoServer; StreamSocket ss; ss.connect(SocketAddress("localhost", echoServer.port())); int n = ss.sendBytes("hello", 5); assert (n == 5); char buffer[256]; n = ss.receiveBytes(buffer, sizeof(buffer)); assert (n == 5); assert (std::string(buffer, n) == "hello"); ss.close(); }
/** * * @brief Performs several connections and disconnections to check the SpotSession. * @param GSpotTestUT The test case name. * @param TestSpotSessionStopStart The test name. * @since 1.0.0 */ TEST(GSpotTestUT, TestSpotSessionStopStart) { std::cout << std::endl << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; std::cout << "////// TestSpotSessionStopStart ////////" << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; EchoServer echoServer; SpotChannel spotChannel("localhost", echoServer.port()); MockSpotSessionCancelTimers spotSession; for(int i=0; i<5; i++) { std::cout << "Starting the SpotSession( sequence [" << std::dec << i+1 << "] )..." << std::endl; spotSession.start(spotChannel); EXPECT_EQ(spotSession.getError(), SpotSession::SpotSessionError::CNoError); if( spotSession.getError() != SpotSession::SpotSessionError::CNoError ) { std::cout << "[" << spotSession.getErrorDescription() << "]" << std::endl; } EXPECT_EQ(spotSession.isConnected(), true); std::cout << "Stopping the SpotSession..." << std::endl; spotSession.stop(); EXPECT_EQ(spotSession.isConnected(), false); EXPECT_EQ(spotSession.getError(), SpotSession::SpotSessionError::CNoError); std::cout << "SpotSession was stopped..." << std::endl; if( spotSession.getError() != SpotSession::SpotSessionError::CNoError ) { std::cout << "[" << spotSession.getErrorDescription() << "]" << std::endl; } } spotSession.stop(); std::cout << "SpotSession was stopped..." << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; std::cout << std::endl << std::endl; }
int main(){ abb::net::SocketAddress addr; if( ! addr.SetUnix("echo_svr",4) ){ LOG(INFO) << "SetUnix fail"; return -1; } EchoServer svr; svr.Start(addr); while(true){ if(svr.num_pkt) LOG(INFO) << "num_pkt:" << svr.num_pkt; svr.num_pkt = 0; sleep(1000); } }
int main() { Logger logger = Logger::getInstance(LOG4CPLUS_TEXT("samples.Applications.EchoServer")); PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("echoServerLog.properties")); LOG4CPLUS_INFO(logger, " begin Echo Client main()"); EchoServer * server = new EchoServer(); server->run(); delete server; LOG4CPLUS_INFO(logger, "end Echo Client main()"); return 0; }
void SocketTest::testAvailable() { EchoServer echoServer; StreamSocket ss; ss.connect(SocketAddress("localhost", echoServer.port())); Timespan timeout(1000000); ss.sendBytes("hello", 5); char buffer[256]; assert (ss.poll(timeout, Socket::SELECT_READ)); int av = ss.available(); assert (av > 0 && av <= 5); int n = ss.receiveBytes(buffer, sizeof(buffer)); assert (n == 5); assert (std::string(buffer, n) == "hello"); ss.close(); }
void DialogSocketTest::testDialogSocket() { EchoServer echoServer; DialogSocket ds; ds.connect(SocketAddress("localhost", echoServer.port())); ds.sendMessage("Hello, world!"); std::string str; ds.receiveMessage(str); assert (str == "Hello, world!"); ds.sendString("Hello, World!\n"); ds.receiveMessage(str); assert (str == "Hello, World!"); ds.sendMessage("EHLO", "appinf.com"); ds.receiveMessage(str); assert (str == "EHLO appinf.com"); ds.sendMessage("PUT", "local.txt", "remote.txt"); ds.receiveMessage(str); assert (str == "PUT local.txt remote.txt"); ds.sendMessage("220 Hello, world!"); int status = ds.receiveStatusMessage(str); assert (status == 220); assert (str == "220 Hello, world!"); ds.sendString("220-line1\r\n220 line2\r\n"); status = ds.receiveStatusMessage(str); assert (status == 220); assert (str == "220-line1\n220 line2"); ds.sendString("220-line1\r\nline2\r\n220 line3\r\n"); status = ds.receiveStatusMessage(str); assert (status == 220); assert (str == "220-line1\nline2\n220 line3"); ds.sendMessage("Hello, world!"); status = ds.receiveStatusMessage(str); assert (status == 0); assert (str == "Hello, world!"); }
void SocketTest::testBufferSize() { EchoServer echoServer; StreamSocket ss; ss.connect(SocketAddress("localhost", echoServer.port())); int osz = ss.getSendBufferSize(); int rsz = 32000; ss.setSendBufferSize(rsz); int asz = ss.getSendBufferSize(); std::cout << "original send buffer size: " << osz << std::endl; std::cout << "requested send buffer size: " << rsz << std::endl; std::cout << "actual send buffer size: " << asz << std::endl; osz = ss.getReceiveBufferSize(); ss.setReceiveBufferSize(rsz); asz = ss.getReceiveBufferSize(); std::cout << "original recv buffer size: " << osz << std::endl; std::cout << "requested recv buffer size: " << rsz << std::endl; std::cout << "actual recv buffer size: " << asz << std::endl; }
/** * @brief Performs a simulation of a disconnection and the spot session retries connection. * @param GSpotTestUT The test case name. * @param TestSpotSessionRetries The test name. * @since 1.0.0 */ TEST(GSpotTestUT, TestSpotSessionAvoidUnknownMsg) { std::cout << std::endl << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; std::cout << "////// TestSpotSessionAvoidUnknownMsg ////////" << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; EchoServer echoServer; SpotChannel spotChannel("localhost", echoServer.port()); MockSpotSessionNoAllClassifiers spotSession; spotSession.start(spotChannel); EXPECT_EQ(spotSession.isReady(), true); SpotMessagePing spotPingMessageRq; SpotMessagePingResponse spotPingMessageRs; spotSession.sendSync(spotPingMessageRq, spotPingMessageRs); EXPECT_EQ(spotSession.remainingBuffer(), false); //NO remaining buffer because the unknown ping message was discarded. spotSession.stop(); std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; std::cout << std::endl << std::endl; }
/** * @brief Performs a simulation of a disconnection from the other end and if the Listeners respond well. * @param GSpotTestUT The test case name. * @param TestSpotSessionCheckDisconnect The test name. * @since 1.0.0 */ TEST(GSpotTestUT, TestSpotSessionCheckDisconnect) { std::cout << std::endl << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; std::cout << "////// TestSpotSessionCheckDisconnect ////////" << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; EchoServer echoServer; SpotChannel spotChannel("localhost", echoServer.port()); MockSpotSessionCancelTimers spotSession; spotSession.start(spotChannel); EXPECT_EQ(spotSession.isConnected(), true); long ms_time_to_throw_the_disconnection = 1000; // 1 second long ms_time_to_wait_in_send_sync = 2000; // 2 seconds echoServer.startTimer(ms_time_to_throw_the_disconnection); // Send a message and wait the disconnect from the echo server ... ////////////////////////////////////////////////////////////////////// SpotMessagePing spotPingMessageRq; SpotMessageLogin spotLoginMessageRs; // Wait for another type of message to generate the desired situation. spotSession.sendSync(spotPingMessageRq, spotLoginMessageRs, ms_time_to_wait_in_send_sync); Thread::sleep(10); EXPECT_EQ(spotSession.getStatus(), SpotSession::SpotSessionStatus::CStatusSessionStopped); ////////////////////////////////////////////////////////////////////// spotSession.stop(); EXPECT_EQ(spotSession.isConnected(), false); std::cout << "SpotSession was stopped..." << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; std::cout << std::endl << std::endl; }
void SocketTest::testPoll() { EchoServer echoServer; StreamSocket ss; ss.connect(SocketAddress("localhost", echoServer.port())); Stopwatch sw; sw.start(); Timespan timeout(1000000); assert (!ss.poll(timeout, Socket::SELECT_READ)); assert (sw.elapsed() >= 900000); sw.restart(); assert (ss.poll(timeout, Socket::SELECT_WRITE)); assert (sw.elapsed() < 100000); ss.sendBytes("hello", 5); char buffer[256]; sw.restart(); assert (ss.poll(timeout, Socket::SELECT_READ)); assert (sw.elapsed() < 100000); int n = ss.receiveBytes(buffer, sizeof(buffer)); assert (n == 5); assert (std::string(buffer, n) == "hello"); ss.close(); }
int main() { signal(SIGPIPE, sigHandler); signal(SIGHUP, sigHandler); Transport gClientTrans; gClientTrans.start(); EchoServer server; server.start(); for (int i = 0; i < 1; i++) { EchoClient* client = new EchoClient; client->mClientTrans = &gClientTrans; cout << "Round " << i << endl; client->Run(); usleep(100000); waitpid(-1, NULL, WNOHANG); } gClientTrans.stop(); gClientTrans.wait(); server.stop(); }
// // FUNCTION: InitInstance(HINSTANCE, int) // // PURPOSE: Saves instance handle and creates main window // // COMMENTS: // // In this function, we save the instance handle in a global variable and // create and display the main program window. // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // Store instance handle in our global variable hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } // Start EchoServer g_server.InitServer( hWnd ); g_server.StartServer( 9001 ); ShowWindow( hWnd, nCmdShow ); UpdateWindow(hWnd); return TRUE; }
void SocketTest::testTimeout() { EchoServer echoServer; StreamSocket ss; ss.connect(SocketAddress("localhost", echoServer.port())); Timespan timeout0 = ss.getReceiveTimeout(); Timespan timeout(250000); ss.setReceiveTimeout(timeout); Timespan timeout1 = ss.getReceiveTimeout(); std::cout << "original receive timeout: " << timeout0.totalMicroseconds() << std::endl; std::cout << "requested receive timeout: " << timeout.totalMicroseconds() << std::endl; std::cout << "actual receive timeout: " << timeout1.totalMicroseconds() << std::endl; // some socket implementations adjust the timeout value // assert (ss.getReceiveTimeout() == timeout); Stopwatch sw; try { char buffer[256]; sw.start(); ss.receiveBytes(buffer, sizeof(buffer)); fail("nothing to receive - must timeout"); } catch (TimeoutException&) { } assert (sw.elapsed() < 1000000); timeout0 = ss.getSendTimeout(); ss.setSendTimeout(timeout); timeout1 = ss.getSendTimeout(); std::cout << "original send timeout: " << timeout0.totalMicroseconds() << std::endl; std::cout << "requested send timeout: " << timeout.totalMicroseconds() << std::endl; std::cout << "actual send timeout: " << timeout1.totalMicroseconds() << std::endl; // assert (ss.getSendTimeout() == timeout); }
void SocketStreamTest::testLargeStreamEcho() { const int msgSize = 64000; EchoServer echoServer; StreamSocket ss; ss.connect(SocketAddress("localhost", echoServer.port())); SocketStream str(ss); ss.setSendBufferSize(msgSize); ss.setReceiveBufferSize(msgSize); std::string payload(msgSize, 'x'); str << payload; assert (str.good()); str.flush(); assert (str.good()); ss.shutdownSend(); assert (str.gcount() == 0); char buffer[msgSize]; str.read(buffer, sizeof(buffer)); assert (str.good()); assert (str.gcount() == msgSize); ss.close(); }
int main(int argc, char **argv) { EchoServer server; server.start(); return 0; }
/** * @brief Performs a simulation of a subscription to a particular message type. * @param GSpotTestUT The test case name. * @param TestSpotSessionSpecialMessageSubscribe The test name. * @since 1.0.0 */ TEST(GSpotTestUT, TestSpotSessionSpecialMessageSubscribe) { std::cout << std::endl << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; std::cout << "////// TestSpotSessionSpecialMessageSubscribe ////////" << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; EchoServer echoServer; SpotSessionListenerWorker workerOne("Worker One"); SpotSessionListenerWorker workerTwo("Worker Two"); SpotChannel spotChannel("localhost", echoServer.port()); MockSpotSessionCancelTimers spotSession; SpotMessagePing firstSpotPingMessageRq; SpotMessageLogin firstSpotLoginMessageRq; SpotMessagePingResponse firstSpotPingMessageRs; SpotMessagePing firstSpotPingMessageRq2; spotSession.subscribe(workerOne, firstSpotPingMessageRq.getTypeId()); spotSession.subscribe(workerOne, firstSpotPingMessageRq2.getTypeId()); spotSession.subscribe(workerTwo, firstSpotLoginMessageRq.getTypeId()); spotSession.subscribe(workerTwo, firstSpotPingMessageRs.getTypeId()); EXPECT_EQ(firstSpotPingMessageRq.getTypeId(), SpotMessagePing::GetTypeId()); workerOne.setSession(spotSession); workerTwo.setSession(spotSession); std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; spotSession.start(spotChannel); EXPECT_EQ(spotSession.isConnected(), true); // First asynchronous send and response evaluation ... ////////////////////////////////////////////////////////////////////// { spotSession.send(firstSpotPingMessageRq); EXPECT_EQ(spotSession.getError(), SpotSession::SpotSessionError::CNoError); // Check the condition in a maximum elapsed time ... { Timestamp initialTime; const unsigned long usTimeout = 800000; // timeout in microseconds... 1000 microseconds are 1 millisecond. while ( ( workerOne.getTypeId() != firstSpotPingMessageRq.getTypeId() ) && ( Timestamp::TimeDiff( (Timestamp()-initialTime) ) < usTimeout ) ) { Thread::sleep(1); } std::cout << "Elapsed time ...[" << std::dec << Timestamp::TimeDiff( (Timestamp()-initialTime) ) << " us]." << std::endl; } EXPECT_EQ(workerOne.getTypeId(), firstSpotPingMessageRq.getTypeId()); } ////////////////////////////////////////////////////////////////////// // Second asynchronous send and response evaluation ... ////////////////////////////////////////////////////////////////////// { spotSession.send(firstSpotLoginMessageRq); EXPECT_EQ(spotSession.getError(), SpotSession::SpotSessionError::CNoError); // Check the condition in a maximum elapsed time ... { Timestamp initialTime; const unsigned long usTimeout = 800000; // timeout in microseconds... 1000 microseconds are 1 millisecond. while ( ( workerTwo.getTypeId() != firstSpotLoginMessageRq.getTypeId() ) && ( Timestamp::TimeDiff( (Timestamp()-initialTime) ) < usTimeout ) ) { Thread::sleep(1); } std::cout << "Elapsed time ...[" << std::dec << Timestamp::TimeDiff( (Timestamp()-initialTime) ) << " us]." << std::endl; } EXPECT_EQ(workerTwo.getTypeId(), firstSpotLoginMessageRq.getTypeId()); SpotMessagePing spotPingMessageRq; spotPingMessageRq.parse(workerOne.getBuffer()); EXPECT_EQ(spotPingMessageRq.getTypeId(), firstSpotPingMessageRq.getTypeId()); } ////////////////////////////////////////////////////////////////////// std::cout << "Stopping the SpotSession..." << std::endl; spotSession.stop(); EXPECT_EQ(spotSession.isConnected(), false); std::cout << "SpotSession was stopped..." << std::endl; std::cout << "//////////////////////////////////////////////////////////////////////" << std::endl; std::cout << std::endl << std::endl; }
int main(int argc, char** argv) { EchoServer app; return app.run(argc, argv); }