Added an unittest for udp_socket_wrapper.
This involves checking what the reasonable call sequences for deleting a socket is; documented the API for this by making the destructor protected. Checked out that the behaviour of undeleted sockets is inconsistent across platforms, and changed the udp_socket_manager_unittest accordingly. BUG= TEST= Review URL: https://webrtc-codereview.appspot.com/578007 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2236 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
f6ec0a91a2
commit
93116ba4fc
@ -18,15 +18,18 @@
|
||||
#include "udp_socket_wrapper.h"
|
||||
#include "udp_socket_manager_wrapper.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "src/system_wrappers/interface/trace.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
TEST(UdpSocketManager, CreateCallsInitAndDoesNotLeakMemory) {
|
||||
WebRtc_Word32 id = 42;
|
||||
WebRtc_UWord8 threads = 1;
|
||||
webrtc::UdpSocketManager* mgr = webrtc::UdpSocketManager::Create(id, threads);
|
||||
UdpSocketManager* mgr = UdpSocketManager::Create(id, threads);
|
||||
// Create is supposed to have called init on the object.
|
||||
EXPECT_EQ(false, mgr->Init(id, threads))
|
||||
<< "Init should return false since Create is supposed to call it.";
|
||||
webrtc::UdpSocketManager::Return();
|
||||
UdpSocketManager::Return();
|
||||
}
|
||||
|
||||
// Creates a socket and adds it to the socket manager, and then removes it
|
||||
@ -34,28 +37,34 @@ TEST(UdpSocketManager, CreateCallsInitAndDoesNotLeakMemory) {
|
||||
TEST(UdpSocketManager, AddAndRemoveSocketDoesNotLeakMemory) {
|
||||
WebRtc_Word32 id = 42;
|
||||
WebRtc_UWord8 threads = 1;
|
||||
webrtc::UdpSocketManager* mgr = webrtc::UdpSocketManager::Create(id, threads);
|
||||
webrtc::UdpSocketWrapper* socket
|
||||
= webrtc::UdpSocketWrapper::CreateSocket(id,
|
||||
mgr,
|
||||
NULL, // CallbackObj
|
||||
NULL, // IncomingSocketCallback
|
||||
false, // ipV6Enable
|
||||
false); // disableGQOS
|
||||
UdpSocketManager* mgr = UdpSocketManager::Create(id, threads);
|
||||
UdpSocketWrapper* socket
|
||||
= UdpSocketWrapper::CreateSocket(id,
|
||||
mgr,
|
||||
NULL, // CallbackObj
|
||||
NULL, // IncomingSocketCallback
|
||||
false, // ipV6Enable
|
||||
false); // disableGQOS
|
||||
// The constructor will do AddSocket on the manager.
|
||||
// RemoveSocket indirectly calls Delete.
|
||||
EXPECT_EQ(true, mgr->RemoveSocket(socket));
|
||||
webrtc::UdpSocketManager::Return();
|
||||
UdpSocketManager::Return();
|
||||
}
|
||||
|
||||
// Creates a socket and add it to the socket manager, but does not remove it
|
||||
// before destroying the socket manager.
|
||||
// This should also destroy the socket.
|
||||
TEST(UdpSocketManager, DISABLED_UnremovedSocketsGetCollectedAtManagerDeletion) {
|
||||
// On Posix, this destroys the socket.
|
||||
// On Winsock2 Windows, it enters an infinite wait for all the sockets
|
||||
// to go away.
|
||||
TEST(UdpSocketManager, UnremovedSocketsGetCollectedAtManagerDeletion) {
|
||||
#if defined(_WIN32)
|
||||
// It's hard to test an infinite wait, so we don't.
|
||||
#else
|
||||
WebRtc_Word32 id = 42;
|
||||
WebRtc_UWord8 threads = 1;
|
||||
webrtc::UdpSocketManager* mgr = webrtc::UdpSocketManager::Create(id, threads);
|
||||
webrtc::UdpSocketWrapper* unused_socket
|
||||
= webrtc::UdpSocketWrapper::CreateSocket(id,
|
||||
UdpSocketManager* mgr = UdpSocketManager::Create(id, threads);
|
||||
UdpSocketWrapper* unused_socket
|
||||
= UdpSocketWrapper::CreateSocket(id,
|
||||
mgr,
|
||||
NULL, // CallbackObj
|
||||
NULL, // IncomingSocketCallback
|
||||
@ -63,5 +72,8 @@ TEST(UdpSocketManager, DISABLED_UnremovedSocketsGetCollectedAtManagerDeletion) {
|
||||
false); // disableGQOS
|
||||
// The constructor will do AddSocket on the manager.
|
||||
unused_socket = NULL;
|
||||
webrtc::UdpSocketManager::Return();
|
||||
UdpSocketManager::Return();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
@ -40,7 +40,6 @@ typedef void(*IncomingSocketCallback)(CallbackObj obj, const WebRtc_Word8* buf,
|
||||
class UdpSocketWrapper
|
||||
{
|
||||
public:
|
||||
virtual ~UdpSocketWrapper();
|
||||
static UdpSocketWrapper* CreateSocket(const WebRtc_Word32 id,
|
||||
UdpSocketManager* mgr,
|
||||
CallbackObj obj,
|
||||
@ -97,7 +96,10 @@ public:
|
||||
virtual WebRtc_UWord32 ReceiveBuffers() {return 0;};
|
||||
|
||||
protected:
|
||||
// Creating the socket is done via CreateSocket().
|
||||
UdpSocketWrapper();
|
||||
// Destroying the socket is done via CloseBlocking().
|
||||
virtual ~UdpSocketWrapper();
|
||||
|
||||
bool _wantsIncoming;
|
||||
EventWrapper* _deleteEvent;
|
||||
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
// Tests for the UdpSocketWrapper interface.
|
||||
// This will test the UdpSocket implementations on various platforms.
|
||||
// Note that this test is using a real SocketManager, which starts up
|
||||
// an extra worker thread, making the testing more complex than it
|
||||
// should be.
|
||||
// This is because on Posix, the CloseBlocking function waits for the
|
||||
// ReadyForDeletion function to be called, which has to be called after
|
||||
// CloseBlocking, and thus has to be called from another thread.
|
||||
// The manager is the one actually doing the deleting.
|
||||
// This is done differently in the Winsock2 code, but that code
|
||||
// will also hang if the destructor is called directly.
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "modules/udp_transport/source/udp_socket_wrapper.h"
|
||||
#include "modules/udp_transport/source/udp_socket_manager_wrapper.h"
|
||||
#include "system_wrappers/interface/trace.h"
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
const int kLogTrace = 0;
|
||||
|
||||
class TestTraceCallback: public TraceCallback {
|
||||
public:
|
||||
void Print(const TraceLevel level,
|
||||
const char *traceString,
|
||||
const int length) {
|
||||
if (traceString) {
|
||||
char* tmp = new char[length+1];
|
||||
memcpy(tmp, traceString, length);
|
||||
tmp[length] = '\0';
|
||||
printf("%s\n", tmp);
|
||||
fflush(stdout);
|
||||
delete[] tmp;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class MockSocketManager : public UdpSocketManager {
|
||||
public:
|
||||
MockSocketManager() {}
|
||||
// Access to protected destructor.
|
||||
void Destroy() {
|
||||
delete this;
|
||||
}
|
||||
MOCK_METHOD2(Init, bool(WebRtc_Word32, WebRtc_UWord8&));
|
||||
MOCK_METHOD1(ChangeUniqueId, WebRtc_Word32(const WebRtc_Word32));
|
||||
MOCK_METHOD0(Start, bool());
|
||||
MOCK_METHOD0(Stop, bool());
|
||||
MOCK_METHOD1(AddSocket, bool(webrtc::UdpSocketWrapper*));
|
||||
MOCK_METHOD1(RemoveSocket, bool(webrtc::UdpSocketWrapper*));
|
||||
};
|
||||
|
||||
// Creates a socket using the static constructor method and verifies that
|
||||
// it's added to the socket manager.
|
||||
TEST(UdpSocketWrapper, CreateSocket) {
|
||||
TestTraceCallback trace;
|
||||
if (kLogTrace) {
|
||||
Trace::CreateTrace();
|
||||
Trace::SetLevelFilter(webrtc::kTraceAll);
|
||||
Trace::SetTraceCallback(&trace);
|
||||
}
|
||||
|
||||
WebRtc_Word32 id = 42;
|
||||
// We can't test deletion of sockets without a socket manager.
|
||||
WebRtc_UWord8 threads = 1;
|
||||
UdpSocketManager* mgr = UdpSocketManager::Create(id, threads);
|
||||
WEBRTC_TRACE(kTraceMemory, kTraceTransport, 42,
|
||||
"Test trace call");
|
||||
|
||||
UdpSocketWrapper* socket
|
||||
= UdpSocketWrapper::CreateSocket(id,
|
||||
mgr,
|
||||
NULL, // CallbackObj
|
||||
NULL, // IncomingSocketCallback
|
||||
false, // ipV6Enable
|
||||
false); // disableGQOS
|
||||
socket->CloseBlocking();
|
||||
UdpSocketManager::Return();
|
||||
if (kLogTrace) {
|
||||
Trace::ReturnTrace();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
@ -108,6 +108,7 @@
|
||||
'sources': [
|
||||
'udp_transport_unittest.cc',
|
||||
'udp_socket_manager_unittest.cc',
|
||||
'udp_socket_wrapper_unittest.cc',
|
||||
],
|
||||
}, # udp_transport_unittests
|
||||
], # targets
|
||||
|
Loading…
x
Reference in New Issue
Block a user