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