Libtransport: Fix memory leaks in tests, fix HTTPRequest memory leak in CURL code

This commit is contained in:
Jan Kaluza 2016-02-23 12:37:10 +01:00
parent 10f8f610d0
commit 1e48fe7719
14 changed files with 122 additions and 49 deletions

View file

@ -40,6 +40,11 @@ DummyNetworkFactories::~DummyNetworkFactories() {
delete connectionFactory;
delete timerFactory;
delete m_platformXMLParserFactory;
#if HAVE_SWIFTEN_3
delete cryptoProvider;
delete networkEnvironment;
#endif
}
}

View file

@ -40,6 +40,14 @@ class HTTPRequest : public Thread {
boost::signal<void ()> onRequestFinished;
static void globalInit() {
curl_global_init(CURL_GLOBAL_ALL);
}
static void globalCleanup() {
curl_global_cleanup();
}
private:
bool init();
bool GET(std::string url, std::string &output);

View file

@ -330,6 +330,7 @@ NetworkPluginServer::~NetworkPluginServer() {
m_server->stop();
m_server.reset();
delete m_component->m_factory;
delete m_xmppParser;
// delete m_vcardResponder;
// delete m_rosterResponder;
// delete m_blockResponder;

View file

@ -30,6 +30,7 @@
#include "transport/Config.h"
#include "transport/Transport.h"
#include "transport/ThreadPool.h"
#include "transport/HTTPRequest.h"
#include <boost/bind.hpp>
#include <boost/smart_ptr/make_shared.hpp>
@ -47,6 +48,7 @@ namespace Transport {
DEFINE_LOGGER(logger, "SlackFrontend");
SlackFrontend::SlackFrontend() {
HTTPRequest::globalInit();
}
void SlackFrontend::init(Component *transport, Swift::EventLoop *loop, Swift::NetworkFactories *factories, Config *config, Transport::UserRegistry *userRegistry) {
@ -57,6 +59,7 @@ void SlackFrontend::init(Component *transport, Swift::EventLoop *loop, Swift::Ne
}
SlackFrontend::~SlackFrontend() {
HTTPRequest::globalCleanup();
}
void SlackFrontend::clearRoomList() {

View file

@ -86,6 +86,23 @@ void XMPPFrontend::init(Component *transport, Swift::EventLoop *loop, Swift::Net
m_config->onBackendConfigUpdated.connect(boost::bind(&XMPPFrontend::handleBackendConfigChanged, this));
m_parserFactories.push_back(new Swift::GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
m_parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
m_parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
m_parserFactories.push_back(new Swift::GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
m_parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
m_parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
m_parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
m_parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
m_payloadSerializers.push_back(new Swift::AttentionSerializer());
m_payloadSerializers.push_back(new Swift::XHTMLIMSerializer());
m_payloadSerializers.push_back(new Transport::BlockSerializer());
m_payloadSerializers.push_back(new Swift::InvisibleSerializer());
m_payloadSerializers.push_back(new Swift::StatsSerializer());
m_payloadSerializers.push_back(new Swift::SpectrumErrorSerializer());
m_payloadSerializers.push_back(new Swift::GatewayPayloadSerializer());
if (CONFIG_BOOL(m_config, "service.server_mode")) {
LOG4CXX_INFO(logger, "Creating component in server mode on port " << CONFIG_INT(m_config, "service.port"));
m_server = new Swift::Server(loop, factories, userRegistry, m_jid, CONFIG_STRING(m_config, "service.server"), CONFIG_INT(m_config, "service.port"));
@ -109,22 +126,13 @@ void XMPPFrontend::init(Component *transport, Swift::EventLoop *loop, Swift::Net
m_stanzaChannel = m_server->getStanzaChannel();
m_iqRouter = m_server->getIQRouter();
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
BOOST_FOREACH(Swift::PayloadParserFactory *factory, m_parserFactories) {
m_server->addPayloadParserFactory(factory);
}
m_server->addPayloadSerializer(new Swift::AttentionSerializer());
m_server->addPayloadSerializer(new Swift::XHTMLIMSerializer());
m_server->addPayloadSerializer(new Transport::BlockSerializer());
m_server->addPayloadSerializer(new Swift::InvisibleSerializer());
m_server->addPayloadSerializer(new Swift::StatsSerializer());
m_server->addPayloadSerializer(new Swift::SpectrumErrorSerializer());
m_server->addPayloadSerializer(new Swift::GatewayPayloadSerializer());
BOOST_FOREACH(Swift::PayloadSerializer *serializer, m_payloadSerializers) {
m_server->addPayloadSerializer(serializer);
}
m_server->onDataRead.connect(boost::bind(&XMPPFrontend::handleDataRead, this, _1));
m_server->onDataWritten.connect(boost::bind(&XMPPFrontend::handleDataWritten, this, _1));
@ -142,22 +150,13 @@ void XMPPFrontend::init(Component *transport, Swift::EventLoop *loop, Swift::Net
m_component->onDataRead.connect(boost::bind(&XMPPFrontend::handleDataRead, this, _1));
m_component->onDataWritten.connect(boost::bind(&XMPPFrontend::handleDataWritten, this, _1));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
BOOST_FOREACH(Swift::PayloadParserFactory *factory, m_parserFactories) {
m_component->addPayloadParserFactory(factory);
}
m_component->addPayloadSerializer(new Swift::AttentionSerializer());
m_component->addPayloadSerializer(new Swift::XHTMLIMSerializer());
m_component->addPayloadSerializer(new Transport::BlockSerializer());
m_component->addPayloadSerializer(new Swift::InvisibleSerializer());
m_component->addPayloadSerializer(new Swift::StatsSerializer());
m_component->addPayloadSerializer(new Swift::SpectrumErrorSerializer());
m_component->addPayloadSerializer(new Swift::GatewayPayloadSerializer());
BOOST_FOREACH(Swift::PayloadSerializer *serializer, m_payloadSerializers) {
m_component->addPayloadSerializer(serializer);
}
m_stanzaChannel = m_component->getStanzaChannel();
m_iqRouter = m_component->getIQRouter();
@ -186,6 +185,16 @@ XMPPFrontend::~XMPPFrontend() {
m_server->stop();
delete m_server;
}
BOOST_FOREACH(Swift::PayloadParserFactory *factory, m_parserFactories) {
delete factory;
}
m_parserFactories.clear();
BOOST_FOREACH(Swift::PayloadSerializer *serializer, m_payloadSerializers) {
delete serializer;
}
m_payloadSerializers.clear();
}
void XMPPFrontend::handleGeneralPresence(Swift::Presence::ref presence) {
@ -275,6 +284,9 @@ User *XMPPFrontend::createUser(const Swift::JID &jid, UserInfo &userInfo, Compon
}
UserManager *XMPPFrontend::createUserManager(Component *component, UserRegistry *userRegistry, StorageBackend *storageBackend) {
if (m_userManager) {
delete m_userManager;
}
m_userManager = new XMPPUserManager(component, userRegistry, storageBackend);
return m_userManager;
}

View file

@ -125,6 +125,8 @@ namespace Transport {
bool m_rawXML;
Component *m_transport;
UserManager *m_userManager;
std::vector<Swift::PayloadParserFactory *> m_parserFactories;
std::vector<Swift::PayloadSerializer *> m_payloadSerializers;
friend class XMPPUser;
friend class UserRegistration;

View file

@ -89,7 +89,7 @@ XMPPUserManager::XMPPUserManager(Component *component, UserRegistry *userRegistr
m_adHocManager = new AdHocManager(component, m_discoItemsResponder, this, storageBackend);
m_adHocManager->start();
SettingsAdHocCommandFactory *m_settings = new SettingsAdHocCommandFactory();
m_settings = new SettingsAdHocCommandFactory();
m_adHocManager->addAdHocCommand(m_settings);
}
@ -118,6 +118,8 @@ XMPPUserManager::~XMPPUserManager() {
m_discoItemsResponder->stop();
delete m_discoItemsResponder;
delete m_settings;
}
void XMPPUserManager::sendVCard(unsigned int id, Swift::VCard::ref vcard) {

View file

@ -21,6 +21,7 @@ class SlackRTMTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
void setUp (void) {
setMeUp();
UserInfo uinfo;
uinfo.id = 1;
m_idManager = new SlackIdManager();
m_rtm = new SlackRTM(component, storage, m_idManager, uinfo);

View file

@ -60,22 +60,30 @@ void BasicTest::setMeUp (void) {
payloadSerializers = new Swift::FullPayloadSerializerCollection();
payloadParserFactories = new Swift::FullPayloadParserFactoryCollection();
payloadParserFactories->addFactory(new Swift::GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
payloadParserFactories->addFactory(new Swift::GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
payloadParserFactories->addFactory(new Swift::GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
payloadParserFactories->addFactory(new Swift::GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
payloadParserFactories->addFactory(new Swift::GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
payloadParserFactories->addFactory(new Swift::GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
payloadParserFactories->addFactory(new Swift::GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
payloadParserFactories->addFactory(new Swift::GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
parserFactories.push_back(new Swift::GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
parserFactories.push_back(new Swift::GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
payloadSerializers->addSerializer(new Swift::AttentionSerializer());
payloadSerializers->addSerializer(new Swift::XHTMLIMSerializer());
payloadSerializers->addSerializer(new Transport::BlockSerializer());
payloadSerializers->addSerializer(new Swift::InvisibleSerializer());
payloadSerializers->addSerializer(new Swift::StatsSerializer());
payloadSerializers->addSerializer(new Swift::SpectrumErrorSerializer());
payloadSerializers->addSerializer(new Swift::GatewayPayloadSerializer());
BOOST_FOREACH(Swift::PayloadParserFactory *factory, parserFactories) {
payloadParserFactories->addFactory(factory);
}
_payloadSerializers.push_back(new Swift::AttentionSerializer());
_payloadSerializers.push_back(new Swift::XHTMLIMSerializer());
_payloadSerializers.push_back(new Transport::BlockSerializer());
_payloadSerializers.push_back(new Swift::InvisibleSerializer());
_payloadSerializers.push_back(new Swift::StatsSerializer());
_payloadSerializers.push_back(new Swift::SpectrumErrorSerializer());
_payloadSerializers.push_back(new Swift::GatewayPayloadSerializer());
BOOST_FOREACH(Swift::PayloadSerializer *serializer, _payloadSerializers) {
payloadSerializers->addSerializer(serializer);
}
parser = new Swift::XMPPParser(this, payloadParserFactories, factories->getXMLParserFactory());
parser2 = new Swift::XMPPParser(this, payloadParserFactories, factories->getXMLParserFactory());
@ -101,6 +109,7 @@ void BasicTest::tearMeDown (void) {
dynamic_cast<Swift::ServerStanzaChannel *>(static_cast<XMPPFrontend *>(component->getFrontend())->getStanzaChannel())->removeSession(serverFromClientSession2);
serverFromClientSession2.reset();
}
delete userManager;
delete component;
delete frontend;
delete userRegistry;
@ -116,6 +125,20 @@ void BasicTest::tearMeDown (void) {
received2.clear();
receivedData.clear();
receivedData2.clear();
delete payloadParserFactories;
delete payloadSerializers;
BOOST_FOREACH(Swift::PayloadParserFactory *factory, parserFactories) {
delete factory;
}
parserFactories.clear();
BOOST_FOREACH(Swift::PayloadSerializer *serializer, _payloadSerializers) {
delete serializer;
}
_payloadSerializers.clear();
}
void BasicTest::handleDataReceived(const Swift::SafeByteArray &data) {

View file

@ -282,5 +282,7 @@ class BasicTest : public Swift::XMPPParserClient {
DiscoItemsResponder *itemsResponder;
bool stream1_active;
Transport::XMPPFrontend *frontend;
std::vector<Swift::PayloadParserFactory *> parserFactories;
std::vector<Swift::PayloadSerializer *> _payloadSerializers;
};

View file

@ -143,6 +143,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
CPPUNIT_ASSERT_EQUAL(std::string("subject"), m_msg->getSubject());
received.clear();
delete conv;
}
void handleNormalMessages() {
@ -611,6 +612,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Moderator, *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].role);
CPPUNIT_ASSERT_EQUAL(std::string("hanzz"), *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].nick);
CPPUNIT_ASSERT_EQUAL(303, getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getStatusCodes()[0].code);
delete conv;
}
void handleParticipantChangedEscaped() {
@ -633,6 +635,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::MUCUserPayload>());
CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Member, *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].affiliation);
CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Participant, *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].role);
delete conv;
}
void handleParticipantChangedEscaped2() {
@ -656,6 +659,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::MUCUserPayload>());
CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Member, *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].affiliation);
CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Participant, *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].role);
delete conv;
}
void handleParticipantChangedIconHash() {
@ -682,6 +686,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
Swift::VCardUpdate::ref payload = getStanza(received[0])->getPayload<Swift::VCardUpdate>();
CPPUNIT_ASSERT(payload);
delete conv;
}
void handleParticipantChangedTwoResources() {
@ -707,6 +712,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
CPPUNIT_ASSERT(getStanza(received2[0])->getPayload<Swift::MUCUserPayload>());
CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Member, *getStanza(received2[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].affiliation);
CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Participant, *getStanza(received2[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].role);
delete conv;
}
void handlePMFromXMPP() {
@ -776,6 +782,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
CPPUNIT_ASSERT_EQUAL(Swift::Presence::Error, dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getType());
CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::ErrorPayload>());
CPPUNIT_ASSERT_EQUAL(Swift::ErrorPayload::Conflict, getStanza(received[0])->getPayload<Swift::ErrorPayload>()->getCondition());
delete conv;
}
void handleNotAuthorized() {
@ -795,6 +802,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
CPPUNIT_ASSERT_EQUAL(Swift::Presence::Error, dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getType());
CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::ErrorPayload>());
CPPUNIT_ASSERT_EQUAL(Swift::ErrorPayload::NotAuthorized, getStanza(received[0])->getPayload<Swift::ErrorPayload>()->getCondition());
delete conv;
}
void handleSetNickname() {
@ -814,6 +822,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[0])));
CPPUNIT_ASSERT_EQUAL(110, getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getStatusCodes()[0].code);
CPPUNIT_ASSERT_EQUAL(210, getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getStatusCodes()[1].code);
delete conv;
}
};

View file

@ -11,6 +11,8 @@
#include "log4cxx/patternlayout.h"
#include "log4cxx/propertyconfigurator.h"
#include "transport/protocol.pb.h"
using namespace log4cxx;
#endif
@ -55,6 +57,7 @@ int main (int argc, char* argv[])
testrunner.run(testresult, *i);
}
catch (const std::exception& e) {
google::protobuf::ShutdownProtobufLibrary();
std::cerr << "Error: " << e.what() << std::endl;
return -1;
}
@ -64,6 +67,8 @@ int main (int argc, char* argv[])
CPPUNIT_NS :: CompilerOutputter compileroutputter (&collectedresults, std::cerr);
compileroutputter.write ();
google::protobuf::ShutdownProtobufLibrary();
// return 0 if tests were successful
return collectedresults.wasSuccessful () ? 0 : 1;
}

View file

@ -18,7 +18,7 @@ using namespace Transport;
class UserManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
CPPUNIT_TEST_SUITE(UserManagerTest);
CPPUNIT_TEST(connectUser);
// CPPUNIT_TEST(connectUser); // executed as part of other tests
CPPUNIT_TEST(connectTwoResources);
CPPUNIT_TEST(connectUserTransportDisabled);
CPPUNIT_TEST(connectUserRegistrationNeeded);

View file

@ -54,9 +54,9 @@ class UserRegistryTest : public CPPUNIT_NS :: TestFixture {
void tearDown (void) {
delete server;
dynamic_cast<Swift::DummyConnection *>(client1.get())->onDataSent.disconnect(boost::bind(&UserRegistryTest::handleDataReceived, this, _1, client1));
dynamic_cast<Swift::DummyConnection *>(client1.get())->onDataSent.disconnect_all_slots();
client1.reset();
dynamic_cast<Swift::DummyConnection *>(client2.get())->onDataSent.disconnect(boost::bind(&UserRegistryTest::handleDataReceived, this, _1, client2));
dynamic_cast<Swift::DummyConnection *>(client2.get())->onDataSent.disconnect_all_slots();
client2.reset();
connectionServer.reset();
delete userRegistry;