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_wrapper.h"
|
||||||
#include "udp_socket_manager_wrapper.h"
|
#include "udp_socket_manager_wrapper.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
#include "src/system_wrappers/interface/trace.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
TEST(UdpSocketManager, CreateCallsInitAndDoesNotLeakMemory) {
|
TEST(UdpSocketManager, CreateCallsInitAndDoesNotLeakMemory) {
|
||||||
WebRtc_Word32 id = 42;
|
WebRtc_Word32 id = 42;
|
||||||
WebRtc_UWord8 threads = 1;
|
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.
|
// Create is supposed to have called init on the object.
|
||||||
EXPECT_EQ(false, mgr->Init(id, threads))
|
EXPECT_EQ(false, mgr->Init(id, threads))
|
||||||
<< "Init should return false since Create is supposed to call it.";
|
<< "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
|
// Creates a socket and adds it to the socket manager, and then removes it
|
||||||
@ -34,28 +37,34 @@ TEST(UdpSocketManager, CreateCallsInitAndDoesNotLeakMemory) {
|
|||||||
TEST(UdpSocketManager, AddAndRemoveSocketDoesNotLeakMemory) {
|
TEST(UdpSocketManager, AddAndRemoveSocketDoesNotLeakMemory) {
|
||||||
WebRtc_Word32 id = 42;
|
WebRtc_Word32 id = 42;
|
||||||
WebRtc_UWord8 threads = 1;
|
WebRtc_UWord8 threads = 1;
|
||||||
webrtc::UdpSocketManager* mgr = webrtc::UdpSocketManager::Create(id, threads);
|
UdpSocketManager* mgr = UdpSocketManager::Create(id, threads);
|
||||||
webrtc::UdpSocketWrapper* socket
|
UdpSocketWrapper* socket
|
||||||
= webrtc::UdpSocketWrapper::CreateSocket(id,
|
= UdpSocketWrapper::CreateSocket(id,
|
||||||
mgr,
|
mgr,
|
||||||
NULL, // CallbackObj
|
NULL, // CallbackObj
|
||||||
NULL, // IncomingSocketCallback
|
NULL, // IncomingSocketCallback
|
||||||
false, // ipV6Enable
|
false, // ipV6Enable
|
||||||
false); // disableGQOS
|
false); // disableGQOS
|
||||||
// The constructor will do AddSocket on the manager.
|
// The constructor will do AddSocket on the manager.
|
||||||
|
// RemoveSocket indirectly calls Delete.
|
||||||
EXPECT_EQ(true, mgr->RemoveSocket(socket));
|
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
|
// Creates a socket and add it to the socket manager, but does not remove it
|
||||||
// before destroying the socket manager.
|
// before destroying the socket manager.
|
||||||
// This should also destroy the socket.
|
// On Posix, this destroys the socket.
|
||||||
TEST(UdpSocketManager, DISABLED_UnremovedSocketsGetCollectedAtManagerDeletion) {
|
// 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_Word32 id = 42;
|
||||||
WebRtc_UWord8 threads = 1;
|
WebRtc_UWord8 threads = 1;
|
||||||
webrtc::UdpSocketManager* mgr = webrtc::UdpSocketManager::Create(id, threads);
|
UdpSocketManager* mgr = UdpSocketManager::Create(id, threads);
|
||||||
webrtc::UdpSocketWrapper* unused_socket
|
UdpSocketWrapper* unused_socket
|
||||||
= webrtc::UdpSocketWrapper::CreateSocket(id,
|
= UdpSocketWrapper::CreateSocket(id,
|
||||||
mgr,
|
mgr,
|
||||||
NULL, // CallbackObj
|
NULL, // CallbackObj
|
||||||
NULL, // IncomingSocketCallback
|
NULL, // IncomingSocketCallback
|
||||||
@ -63,5 +72,8 @@ TEST(UdpSocketManager, DISABLED_UnremovedSocketsGetCollectedAtManagerDeletion) {
|
|||||||
false); // disableGQOS
|
false); // disableGQOS
|
||||||
// The constructor will do AddSocket on the manager.
|
// The constructor will do AddSocket on the manager.
|
||||||
unused_socket = NULL;
|
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
|
* 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
|
* 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
|
class UdpSocketWrapper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~UdpSocketWrapper();
|
|
||||||
static UdpSocketWrapper* CreateSocket(const WebRtc_Word32 id,
|
static UdpSocketWrapper* CreateSocket(const WebRtc_Word32 id,
|
||||||
UdpSocketManager* mgr,
|
UdpSocketManager* mgr,
|
||||||
CallbackObj obj,
|
CallbackObj obj,
|
||||||
@ -97,7 +96,10 @@ public:
|
|||||||
virtual WebRtc_UWord32 ReceiveBuffers() {return 0;};
|
virtual WebRtc_UWord32 ReceiveBuffers() {return 0;};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// Creating the socket is done via CreateSocket().
|
||||||
UdpSocketWrapper();
|
UdpSocketWrapper();
|
||||||
|
// Destroying the socket is done via CloseBlocking().
|
||||||
|
virtual ~UdpSocketWrapper();
|
||||||
|
|
||||||
bool _wantsIncoming;
|
bool _wantsIncoming;
|
||||||
EventWrapper* _deleteEvent;
|
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': [
|
'sources': [
|
||||||
'udp_transport_unittest.cc',
|
'udp_transport_unittest.cc',
|
||||||
'udp_socket_manager_unittest.cc',
|
'udp_socket_manager_unittest.cc',
|
||||||
|
'udp_socket_wrapper_unittest.cc',
|
||||||
],
|
],
|
||||||
}, # udp_transport_unittests
|
}, # udp_transport_unittests
|
||||||
], # targets
|
], # targets
|
||||||
|
Loading…
x
Reference in New Issue
Block a user