Home | History | Annotate | Download | only in cctest
      1 // Copyright 2009 the V8 project authors. All rights reserved.
      2 
      3 #include "v8.h"
      4 #include "platform.h"
      5 #include "cctest.h"
      6 
      7 
      8 using namespace ::v8::internal;
      9 
     10 
     11 class SocketListenerThread : public Thread {
     12  public:
     13   SocketListenerThread(int port, int data_size)
     14       : Thread("SocketListenerThread"),
     15         port_(port),
     16         data_size_(data_size),
     17         server_(NULL),
     18         client_(NULL),
     19         listening_(OS::CreateSemaphore(0)) {
     20     data_ = new char[data_size_];
     21   }
     22   ~SocketListenerThread() {
     23     // Close both sockets.
     24     delete client_;
     25     delete server_;
     26     delete listening_;
     27     delete[] data_;
     28   }
     29 
     30   void Run();
     31   void WaitForListening() { listening_->Wait(); }
     32   char* data() { return data_; }
     33 
     34  private:
     35   int port_;
     36   char* data_;
     37   int data_size_;
     38   Socket* server_;  // Server socket used for bind/accept.
     39   Socket* client_;  // Single client connection used by the test.
     40   Semaphore* listening_;  // Signalled when the server socket is in listen mode.
     41 };
     42 
     43 
     44 void SocketListenerThread::Run() {
     45   bool ok;
     46 
     47   // Create the server socket and bind it to the requested port.
     48   server_ = OS::CreateSocket();
     49   server_->SetReuseAddress(true);
     50   CHECK(server_ != NULL);
     51   ok = server_->Bind(port_);
     52   CHECK(ok);
     53 
     54   // Listen for new connections.
     55   ok = server_->Listen(1);
     56   CHECK(ok);
     57   listening_->Signal();
     58 
     59   // Accept a connection.
     60   client_ = server_->Accept();
     61   CHECK(client_ != NULL);
     62 
     63   // Read the expected niumber of bytes of data.
     64   int bytes_read = 0;
     65   while (bytes_read < data_size_) {
     66     bytes_read += client_->Receive(data_ + bytes_read, data_size_ - bytes_read);
     67   }
     68 }
     69 
     70 
     71 static bool SendAll(Socket* socket, const char* data, int len) {
     72   int sent_len = 0;
     73   while (sent_len < len) {
     74     int status = socket->Send(data, len);
     75     if (status <= 0) {
     76       return false;
     77     }
     78     sent_len += status;
     79   }
     80   return true;
     81 }
     82 
     83 
     84 static void SendAndReceive(int port, char *data, int len) {
     85   static const char* kLocalhost = "localhost";
     86 
     87   bool ok;
     88 
     89   // Make a string with the port number.
     90   const int kPortBuferLen = 6;
     91   char port_str[kPortBuferLen];
     92   OS::SNPrintF(Vector<char>(port_str, kPortBuferLen), "%d", port);
     93 
     94   // Create a socket listener.
     95   SocketListenerThread* listener = new SocketListenerThread(port, len);
     96   listener->Start();
     97   listener->WaitForListening();
     98 
     99   // Connect and write some data.
    100   Socket* client = OS::CreateSocket();
    101   CHECK(client != NULL);
    102   ok = client->Connect(kLocalhost, port_str);
    103   CHECK(ok);
    104 
    105   // Send all the data.
    106   ok = SendAll(client, data, len);
    107   CHECK(ok);
    108 
    109   // Wait until data is received.
    110   listener->Join();
    111 
    112   // Check that data received is the same as data send.
    113   for (int i = 0; i < len; i++) {
    114     CHECK(data[i] == listener->data()[i]);
    115   }
    116 
    117   // Close the client before the listener to avoid TIME_WAIT issues.
    118   client->Shutdown();
    119   delete client;
    120   delete listener;
    121 }
    122 
    123 
    124 TEST(Socket) {
    125   // Make sure this port is not used by other tests to allow tests to run in
    126   // parallel.
    127   static const int kPort = 5859;
    128 
    129   bool ok;
    130 
    131   // Initialize socket support.
    132   ok = Socket::SetUp();
    133   CHECK(ok);
    134 
    135   // Send and receive some data.
    136   static const int kBufferSizeSmall = 20;
    137   char small_data[kBufferSizeSmall + 1] = "1234567890abcdefghij";
    138   SendAndReceive(kPort, small_data, kBufferSizeSmall);
    139 
    140   // Send and receive some more data.
    141   static const int kBufferSizeMedium = 10000;
    142   char* medium_data = new char[kBufferSizeMedium];
    143   for (int i = 0; i < kBufferSizeMedium; i++) {
    144     medium_data[i] = i % 256;
    145   }
    146   SendAndReceive(kPort, medium_data, kBufferSizeMedium);
    147   delete[] medium_data;
    148 
    149   // Send and receive even more data.
    150   static const int kBufferSizeLarge = 1000000;
    151   char* large_data = new char[kBufferSizeLarge];
    152   for (int i = 0; i < kBufferSizeLarge; i++) {
    153     large_data[i] = i % 256;
    154   }
    155   SendAndReceive(kPort, large_data, kBufferSizeLarge);
    156   delete[] large_data;
    157 }
    158 
    159 
    160 TEST(HToNNToH) {
    161   uint16_t x = 1234;
    162   CHECK_EQ(x, Socket::NToH(Socket::HToN(x)));
    163 
    164   uint32_t y = 12345678;
    165   CHECK(y == Socket::NToH(Socket::HToN(y)));
    166 }
    167