/*!
  \file
  \brief TcpipServer のテスト

  \author Satofumi KAMIMURA

  $Id: TestTcpipServer.cpp 1347 2009-09-30 06:40:12Z satofumi $
*/

#include "TestTcpipServer.h"
#include "TcpipServer.h"
#include "TcpipSocket.h"
#include "Thread.h"

using namespace qrk;
using namespace std;


CPPUNIT_TEST_SUITE_REGISTRATION(TestTcpipServer);
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(TestTcpipServer, "TestTcpipServer");

enum {
  Port = 57577,
  Timeout = 1000,
};


namespace
{
  static int connectThread(void* args)
  {
    TcpipServer* server = static_cast<TcpipServer*>(args);

    return server->accept(Timeout);
  }
}


void TestTcpipServer::connectTest(void)
{
  // サーバの起動
  TcpipServer server;
  bool activated = server.activate(Port);
  CPPUNIT_ASSERT_EQUAL(true, activated);
  Thread thread(connectThread, &server);
  thread.run(1);

  // クライアントからの接続
  TcpipSocket client;
  if (! client.connect("localhost", Port)) {
    CPPUNIT_FAIL(string("connection failed.: ") + client.what());
  }

  bool is_connected = thread.wait();
  CPPUNIT_ASSERT_EQUAL_MESSAGE(server.what(), true, is_connected);

  // サーバからの１文字送信
  int send_size = server.send("a", 1);
  CPPUNIT_ASSERT_EQUAL(1, send_size);

  char ch = '\0';
  int recv_size = client.receive(&ch, 1, Timeout);
  CPPUNIT_ASSERT_EQUAL(1, recv_size);
  CPPUNIT_ASSERT_EQUAL(ch, 'a');


  // クライアントからの１文字送信
  send_size = client.send("A", 1);
  CPPUNIT_ASSERT_EQUAL(1, send_size);

  ch = '\0';
  recv_size = server.receive(&ch, 1, Timeout);
  CPPUNIT_ASSERT_EQUAL(1, recv_size);
  CPPUNIT_ASSERT_EQUAL(ch, 'A');
}


void TestTcpipServer::timeoutTest(void)
{
  // サーバの起動
  TcpipServer server;
  bool activated = server.activate(Port);
  CPPUNIT_ASSERT_EQUAL(true, activated);
  Thread thread(connectThread, &server);
  thread.run(1);

  // クライアントからの接続
  TcpipSocket client;
  if (! client.connect("localhost", Port)) {
    CPPUNIT_FAIL(string("connection failed.: ") + client.what());
  }

  bool is_connected = thread.wait();
  CPPUNIT_ASSERT_EQUAL_MESSAGE(server.what(), true, is_connected);

  // 即座にタイムアウトするか、のテスト
  char ch = '\0';
  int recv_size = client.receive(&ch, 1, 0);
  CPPUNIT_ASSERT_EQUAL(0, recv_size);
}
