test_utils.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. * Copyright 2004 The WebRTC Project Authors. All rights reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef RTC_BASE_TEST_UTILS_H_
  11. #define RTC_BASE_TEST_UTILS_H_
  12. // Utilities for testing rtc infrastructure in unittests
  13. #include <map>
  14. #include <utility>
  15. #include "rtc_base/async_socket.h"
  16. #include "rtc_base/stream.h"
  17. #include "rtc_base/third_party/sigslot/sigslot.h"
  18. namespace webrtc {
  19. namespace testing {
  20. ///////////////////////////////////////////////////////////////////////////////
  21. // StreamSink - Monitor asynchronously signalled events from StreamInterface
  22. // or AsyncSocket (which should probably be a StreamInterface.
  23. ///////////////////////////////////////////////////////////////////////////////
  24. // Note: Any event that is an error is treaded as SSE_ERROR instead of that
  25. // event.
  26. enum StreamSinkEvent {
  27. SSE_OPEN = rtc::SE_OPEN,
  28. SSE_READ = rtc::SE_READ,
  29. SSE_WRITE = rtc::SE_WRITE,
  30. SSE_CLOSE = rtc::SE_CLOSE,
  31. SSE_ERROR = 16
  32. };
  33. class StreamSink : public sigslot::has_slots<> {
  34. public:
  35. StreamSink();
  36. ~StreamSink() override;
  37. void Monitor(rtc::StreamInterface* stream) {
  38. stream->SignalEvent.connect(this, &StreamSink::OnEvent);
  39. events_.erase(stream);
  40. }
  41. void Unmonitor(rtc::StreamInterface* stream) {
  42. stream->SignalEvent.disconnect(this);
  43. // In case you forgot to unmonitor a previous object with this address
  44. events_.erase(stream);
  45. }
  46. bool Check(rtc::StreamInterface* stream,
  47. StreamSinkEvent event,
  48. bool reset = true) {
  49. return DoCheck(stream, event, reset);
  50. }
  51. int Events(rtc::StreamInterface* stream, bool reset = true) {
  52. return DoEvents(stream, reset);
  53. }
  54. void Monitor(rtc::AsyncSocket* socket) {
  55. socket->SignalConnectEvent.connect(this, &StreamSink::OnConnectEvent);
  56. socket->SignalReadEvent.connect(this, &StreamSink::OnReadEvent);
  57. socket->SignalWriteEvent.connect(this, &StreamSink::OnWriteEvent);
  58. socket->SignalCloseEvent.connect(this, &StreamSink::OnCloseEvent);
  59. // In case you forgot to unmonitor a previous object with this address
  60. events_.erase(socket);
  61. }
  62. void Unmonitor(rtc::AsyncSocket* socket) {
  63. socket->SignalConnectEvent.disconnect(this);
  64. socket->SignalReadEvent.disconnect(this);
  65. socket->SignalWriteEvent.disconnect(this);
  66. socket->SignalCloseEvent.disconnect(this);
  67. events_.erase(socket);
  68. }
  69. bool Check(rtc::AsyncSocket* socket,
  70. StreamSinkEvent event,
  71. bool reset = true) {
  72. return DoCheck(socket, event, reset);
  73. }
  74. int Events(rtc::AsyncSocket* socket, bool reset = true) {
  75. return DoEvents(socket, reset);
  76. }
  77. private:
  78. typedef std::map<void*, int> EventMap;
  79. void OnEvent(rtc::StreamInterface* stream, int events, int error) {
  80. if (error) {
  81. events = SSE_ERROR;
  82. }
  83. AddEvents(stream, events);
  84. }
  85. void OnConnectEvent(rtc::AsyncSocket* socket) { AddEvents(socket, SSE_OPEN); }
  86. void OnReadEvent(rtc::AsyncSocket* socket) { AddEvents(socket, SSE_READ); }
  87. void OnWriteEvent(rtc::AsyncSocket* socket) { AddEvents(socket, SSE_WRITE); }
  88. void OnCloseEvent(rtc::AsyncSocket* socket, int error) {
  89. AddEvents(socket, (0 == error) ? SSE_CLOSE : SSE_ERROR);
  90. }
  91. void AddEvents(void* obj, int events) {
  92. EventMap::iterator it = events_.find(obj);
  93. if (events_.end() == it) {
  94. events_.insert(EventMap::value_type(obj, events));
  95. } else {
  96. it->second |= events;
  97. }
  98. }
  99. bool DoCheck(void* obj, StreamSinkEvent event, bool reset) {
  100. EventMap::iterator it = events_.find(obj);
  101. if ((events_.end() == it) || (0 == (it->second & event))) {
  102. return false;
  103. }
  104. if (reset) {
  105. it->second &= ~event;
  106. }
  107. return true;
  108. }
  109. int DoEvents(void* obj, bool reset) {
  110. EventMap::iterator it = events_.find(obj);
  111. if (events_.end() == it)
  112. return 0;
  113. int events = it->second;
  114. if (reset) {
  115. it->second = 0;
  116. }
  117. return events;
  118. }
  119. EventMap events_;
  120. };
  121. } // namespace testing
  122. } // namespace webrtc
  123. #endif // RTC_BASE_TEST_UTILS_H_