Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / base / testutils.h
1 /*
2  * libjingle
3  * Copyright 2004--2011, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #ifndef TALK_BASE_TESTUTILS_H__
29 #define TALK_BASE_TESTUTILS_H__
30
31 // Utilities for testing talk_base infrastructure in unittests
32
33 #ifdef LINUX
34 #include <X11/Xlib.h>
35 #include <X11/extensions/Xrandr.h>
36
37 // X defines a few macros that stomp on types that gunit.h uses.
38 #undef None
39 #undef Bool
40 #endif
41
42 #include <map>
43 #include <vector>
44 #include "talk/base/asyncsocket.h"
45 #include "talk/base/common.h"
46 #include "talk/base/gunit.h"
47 #include "talk/base/nethelpers.h"
48 #include "talk/base/stream.h"
49 #include "talk/base/stringencode.h"
50 #include "talk/base/stringutils.h"
51 #include "talk/base/thread.h"
52
53 namespace testing {
54
55 using namespace talk_base;
56
57 ///////////////////////////////////////////////////////////////////////////////
58 // StreamSink - Monitor asynchronously signalled events from StreamInterface
59 // or AsyncSocket (which should probably be a StreamInterface.
60 ///////////////////////////////////////////////////////////////////////////////
61
62 // Note: Any event that is an error is treaded as SSE_ERROR instead of that
63 // event.
64
65 enum StreamSinkEvent {
66   SSE_OPEN  = SE_OPEN,
67   SSE_READ  = SE_READ,
68   SSE_WRITE = SE_WRITE,
69   SSE_CLOSE = SE_CLOSE,
70   SSE_ERROR = 16
71 };
72
73 class StreamSink : public sigslot::has_slots<> {
74  public:
75   void Monitor(StreamInterface* stream) {
76    stream->SignalEvent.connect(this, &StreamSink::OnEvent);
77    events_.erase(stream);
78   }
79   void Unmonitor(StreamInterface* stream) {
80    stream->SignalEvent.disconnect(this);
81    // In case you forgot to unmonitor a previous object with this address
82    events_.erase(stream);
83   }
84   bool Check(StreamInterface* stream, StreamSinkEvent event, bool reset = true) {
85     return DoCheck(stream, event, reset);
86   }
87   int Events(StreamInterface* stream, bool reset = true) {
88     return DoEvents(stream, reset);
89   }
90
91   void Monitor(AsyncSocket* socket) {
92    socket->SignalConnectEvent.connect(this, &StreamSink::OnConnectEvent);
93    socket->SignalReadEvent.connect(this, &StreamSink::OnReadEvent);
94    socket->SignalWriteEvent.connect(this, &StreamSink::OnWriteEvent);
95    socket->SignalCloseEvent.connect(this, &StreamSink::OnCloseEvent);
96    // In case you forgot to unmonitor a previous object with this address
97    events_.erase(socket);
98   }
99   void Unmonitor(AsyncSocket* socket) {
100    socket->SignalConnectEvent.disconnect(this);
101    socket->SignalReadEvent.disconnect(this);
102    socket->SignalWriteEvent.disconnect(this);
103    socket->SignalCloseEvent.disconnect(this);
104    events_.erase(socket);
105   }
106   bool Check(AsyncSocket* socket, StreamSinkEvent event, bool reset = true) {
107     return DoCheck(socket, event, reset);
108   }
109   int Events(AsyncSocket* socket, bool reset = true) {
110     return DoEvents(socket, reset);
111   }
112
113  private:
114   typedef std::map<void*,int> EventMap;
115
116   void OnEvent(StreamInterface* stream, int events, int error) {
117     if (error) {
118       events = SSE_ERROR;
119     }
120     AddEvents(stream, events);
121   }
122   void OnConnectEvent(AsyncSocket* socket) {
123     AddEvents(socket, SSE_OPEN);
124   }
125   void OnReadEvent(AsyncSocket* socket) {
126     AddEvents(socket, SSE_READ);
127   }
128   void OnWriteEvent(AsyncSocket* socket) {
129     AddEvents(socket, SSE_WRITE);
130   }
131   void OnCloseEvent(AsyncSocket* socket, int error) {
132     AddEvents(socket, (0 == error) ? SSE_CLOSE : SSE_ERROR);
133   }
134
135   void AddEvents(void* obj, int events) {
136     EventMap::iterator it = events_.find(obj);
137     if (events_.end() == it) {
138       events_.insert(EventMap::value_type(obj, events));
139     } else {
140       it->second |= events;
141     }
142   }
143   bool DoCheck(void* obj, StreamSinkEvent event, bool reset) {
144     EventMap::iterator it = events_.find(obj);
145     if ((events_.end() == it) || (0 == (it->second & event))) {
146       return false;
147     }
148     if (reset) {
149       it->second &= ~event;
150     }
151     return true;
152   }
153   int DoEvents(void* obj, bool reset) {
154     EventMap::iterator it = events_.find(obj);
155     if (events_.end() == it)
156       return 0;
157     int events = it->second;
158     if (reset) {
159       it->second = 0;
160     }
161     return events;
162   }
163
164   EventMap events_;
165 };
166
167 ///////////////////////////////////////////////////////////////////////////////
168 // StreamSource - Implements stream interface and simulates asynchronous
169 // events on the stream, without a network.  Also buffers written data.
170 ///////////////////////////////////////////////////////////////////////////////
171
172 class StreamSource : public StreamInterface {
173 public:
174   StreamSource() {
175     Clear();
176   }
177
178   void Clear() {
179     readable_data_.clear();
180     written_data_.clear();
181     state_ = SS_CLOSED;
182     read_block_ = 0;
183     write_block_ = SIZE_UNKNOWN;
184   }
185   void QueueString(const char* data) {
186     QueueData(data, strlen(data));
187   }
188   void QueueStringF(const char* format, ...) {
189     va_list args;
190     va_start(args, format);
191     char buffer[1024];
192     size_t len = vsprintfn(buffer, sizeof(buffer), format, args);
193     ASSERT(len < sizeof(buffer) - 1);
194     va_end(args);
195     QueueData(buffer, len);
196   }
197   void QueueData(const char* data, size_t len) {
198     readable_data_.insert(readable_data_.end(), data, data + len);
199     if ((SS_OPEN == state_) && (readable_data_.size() == len)) {
200       SignalEvent(this, SE_READ, 0);
201     }
202   }
203   std::string ReadData() {
204     std::string data;
205     // avoid accessing written_data_[0] if it is undefined
206     if (written_data_.size() > 0) {
207       data.insert(0, &written_data_[0], written_data_.size());
208     }
209     written_data_.clear();
210     return data;
211   }
212   void SetState(StreamState state) {
213     int events = 0;
214     if ((SS_OPENING == state_) && (SS_OPEN == state)) {
215       events |= SE_OPEN;
216       if (!readable_data_.empty()) {
217         events |= SE_READ;
218       }
219     } else if ((SS_CLOSED != state_) && (SS_CLOSED == state)) {
220       events |= SE_CLOSE;
221     }
222     state_ = state;
223     if (events) {
224       SignalEvent(this, events, 0);
225     }
226   }
227   // Will cause Read to block when there are pos bytes in the read queue.
228   void SetReadBlock(size_t pos) { read_block_ = pos; }
229   // Will cause Write to block when there are pos bytes in the write queue.
230   void SetWriteBlock(size_t pos) { write_block_ = pos; }
231
232   virtual StreamState GetState() const { return state_; }
233   virtual StreamResult Read(void* buffer, size_t buffer_len,
234                             size_t* read, int* error) {
235     if (SS_CLOSED == state_) {
236       if (error) *error = -1;
237       return SR_ERROR;
238     }
239     if ((SS_OPENING == state_) || (readable_data_.size() <= read_block_)) {
240       return SR_BLOCK;
241     }
242     size_t count = _min(buffer_len, readable_data_.size() - read_block_);
243     memcpy(buffer, &readable_data_[0], count);
244     size_t new_size = readable_data_.size() - count;
245     // Avoid undefined access beyond the last element of the vector.
246     // This only happens when new_size is 0.
247     if (count < readable_data_.size()) {
248       memmove(&readable_data_[0], &readable_data_[count], new_size);
249     }
250     readable_data_.resize(new_size);
251     if (read) *read = count;
252     return SR_SUCCESS;
253   }
254   virtual StreamResult Write(const void* data, size_t data_len,
255                              size_t* written, int* error) {
256     if (SS_CLOSED == state_) {
257       if (error) *error = -1;
258       return SR_ERROR;
259     }
260     if (SS_OPENING == state_) {
261       return SR_BLOCK;
262     }
263     if (SIZE_UNKNOWN != write_block_) {
264       if (written_data_.size() >= write_block_) {
265         return SR_BLOCK;
266       }
267       if (data_len > (write_block_ - written_data_.size())) {
268         data_len = write_block_ - written_data_.size();
269       }
270     }
271     if (written) *written = data_len;
272     const char* cdata = static_cast<const char*>(data);
273     written_data_.insert(written_data_.end(), cdata, cdata + data_len);
274     return SR_SUCCESS;
275   }
276   virtual void Close() { state_ = SS_CLOSED; }
277
278 private:
279   typedef std::vector<char> Buffer;
280   Buffer readable_data_, written_data_;
281   StreamState state_;
282   size_t read_block_, write_block_;
283 };
284
285 ///////////////////////////////////////////////////////////////////////////////
286 // SocketTestClient
287 // Creates a simulated client for testing.  Works on real and virtual networks.
288 ///////////////////////////////////////////////////////////////////////////////
289
290 class SocketTestClient : public sigslot::has_slots<> {
291 public:
292   SocketTestClient() {
293     Init(NULL, AF_INET);
294   }
295   SocketTestClient(AsyncSocket* socket) {
296     Init(socket, socket->GetLocalAddress().family());
297   }
298   SocketTestClient(const SocketAddress& address) {
299     Init(NULL, address.family());
300     socket_->Connect(address);
301   }
302
303   AsyncSocket* socket() { return socket_.get(); }
304
305   void QueueString(const char* data) {
306     QueueData(data, strlen(data));
307   }
308   void QueueStringF(const char* format, ...) {
309     va_list args;
310     va_start(args, format);
311     char buffer[1024];
312     size_t len = vsprintfn(buffer, sizeof(buffer), format, args);
313     ASSERT(len < sizeof(buffer) - 1);
314     va_end(args);
315     QueueData(buffer, len);
316   }
317   void QueueData(const char* data, size_t len) {
318     send_buffer_.insert(send_buffer_.end(), data, data + len);
319     if (Socket::CS_CONNECTED == socket_->GetState()) {
320       Flush();
321     }
322   }
323   std::string ReadData() {
324     std::string data(&recv_buffer_[0], recv_buffer_.size());
325     recv_buffer_.clear();
326     return data;
327   }
328
329   bool IsConnected() const {
330     return (Socket::CS_CONNECTED == socket_->GetState());
331   }
332   bool IsClosed() const {
333     return (Socket::CS_CLOSED == socket_->GetState());
334   }
335
336 private:
337   typedef std::vector<char> Buffer;
338
339   void Init(AsyncSocket* socket, int family) {
340     if (!socket) {
341       socket = Thread::Current()->socketserver()
342           ->CreateAsyncSocket(family, SOCK_STREAM);
343     }
344     socket_.reset(socket);
345     socket_->SignalConnectEvent.connect(this,
346       &SocketTestClient::OnConnectEvent);
347     socket_->SignalReadEvent.connect(this, &SocketTestClient::OnReadEvent);
348     socket_->SignalWriteEvent.connect(this, &SocketTestClient::OnWriteEvent);
349     socket_->SignalCloseEvent.connect(this, &SocketTestClient::OnCloseEvent);
350   }
351
352   void Flush() {
353     size_t sent = 0;
354     while (sent < send_buffer_.size()) {
355       int result = socket_->Send(&send_buffer_[sent],
356                                  send_buffer_.size() - sent);
357       if (result > 0) {
358         sent += result;
359       } else {
360         break;
361       }
362     }
363     size_t new_size = send_buffer_.size() - sent;
364     memmove(&send_buffer_[0], &send_buffer_[sent], new_size);
365     send_buffer_.resize(new_size);
366   }
367
368   void OnConnectEvent(AsyncSocket* socket) {
369     if (!send_buffer_.empty()) {
370       Flush();
371     }
372   }
373   void OnReadEvent(AsyncSocket* socket) {
374     char data[64 * 1024];
375     int result = socket_->Recv(data, ARRAY_SIZE(data));
376     if (result > 0) {
377       recv_buffer_.insert(recv_buffer_.end(), data, data + result);
378     }
379   }
380   void OnWriteEvent(AsyncSocket* socket) {
381     if (!send_buffer_.empty()) {
382       Flush();
383     }
384   }
385   void OnCloseEvent(AsyncSocket* socket, int error) {
386   }
387
388   scoped_ptr<AsyncSocket> socket_;
389   Buffer send_buffer_, recv_buffer_;
390 };
391
392 ///////////////////////////////////////////////////////////////////////////////
393 // SocketTestServer
394 // Creates a simulated server for testing.  Works on real and virtual networks.
395 ///////////////////////////////////////////////////////////////////////////////
396
397 class SocketTestServer : public sigslot::has_slots<> {
398  public:
399   SocketTestServer(const SocketAddress& address)
400       : socket_(Thread::Current()->socketserver()
401                 ->CreateAsyncSocket(address.family(), SOCK_STREAM))
402   {
403     socket_->SignalReadEvent.connect(this, &SocketTestServer::OnReadEvent);
404     socket_->Bind(address);
405     socket_->Listen(5);
406   }
407   virtual ~SocketTestServer() {
408     clear();
409   }
410
411   size_t size() const { return clients_.size(); }
412   SocketTestClient* client(size_t index) const { return clients_[index]; }
413   SocketTestClient* operator[](size_t index) const { return client(index); }
414
415   void clear() {
416     for (size_t i=0; i<clients_.size(); ++i) {
417       delete clients_[i];
418     }
419     clients_.clear();
420   }
421
422  private:
423   void OnReadEvent(AsyncSocket* socket) {
424     AsyncSocket* accepted =
425       static_cast<AsyncSocket*>(socket_->Accept(NULL));
426     if (!accepted)
427       return;
428     clients_.push_back(new SocketTestClient(accepted));
429   }
430
431   scoped_ptr<AsyncSocket> socket_;
432   std::vector<SocketTestClient*> clients_;
433 };
434
435 ///////////////////////////////////////////////////////////////////////////////
436 // Generic Utilities
437 ///////////////////////////////////////////////////////////////////////////////
438
439 inline bool ReadFile(const char* filename, std::string* contents) {
440   FILE* fp = fopen(filename, "rb");
441   if (!fp)
442     return false;
443   char buffer[1024*64];
444   size_t read;
445   contents->clear();
446   while ((read = fread(buffer, 1, sizeof(buffer), fp))) {
447     contents->append(buffer, read);
448   }
449   bool success = (0 != feof(fp));
450   fclose(fp);
451   return success;
452 }
453
454 ///////////////////////////////////////////////////////////////////////////////
455 // Unittest predicates which are similar to STREQ, but for raw memory
456 ///////////////////////////////////////////////////////////////////////////////
457
458 inline AssertionResult CmpHelperMemEq(const char* expected_expression,
459                                       const char* expected_length_expression,
460                                       const char* actual_expression,
461                                       const char* actual_length_expression,
462                                       const void* expected,
463                                       size_t expected_length,
464                                       const void* actual,
465                                       size_t actual_length)
466 {
467   if ((expected_length == actual_length)
468       && (0 == memcmp(expected, actual, expected_length))) {
469     return AssertionSuccess();
470   }
471
472   Message msg;
473   msg << "Value of: " << actual_expression
474       << " [" << actual_length_expression << "]";
475   if (true) {  //!actual_value.Equals(actual_expression)) {
476     size_t buffer_size = actual_length * 2 + 1;
477     char* buffer = STACK_ARRAY(char, buffer_size);
478     hex_encode(buffer, buffer_size,
479                reinterpret_cast<const char*>(actual), actual_length);
480     msg << "\n  Actual: " << buffer << " [" << actual_length << "]";
481   }
482
483   msg << "\nExpected: " << expected_expression
484       << " [" << expected_length_expression << "]";
485   if (true) {  //!expected_value.Equals(expected_expression)) {
486     size_t buffer_size = expected_length * 2 + 1;
487     char* buffer = STACK_ARRAY(char, buffer_size);
488     hex_encode(buffer, buffer_size,
489                reinterpret_cast<const char*>(expected), expected_length);
490     msg << "\nWhich is: " << buffer << " [" << expected_length << "]";
491   }
492
493   return AssertionFailure(msg);
494 }
495
496 inline AssertionResult CmpHelperFileEq(const char* expected_expression,
497                                        const char* expected_length_expression,
498                                        const char* actual_filename,
499                                        const void* expected,
500                                        size_t expected_length,
501                                        const char* filename)
502 {
503   std::string contents;
504   if (!ReadFile(filename, &contents)) {
505     Message msg;
506     msg << "File '" << filename << "' could not be read.";
507     return AssertionFailure(msg);
508   }
509   return CmpHelperMemEq(expected_expression, expected_length_expression,
510                         actual_filename, "",
511                         expected, expected_length,
512                         contents.c_str(), contents.size());
513 }
514
515 #define EXPECT_MEMEQ(expected, expected_length, actual, actual_length) \
516   EXPECT_PRED_FORMAT4(::testing::CmpHelperMemEq, expected, expected_length, \
517                       actual, actual_length)
518
519 #define ASSERT_MEMEQ(expected, expected_length, actual, actual_length) \
520   ASSERT_PRED_FORMAT4(::testing::CmpHelperMemEq, expected, expected_length, \
521                       actual, actual_length)
522
523 #define EXPECT_FILEEQ(expected, expected_length, filename) \
524   EXPECT_PRED_FORMAT3(::testing::CmpHelperFileEq, expected, expected_length, \
525                       filename)
526
527 #define ASSERT_FILEEQ(expected, expected_length, filename) \
528   ASSERT_PRED_FORMAT3(::testing::CmpHelperFileEq, expected, expected_length, \
529                       filename)
530
531 ///////////////////////////////////////////////////////////////////////////////
532 // Helpers for initializing constant memory with integers in a particular byte
533 // order
534 ///////////////////////////////////////////////////////////////////////////////
535
536 #define BYTE_CAST(x) static_cast<uint8>((x) & 0xFF)
537
538 // Declare a N-bit integer as a little-endian sequence of bytes
539 #define LE16(x) BYTE_CAST(((uint16)x) >>  0), BYTE_CAST(((uint16)x) >>  8)
540
541 #define LE32(x) BYTE_CAST(((uint32)x) >>  0), BYTE_CAST(((uint32)x) >>  8), \
542                 BYTE_CAST(((uint32)x) >> 16), BYTE_CAST(((uint32)x) >> 24)
543
544 #define LE64(x) BYTE_CAST(((uint64)x) >>  0), BYTE_CAST(((uint64)x) >>  8), \
545                 BYTE_CAST(((uint64)x) >> 16), BYTE_CAST(((uint64)x) >> 24), \
546                 BYTE_CAST(((uint64)x) >> 32), BYTE_CAST(((uint64)x) >> 40), \
547                 BYTE_CAST(((uint64)x) >> 48), BYTE_CAST(((uint64)x) >> 56)
548
549 // Declare a N-bit integer as a big-endian (Internet) sequence of bytes
550 #define BE16(x) BYTE_CAST(((uint16)x) >>  8), BYTE_CAST(((uint16)x) >>  0)
551
552 #define BE32(x) BYTE_CAST(((uint32)x) >> 24), BYTE_CAST(((uint32)x) >> 16), \
553                 BYTE_CAST(((uint32)x) >>  8), BYTE_CAST(((uint32)x) >>  0)
554
555 #define BE64(x) BYTE_CAST(((uint64)x) >> 56), BYTE_CAST(((uint64)x) >> 48), \
556                 BYTE_CAST(((uint64)x) >> 40), BYTE_CAST(((uint64)x) >> 32), \
557                 BYTE_CAST(((uint64)x) >> 24), BYTE_CAST(((uint64)x) >> 16), \
558                 BYTE_CAST(((uint64)x) >>  8), BYTE_CAST(((uint64)x) >>  0)
559
560 // Declare a N-bit integer as a this-endian (local machine) sequence of bytes
561 #ifndef BIG_ENDIAN
562 #define BIG_ENDIAN 1
563 #endif  // BIG_ENDIAN
564
565 #if BIG_ENDIAN
566 #define TE16 BE16
567 #define TE32 BE32
568 #define TE64 BE64
569 #else  // !BIG_ENDIAN
570 #define TE16 LE16
571 #define TE32 LE32
572 #define TE64 LE64
573 #endif  // !BIG_ENDIAN
574
575 ///////////////////////////////////////////////////////////////////////////////
576
577 // Helpers for determining if X/screencasting is available (on linux).
578
579 #define MAYBE_SKIP_SCREENCAST_TEST() \
580   if (!testing::IsScreencastingAvailable()) { \
581     LOG(LS_WARNING) << "Skipping test, since it doesn't have the requisite " \
582                     << "X environment for screen capture."; \
583     return; \
584   } \
585
586 #ifdef LINUX
587 struct XDisplay {
588   XDisplay() : display_(XOpenDisplay(NULL)) { }
589   ~XDisplay() { if (display_) XCloseDisplay(display_); }
590   bool IsValid() const { return display_ != NULL; }
591   operator Display*() { return display_; }
592  private:
593   Display* display_;
594 };
595 #endif
596
597 // Returns true if screencasting is available. When false, anything that uses
598 // screencasting features may fail.
599 inline bool IsScreencastingAvailable() {
600 #ifdef LINUX
601   XDisplay display;
602   if (!display.IsValid()) {
603     LOG(LS_WARNING) << "No X Display available.";
604     return false;
605   }
606   int ignored_int, major_version, minor_version;
607   if (!XRRQueryExtension(display, &ignored_int, &ignored_int) ||
608       !XRRQueryVersion(display, &major_version, &minor_version) ||
609       major_version < 1 ||
610       (major_version < 2 && minor_version < 3)) {
611     LOG(LS_WARNING) << "XRandr version: " << major_version << "."
612                     << minor_version;
613     LOG(LS_WARNING) << "XRandr is not supported or is too old (pre 1.3).";
614     return false;
615   }
616 #endif
617   return true;
618 }
619 }  // namespace testing
620
621 #endif  // TALK_BASE_TESTUTILS_H__