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