// Copyright (C) 2006 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#include <cstdlib>
#include <sstream>
#include <string>
#include <vector>
#include <ctime>
#include <dlib/sockets.h>
#include <dlib/misc_api.h>
#include <dlib/sockstreambuf.h>
#include "tester.h"
namespace
{
using namespace test;
using namespace dlib;
using namespace std;
dlib::mutex m;
dlib::signaler s(m);
bool thread_running;
logger dlog("test.sockstreambuf");
// ----------------------------------------------------------------------------------------
template <typename ssb>
struct thread_proc_struct
{
static void thread_proc (
void* param
)
{
listener& list = *static_cast<listener*>(param);
connection* con;
list.accept(con);
ssb buf(con);
ostream out(&buf);
char ch;
char* bigbuf = new char[1000000];
for (int i = 'a'; i < 'z'; ++i)
{
ch = i;
out << ch << " ";
}
out.put('A');
for (int i = 0; i < 256; ++i)
{
ch = i;
out.write(&ch,1);
}
for (int i = -100; i < 25600; ++i)
{
out << i << " ";
}
out.put('A');
for (int i = -100; i < 25600; ++i)
{
out.write((char*)&i,sizeof(i));
}
for (int i = 0; i < 1000000; ++i)
{
bigbuf[i] = (i&0xFF);
}
out.write(bigbuf,1000000);
out.put('d');
out.put('a');
out.put('v');
out.put('i');
out.put('s');
string tstring = "this is a test";
int tint = -853;
unsigned int tuint = 89;
serialize(tstring,out);
serialize(tint,out);
serialize(tuint,out);
out.flush();
auto_mutex M(m);
thread_running = false;
s.signal();
dlib::sleep(300);
delete con;
delete &list;
delete [] bigbuf;
}
};
template <typename ssb>
void sockstreambuf_test (
)
/*!
requires
- ssb is an implementation of sockstreambuf/sockstreambuf_kernel_abstract.h
ensures
- runs tests on ssb for compliance with the specs
!*/
{
char ch;
vector<char> vbuf;
vbuf.resize(1000000);
char* bigbuf = &vbuf[0];
connection* con;
print_spinner();
thread_running = true;
listener* list;
if (create_listener(list,0))
{
DLIB_TEST_MSG(false, "Unable to create a listener");
}
create_new_thread(&thread_proc_struct<ssb>::thread_proc,list);
if (create_connection(con,list->get_listening_port(),"127.0.0.1"))
{
DLIB_TEST_MSG(false, "Unable to create a connection");
}
// make sure con gets deleted
std::unique_ptr<connection> del_con(con);
ssb buf(con);
istream in(&buf);
for (int i = 'a'; i < 'z'; ++i)
{
in >> ch;
char c = i;
DLIB_TEST_MSG(ch == c,"ch: " << (int)ch << " c: " << (int)c);
}
in.get();
DLIB_TEST_MSG(in.peek() == 'A', "*" << in.peek() << "*");
in.get();
for (int i = 0; i < 256; ++i)
{
in.read(&ch,1);
char c = i;
DLIB_TEST_MSG(ch == c,"ch: " << (int)ch << " c: " << (int)c );
}
for (int i = -100; i < 25600; ++i)
{
int n = 0;
in >> n;
DLIB_TEST_MSG(n == i,"n: " << n << " i:" << i);
}
in.get();
DLIB_TEST_MSG(in.peek() == 'A', "*" << in.peek() << "*");
in.get();
for (int i = -100; i < 25600; ++i)
{
int n;
in.read((char*)&n,sizeof(n));
DLIB_TEST_MSG(n == i,"n: " << n << " i:" << i);
}
in.read(bigbuf,1000000);
for (int i = 0; i < 1000000; ++i)
{
DLIB_TEST(bigbuf[i] == (char)(i&0xFF));
}
DLIB_TEST(in.get() == 'd');
DLIB_TEST(in.get() == 'a');
DLIB_TEST(in.get() == 'v');
DLIB_TEST(in.get() == 'i');
DLIB_TEST(in.peek() == 's');
DLIB_TEST(in.get() == 's');
in.putback('s');
DLIB_TEST(in.peek() == 's');
DLIB_TEST(in.get() == 's');
string tstring;
int tint;
unsigned int tuint;
deserialize(tstring,in);
deserialize(tint,in);
deserialize(tuint,in);
DLIB_TEST(tstring == "this is a test");
DLIB_TEST(tint == -853);
DLIB_TEST(tuint == 89);
auto_mutex M(m);
while (thread_running)
s.wait();
}
// ----------------------------------------------------------------------------------------
class sockstreambuf_tester : public tester
{
public:
sockstreambuf_tester (
) :
tester ("test_sockstreambuf",
"Runs tests on the sockstreambuf component.")
{}
void perform_test (
)
{
dlog << LINFO << "testing sockstreambuf";
sockstreambuf_test<sockstreambuf>();
dlog << LINFO << "testing sockstreambuf_unbuffered";
sockstreambuf_test<sockstreambuf_unbuffered>();
}
} a;
}