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 11 #ifndef RTC_BASE_TEST_UTILS_H_ 12 #define RTC_BASE_TEST_UTILS_H_ 13 14 // Utilities for testing rtc infrastructure in unittests 15 16 #include <map> 17 #include <utility> 18 19 #include "rtc_base/socket.h" 20 #include "rtc_base/third_party/sigslot/sigslot.h" 21 22 namespace webrtc { 23 namespace testing { 24 25 /////////////////////////////////////////////////////////////////////////////// 26 // StreamSink - Monitor asynchronously signalled events from Socket. 27 /////////////////////////////////////////////////////////////////////////////// 28 29 // Note: Any event that is an error is treated as SSE_ERROR instead of that 30 // event. 31 32 enum StreamSinkEvent { 33 SSE_OPEN = 1, 34 SSE_READ = 2, 35 SSE_WRITE = 4, 36 SSE_CLOSE = 8, 37 SSE_ERROR = 16 38 }; 39 40 class StreamSink : public sigslot::has_slots<> { 41 public: 42 StreamSink(); 43 ~StreamSink() override; 44 Monitor(rtc::Socket * socket)45 void Monitor(rtc::Socket* socket) { 46 socket->SignalConnectEvent.connect(this, &StreamSink::OnConnectEvent); 47 socket->SignalReadEvent.connect(this, &StreamSink::OnReadEvent); 48 socket->SignalWriteEvent.connect(this, &StreamSink::OnWriteEvent); 49 socket->SignalCloseEvent.connect(this, &StreamSink::OnCloseEvent); 50 // In case you forgot to unmonitor a previous object with this address 51 events_.erase(socket); 52 } Unmonitor(rtc::Socket * socket)53 void Unmonitor(rtc::Socket* socket) { 54 socket->SignalConnectEvent.disconnect(this); 55 socket->SignalReadEvent.disconnect(this); 56 socket->SignalWriteEvent.disconnect(this); 57 socket->SignalCloseEvent.disconnect(this); 58 events_.erase(socket); 59 } 60 bool Check(rtc::Socket* socket, StreamSinkEvent event, bool reset = true) { 61 return DoCheck(socket, event, reset); 62 } 63 64 private: 65 typedef std::map<rtc::Socket*, int> EventMap; 66 OnConnectEvent(rtc::Socket * socket)67 void OnConnectEvent(rtc::Socket* socket) { AddEvents(socket, SSE_OPEN); } OnReadEvent(rtc::Socket * socket)68 void OnReadEvent(rtc::Socket* socket) { AddEvents(socket, SSE_READ); } OnWriteEvent(rtc::Socket * socket)69 void OnWriteEvent(rtc::Socket* socket) { AddEvents(socket, SSE_WRITE); } OnCloseEvent(rtc::Socket * socket,int error)70 void OnCloseEvent(rtc::Socket* socket, int error) { 71 AddEvents(socket, (0 == error) ? SSE_CLOSE : SSE_ERROR); 72 } 73 AddEvents(rtc::Socket * obj,int events)74 void AddEvents(rtc::Socket* obj, int events) { 75 EventMap::iterator it = events_.find(obj); 76 if (events_.end() == it) { 77 events_.insert(EventMap::value_type(obj, events)); 78 } else { 79 it->second |= events; 80 } 81 } DoCheck(rtc::Socket * obj,StreamSinkEvent event,bool reset)82 bool DoCheck(rtc::Socket* obj, StreamSinkEvent event, bool reset) { 83 EventMap::iterator it = events_.find(obj); 84 if ((events_.end() == it) || (0 == (it->second & event))) { 85 return false; 86 } 87 if (reset) { 88 it->second &= ~event; 89 } 90 return true; 91 } 92 93 EventMap events_; 94 }; 95 96 } // namespace testing 97 } // namespace webrtc 98 99 #endif // RTC_BASE_TEST_UTILS_H_ 100