• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
SocketListenerThread(Isolate * isolate,int port,int data_size)13   explicit SocketListenerThread(Isolate* isolate, int port, int data_size)
14       : Thread(isolate, "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   }
~SocketListenerThread()22   ~SocketListenerThread() {
23     // Close both sockets.
24     delete client_;
25     delete server_;
26     delete listening_;
27     delete[] data_;
28   }
29 
30   void Run();
WaitForListening()31   void WaitForListening() { listening_->Wait(); }
data()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 
Run()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 
SendAll(Socket * socket,const char * data,int len)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 
SendAndReceive(int port,char * data,int len)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(Isolate::Current(),
96       port, len);
97   listener->Start();
98   listener->WaitForListening();
99 
100   // Connect and write some data.
101   Socket* client = OS::CreateSocket();
102   CHECK(client != NULL);
103   ok = client->Connect(kLocalhost, port_str);
104   CHECK(ok);
105 
106   // Send all the data.
107   ok = SendAll(client, data, len);
108   CHECK(ok);
109 
110   // Wait until data is received.
111   listener->Join();
112 
113   // Check that data received is the same as data send.
114   for (int i = 0; i < len; i++) {
115     CHECK(data[i] == listener->data()[i]);
116   }
117 
118   // Close the client before the listener to avoid TIME_WAIT issues.
119   client->Shutdown();
120   delete client;
121   delete listener;
122 }
123 
124 
TEST(Socket)125 TEST(Socket) {
126   // Make sure this port is not used by other tests to allow tests to run in
127   // parallel.
128   static const int kPort = 5859;
129 
130   bool ok;
131 
132   // Initialize socket support.
133   ok = Socket::Setup();
134   CHECK(ok);
135 
136   // Send and receive some data.
137   static const int kBufferSizeSmall = 20;
138   char small_data[kBufferSizeSmall + 1] = "1234567890abcdefghij";
139   SendAndReceive(kPort, small_data, kBufferSizeSmall);
140 
141   // Send and receive some more data.
142   static const int kBufferSizeMedium = 10000;
143   char* medium_data = new char[kBufferSizeMedium];
144   for (int i = 0; i < kBufferSizeMedium; i++) {
145     medium_data[i] = i % 256;
146   }
147   SendAndReceive(kPort, medium_data, kBufferSizeMedium);
148   delete[] medium_data;
149 
150   // Send and receive even more data.
151   static const int kBufferSizeLarge = 1000000;
152   char* large_data = new char[kBufferSizeLarge];
153   for (int i = 0; i < kBufferSizeLarge; i++) {
154     large_data[i] = i % 256;
155   }
156   SendAndReceive(kPort, large_data, kBufferSizeLarge);
157   delete[] large_data;
158 }
159 
160 
TEST(HToNNToH)161 TEST(HToNNToH) {
162   uint16_t x = 1234;
163   CHECK_EQ(x, Socket::NToH(Socket::HToN(x)));
164 
165   uint32_t y = 12345678;
166   CHECK(y == Socket::NToH(Socket::HToN(y)));
167 }
168