/* Copyright (C) 2020 Carl Hetherington This file is part of DCP-o-matic. DCP-o-matic is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. DCP-o-matic is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with DCP-o-matic. If not, see . */ #include "lib/server.h" #include "lib/dcpomatic_socket.h" #include #include #include #include #include using boost::shared_ptr; using boost::bind; #define TEST_SERVER_PORT 9142 #define TEST_SERVER_BUFFER_LENGTH 1024 class TestServer : public Server { public: TestServer (bool digest) : Server (TEST_SERVER_PORT, 30) , _buffer (new uint8_t[TEST_SERVER_BUFFER_LENGTH]) , _size (0) , _result (false) , _digest (digest) { _thread = boost::thread(bind(&TestServer::run, this)); } ~TestServer () { stop (); _thread.join (); delete[] _buffer; } void expect (int size) { boost::mutex::scoped_lock lm (_mutex); _size = size; } uint8_t const * buffer() const { return _buffer; } void await () { boost::mutex::scoped_lock lm (_mutex); if (_size) { _condition.wait (lm); } } bool result () const { return _result; } private: void handle (boost::shared_ptr socket) { boost::mutex::scoped_lock lm (_mutex); BOOST_REQUIRE (_size); if (_digest) { Socket::ReadDigestScope ds (socket); socket->read (_buffer, _size); _size = 0; _condition.notify_one (); _result = ds.check(); } else { socket->read (_buffer, _size); _size = 0; _condition.notify_one (); } } boost::thread _thread; boost::mutex _mutex; boost::condition _condition; uint8_t* _buffer; int _size; bool _result; bool _digest; }; void send (shared_ptr socket, char const* message) { socket->write (reinterpret_cast(message), strlen(message) + 1); } /** Basic test to see if Socket can send and receive data */ BOOST_AUTO_TEST_CASE (socket_basic_test) { TestServer server(false); server.expect (13); shared_ptr socket (new Socket); socket->connect (boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), TEST_SERVER_PORT)); send (socket, "Hello world!"); server.await (); BOOST_CHECK_EQUAL(strcmp(reinterpret_cast(server.buffer()), "Hello world!"), 0); } /** Check that the socket "auto-digest" creation works */ BOOST_AUTO_TEST_CASE (socket_digest_test1) { TestServer server(false); server.expect (13 + 16); shared_ptr socket(new Socket); socket->connect (boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), TEST_SERVER_PORT)); { Socket::WriteDigestScope ds(socket); send (socket, "Hello world!"); } server.await (); BOOST_CHECK_EQUAL(strcmp(reinterpret_cast(server.buffer()), "Hello world!"), 0); /* printf "%s\0" "Hello world!" | md5sum" in bash */ char ref[] = "\x59\x86\x88\xed\x18\xc8\x71\xdd\x57\xb9\xb7\x9f\x4b\x03\x14\xcf"; BOOST_CHECK_EQUAL (memcmp(server.buffer() + 13, ref, 16), 0); } /** Check that the socket "auto-digest" round-trip works */ BOOST_AUTO_TEST_CASE (socket_digest_test2) { TestServer server(true); server.expect (13); shared_ptr socket(new Socket); socket->connect (boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), TEST_SERVER_PORT)); { Socket::WriteDigestScope ds(socket); send (socket, "Hello world!"); } server.await (); BOOST_CHECK_EQUAL(strcmp(reinterpret_cast(server.buffer()), "Hello world!"), 0); BOOST_CHECK (server.result()); }