summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/test/sockets2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/dlib/test/sockets2.cpp')
-rw-r--r--ml/dlib/dlib/test/sockets2.cpp204
1 files changed, 204 insertions, 0 deletions
diff --git a/ml/dlib/dlib/test/sockets2.cpp b/ml/dlib/dlib/test/sockets2.cpp
new file mode 100644
index 00000000..3521e751
--- /dev/null
+++ b/ml/dlib/dlib/test/sockets2.cpp
@@ -0,0 +1,204 @@
+// Copyright (C) 2008 Davis E. King (davis@dlib.net)
+// License: Boost Software License See LICENSE.txt for the full license.
+
+#include <algorithm>
+#include <memory>
+
+#include "tester.h"
+#include <dlib/sockets.h>
+#include <dlib/threads.h>
+#include <dlib/array.h>
+
+// This is called an unnamed-namespace and it has the effect of making everything
+// inside this file "private" so that everything you declare will have static linkage.
+// Thus we won't have any multiply defined symbol errors coming out of the linker when
+// we try to compile the test suite.
+namespace
+{
+ using namespace test;
+ using namespace dlib;
+ using namespace std;
+ // Declare the logger we will use in this test. The name of the logger
+ // should start with "test."
+ dlib::logger dlog("test.sockets2");
+
+
+ class sockets2_tester : public tester, private multithreaded_object
+ {
+ /*!
+ WHAT THIS OBJECT REPRESENTS
+ This object represents a unit test. When it is constructed
+ it adds itself into the testing framework.
+ !*/
+
+ short port_num;
+ string data_to_send;
+
+ bool test_failed;
+
+ void write_thread (
+ )
+ {
+ try
+ {
+ std::unique_ptr<connection> con(connect("127.0.0.1", port_num));
+
+ // Send a copy of the data down the connection so we can test our the read() function
+ // that uses timeouts in the main thread.
+ if (con->write(data_to_send.data(), data_to_send.size()) != (int)data_to_send.size())
+ {
+ test_failed = true;
+ dlog << LERROR << "failed to send all the data down the connection";
+ }
+
+ close_gracefully(con,300000);
+ }
+ catch (exception& e)
+ {
+ test_failed = true;
+ dlog << LERROR << e.what();
+ }
+ }
+
+ void no_write_thread (
+ )
+ {
+ try
+ {
+ std::unique_ptr<connection> con(connect("127.0.0.1", port_num));
+
+ // just do nothing until the connection closes
+ char ch;
+ con->read(&ch, 1);
+ dlog << LDEBUG << "silent connection finally closing";
+ }
+ catch (exception& e)
+ {
+ test_failed = true;
+ dlog << LERROR << e.what();
+ }
+ }
+
+ public:
+ sockets2_tester (
+ ) :
+ tester (
+ "test_sockets2", // the command line argument name for this test
+ "Run sockets2 tests.", // the command line argument description
+ 0 // the number of command line arguments for this test
+ )
+ {
+ register_thread(*this, &sockets2_tester::write_thread);
+ register_thread(*this, &sockets2_tester::write_thread);
+ register_thread(*this, &sockets2_tester::write_thread);
+ register_thread(*this, &sockets2_tester::write_thread);
+ register_thread(*this, &sockets2_tester::write_thread);
+ register_thread(*this, &sockets2_tester::no_write_thread);
+ }
+
+ void perform_test (
+ )
+ {
+ run_tests(0);
+ run_tests(40);
+ }
+
+ void run_tests (
+ unsigned long timeout_to_use
+ )
+ {
+ // make sure there aren't any threads running
+ wait();
+
+ port_num = 5000;
+ test_failed = false;
+
+ print_spinner();
+ data_to_send = "oi 2m3ormao2m fo2im3fo23mi o2mi3 foa2m3fao23ifm2o3fmia23oima23iom3giugbiua";
+ // make the block of data much larger
+ for (int i = 0; i < 11; ++i)
+ data_to_send = data_to_send + data_to_send;
+
+ dlog << LINFO << "data block size: " << data_to_send.size();
+
+
+ std::unique_ptr<listener> list;
+ DLIB_TEST(create_listener(list, port_num, "127.0.0.1") == 0);
+ DLIB_TEST(bool(list));
+
+ // kick off the sending threads
+ start();
+
+
+ dlib::array<std::unique_ptr<connection> > cons;
+ std::vector<long> bytes_received(6,0);
+ std::unique_ptr<connection> con_temp;
+
+ // accept the 6 connections we should get
+ for (int i = 0; i < 6; ++i)
+ {
+ DLIB_TEST(list->accept(con_temp) == 0);
+ cons.push_back(con_temp);
+ print_spinner();
+ }
+
+ int finished_cons = 0;
+
+ // now receive all the bytes from the sending threads
+ while (finished_cons < 5)
+ {
+ for (unsigned long i = 0; i < cons.size(); ++i)
+ {
+ if (cons[i])
+ {
+ const int buf_size = 3000;
+ char buf[buf_size];
+
+ int status = cons[i]->read(buf, buf_size, timeout_to_use);
+
+ if (status > 0)
+ {
+ DLIB_TEST(equal(buf, buf+status, data_to_send.begin()+bytes_received[i]));
+ bytes_received[i] += status;
+ }
+ else if (status == 0)
+ {
+ // the connection is closed to kill it
+ cons[i].reset();
+ ++finished_cons;
+ }
+ }
+ }
+ print_spinner();
+ }
+
+ for (unsigned long i = 0; i < bytes_received.size(); ++i)
+ {
+ DLIB_TEST(bytes_received[i] == (long)data_to_send.size() || cons[i]);
+ }
+
+
+ dlog << LINFO << "All data received correctly";
+
+ cons.clear();
+
+
+ print_spinner();
+
+ DLIB_TEST(test_failed == false);
+
+
+ // wait for all the sending threads to terminate
+ wait();
+ }
+ };
+
+ // Create an instance of this object. Doing this causes this test
+ // to be automatically inserted into the testing framework whenever this cpp file
+ // is linked into the project. Note that since we are inside an unnamed-namespace
+ // we won't get any linker errors about the symbol a being defined multiple times.
+ sockets2_tester a;
+
+}
+
+