Unit tests for SMTP.
This commit is contained in:
parent
4579f8f95a
commit
2791e5d41e
@ -333,6 +333,7 @@ libvmimetest_common = [
|
||||
|
||||
libvmimetest_sources = [
|
||||
'tests/testRunner.cpp',
|
||||
'tests/testUtils.cpp',
|
||||
# ============================== Parser ==============================
|
||||
'tests/parser/attachmentHelperTest.cpp',
|
||||
'tests/parser/bodyPartTest.cpp',
|
||||
@ -360,7 +361,10 @@ libvmimetest_sources = [
|
||||
'tests/misc/importanceHelperTest.cpp',
|
||||
# ============================= Security =============================
|
||||
'tests/security/digest/md5Test.cpp',
|
||||
'tests/security/digest/sha1Test.cpp'
|
||||
'tests/security/digest/sha1Test.cpp',
|
||||
# =============================== Net ================================
|
||||
'tests/net/smtp/SMTPTransportTest.cpp',
|
||||
'tests/net/smtp/SMTPResponseTest.cpp'
|
||||
]
|
||||
|
||||
libvmime_autotools = [
|
||||
|
189
tests/net/smtp/SMTPResponseTest.cpp
Normal file
189
tests/net/smtp/SMTPResponseTest.cpp
Normal file
@ -0,0 +1,189 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2006 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#include "tests/testUtils.hpp"
|
||||
|
||||
#include "vmime/net/smtp/SMTPResponse.hpp"
|
||||
|
||||
|
||||
#define VMIME_TEST_SUITE SMTPResponseTest
|
||||
#define VMIME_TEST_SUITE_MODULE "Net/SMTP"
|
||||
|
||||
|
||||
VMIME_TEST_SUITE_BEGIN
|
||||
|
||||
VMIME_TEST_LIST_BEGIN
|
||||
VMIME_TEST(testSingleLineResponse)
|
||||
VMIME_TEST(testSingleLineResponseLF)
|
||||
VMIME_TEST(testMultiLineResponse)
|
||||
VMIME_TEST(testMultiLineResponseDifferentCode)
|
||||
VMIME_TEST(testIncompleteMultiLineResponse)
|
||||
VMIME_TEST(testIntermediateResponse)
|
||||
VMIME_TEST(testNoResponseText)
|
||||
VMIME_TEST_LIST_END
|
||||
|
||||
|
||||
void testSingleLineResponse()
|
||||
{
|
||||
vmime::ref <testSocket> socket = vmime::create <testSocket>();
|
||||
vmime::ref <vmime::net::timeoutHandler> toh =
|
||||
vmime::create <testTimeoutHandler>();
|
||||
|
||||
socket->localSend("123 Response Text\r\n");
|
||||
|
||||
vmime::ref <vmime::net::smtp::SMTPResponse> resp =
|
||||
vmime::net::smtp::SMTPResponse::readResponse(socket, toh);
|
||||
|
||||
VASSERT_EQ("Code", 123, resp->getCode());
|
||||
VASSERT_EQ("Lines", 1, resp->getLineCount());
|
||||
VASSERT_EQ("Text", "Response Text", resp->getText());
|
||||
}
|
||||
|
||||
void testSingleLineResponseLF()
|
||||
{
|
||||
vmime::ref <testSocket> socket = vmime::create <testSocket>();
|
||||
vmime::ref <vmime::net::timeoutHandler> toh =
|
||||
vmime::create <testTimeoutHandler>();
|
||||
|
||||
socket->localSend("123 Response Text\n");
|
||||
|
||||
vmime::ref <vmime::net::smtp::SMTPResponse> resp =
|
||||
vmime::net::smtp::SMTPResponse::readResponse(socket, toh);
|
||||
|
||||
VASSERT_EQ("Code", 123, resp->getCode());
|
||||
VASSERT_EQ("Lines", 1, resp->getLineCount());
|
||||
VASSERT_EQ("Text", "Response Text", resp->getText());
|
||||
}
|
||||
|
||||
void testMultiLineResponse()
|
||||
{
|
||||
vmime::ref <testSocket> socket = vmime::create <testSocket>();
|
||||
vmime::ref <vmime::net::timeoutHandler> toh =
|
||||
vmime::create <testTimeoutHandler>();
|
||||
|
||||
socket->localSend
|
||||
(
|
||||
"123-Response\r\n"
|
||||
"123 Text\r\n"
|
||||
);
|
||||
|
||||
vmime::ref <vmime::net::smtp::SMTPResponse> resp =
|
||||
vmime::net::smtp::SMTPResponse::readResponse(socket, toh);
|
||||
|
||||
VASSERT_EQ("Code", 123, resp->getCode());
|
||||
VASSERT_EQ("Lines", 2, resp->getLineCount());
|
||||
VASSERT_EQ("Text", "Response\nText", resp->getText());
|
||||
|
||||
VASSERT_EQ("Code", 123, resp->getLineAt(0).getCode());
|
||||
VASSERT_EQ("Text", "Response", resp->getLineAt(0).getText());
|
||||
|
||||
VASSERT_EQ("Code", 123, resp->getLineAt(1).getCode());
|
||||
VASSERT_EQ("Text", "Text", resp->getLineAt(1).getText());
|
||||
}
|
||||
|
||||
void testMultiLineResponseDifferentCode()
|
||||
{
|
||||
vmime::ref <testSocket> socket = vmime::create <testSocket>();
|
||||
vmime::ref <vmime::net::timeoutHandler> toh =
|
||||
vmime::create <testTimeoutHandler>();
|
||||
|
||||
socket->localSend
|
||||
(
|
||||
"123-Response\r\n"
|
||||
"456 Text\r\n"
|
||||
);
|
||||
|
||||
vmime::ref <vmime::net::smtp::SMTPResponse> resp =
|
||||
vmime::net::smtp::SMTPResponse::readResponse(socket, toh);
|
||||
|
||||
VASSERT_EQ("Code", 0, resp->getCode());
|
||||
VASSERT_EQ("Lines", 2, resp->getLineCount());
|
||||
VASSERT_EQ("Text", "Response\nText", resp->getText());
|
||||
|
||||
VASSERT_EQ("Code", 123, resp->getLineAt(0).getCode());
|
||||
VASSERT_EQ("Text", "Response", resp->getLineAt(0).getText());
|
||||
|
||||
VASSERT_EQ("Code", 456, resp->getLineAt(1).getCode());
|
||||
VASSERT_EQ("Text", "Text", resp->getLineAt(1).getText());
|
||||
}
|
||||
|
||||
void testIncompleteMultiLineResponse()
|
||||
{
|
||||
vmime::ref <testSocket> socket = vmime::create <testSocket>();
|
||||
vmime::ref <vmime::net::timeoutHandler> toh =
|
||||
vmime::create <testTimeoutHandler>(1);
|
||||
|
||||
socket->localSend
|
||||
(
|
||||
"123-Response\r\n"
|
||||
"123-Text\r\n"
|
||||
// Missing data
|
||||
);
|
||||
|
||||
VASSERT_THROW("Incomplete response",
|
||||
vmime::net::smtp::SMTPResponse::readResponse(socket, toh),
|
||||
vmime::exceptions::operation_timed_out);
|
||||
}
|
||||
|
||||
void testIntermediateResponse()
|
||||
{
|
||||
vmime::ref <testSocket> socket = vmime::create <testSocket>();
|
||||
vmime::ref <vmime::net::timeoutHandler> toh =
|
||||
vmime::create <testTimeoutHandler>(1);
|
||||
|
||||
socket->localSend
|
||||
(
|
||||
"334\r\n"
|
||||
"More information\r\n"
|
||||
);
|
||||
|
||||
vmime::ref <vmime::net::smtp::SMTPResponse> resp =
|
||||
vmime::net::smtp::SMTPResponse::readResponse(socket, toh);
|
||||
|
||||
VASSERT_EQ("Code", 334, resp->getCode());
|
||||
VASSERT_EQ("Lines", 1, resp->getLineCount());
|
||||
VASSERT_EQ("Text", "More information", resp->getText());
|
||||
}
|
||||
|
||||
void testNoResponseText()
|
||||
{
|
||||
vmime::ref <testSocket> socket = vmime::create <testSocket>();
|
||||
vmime::ref <vmime::net::timeoutHandler> toh =
|
||||
vmime::create <testTimeoutHandler>(1);
|
||||
|
||||
socket->localSend
|
||||
(
|
||||
"250\r\n"
|
||||
);
|
||||
|
||||
vmime::ref <vmime::net::smtp::SMTPResponse> resp =
|
||||
vmime::net::smtp::SMTPResponse::readResponse(socket, toh);
|
||||
|
||||
VASSERT_EQ("Code", 250, resp->getCode());
|
||||
VASSERT_EQ("Lines", 1, resp->getLineCount());
|
||||
VASSERT_EQ("Text", "", resp->getText());
|
||||
}
|
||||
|
||||
|
||||
VMIME_TEST_SUITE_END
|
||||
|
256
tests/net/smtp/SMTPTransportTest.cpp
Normal file
256
tests/net/smtp/SMTPTransportTest.cpp
Normal file
@ -0,0 +1,256 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2006 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#include "tests/testUtils.hpp"
|
||||
|
||||
|
||||
#define VMIME_TEST_SUITE SMTPTransportTest
|
||||
#define VMIME_TEST_SUITE_MODULE "Net/SMTP"
|
||||
|
||||
|
||||
class greetingErrorSMTPTestSocket;
|
||||
class MAILandRCPTSMTPTestSocket;
|
||||
|
||||
|
||||
VMIME_TEST_SUITE_BEGIN
|
||||
|
||||
VMIME_TEST_LIST_BEGIN
|
||||
VMIME_TEST(testGreetingError)
|
||||
VMIME_TEST(testMAILandRCPT)
|
||||
VMIME_TEST_LIST_END
|
||||
|
||||
|
||||
void testGreetingError()
|
||||
{
|
||||
vmime::ref <vmime::net::session> session =
|
||||
vmime::create <vmime::net::session>();
|
||||
|
||||
vmime::ref <vmime::net::transport> tr = session->getTransport
|
||||
(vmime::utility::url("smtp://localhost"));
|
||||
|
||||
tr->setSocketFactory(vmime::create <testSocketFactory <greetingErrorSMTPTestSocket> >());
|
||||
tr->setTimeoutHandlerFactory(vmime::create <testTimeoutHandlerFactory>());
|
||||
|
||||
VASSERT_THROW("Connection", tr->connect(),
|
||||
vmime::exceptions::connection_greeting_error);
|
||||
}
|
||||
|
||||
void testMAILandRCPT()
|
||||
{
|
||||
vmime::ref <vmime::net::session> session =
|
||||
vmime::create <vmime::net::session>();
|
||||
|
||||
vmime::ref <vmime::net::transport> tr = session->getTransport
|
||||
(vmime::utility::url("smtp://localhost"));
|
||||
|
||||
tr->setSocketFactory(vmime::create <testSocketFactory <MAILandRCPTSMTPTestSocket> >());
|
||||
tr->setTimeoutHandlerFactory(vmime::create <testTimeoutHandlerFactory>());
|
||||
|
||||
VASSERT_NO_THROW("Connection", tr->connect());
|
||||
|
||||
vmime::mailbox exp("expeditor@test.vmime.org");
|
||||
|
||||
vmime::mailboxList recips;
|
||||
recips.appendMailbox(vmime::create <vmime::mailbox>("recipient1@test.vmime.org"));
|
||||
recips.appendMailbox(vmime::create <vmime::mailbox>("recipient2@test.vmime.org"));
|
||||
recips.appendMailbox(vmime::create <vmime::mailbox>("recipient3@test.vmime.org"));
|
||||
|
||||
vmime::string data("Message data");
|
||||
vmime::utility::inputStreamStringAdapter is(data);
|
||||
|
||||
tr->send(exp, recips, is, 0);
|
||||
}
|
||||
|
||||
VMIME_TEST_SUITE_END
|
||||
|
||||
|
||||
/** Accepts connection and fails on greeting.
|
||||
*/
|
||||
class greetingErrorSMTPTestSocket : public lineBasedTestSocket
|
||||
{
|
||||
public:
|
||||
|
||||
void onConnected()
|
||||
{
|
||||
localSend("421 test.vmime.org Service not available, closing transmission channel\r\n");
|
||||
disconnect();
|
||||
}
|
||||
|
||||
void processCommand()
|
||||
{
|
||||
if (!haveMoreLines())
|
||||
return;
|
||||
|
||||
getNextLine();
|
||||
|
||||
localSend("502 Command not implemented\r\n");
|
||||
processCommand();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** SMTP test server 1.
|
||||
*
|
||||
* Test send().
|
||||
* Ensure MAIL and RCPT commands are sent correctly.
|
||||
*/
|
||||
class MAILandRCPTSMTPTestSocket : public lineBasedTestSocket
|
||||
{
|
||||
public:
|
||||
|
||||
MAILandRCPTSMTPTestSocket()
|
||||
{
|
||||
m_recipients.insert("recipient1@test.vmime.org");
|
||||
m_recipients.insert("recipient2@test.vmime.org");
|
||||
m_recipients.insert("recipient3@test.vmime.org");
|
||||
|
||||
m_state = STATE_NOT_CONNECTED;
|
||||
}
|
||||
|
||||
void onConnected()
|
||||
{
|
||||
localSend("220 test.vmime.org Service ready\r\n");
|
||||
processCommand();
|
||||
|
||||
m_state = STATE_COMMAND;
|
||||
}
|
||||
|
||||
void processCommand()
|
||||
{
|
||||
if (!haveMoreLines())
|
||||
return;
|
||||
|
||||
vmime::string line = getNextLine();
|
||||
std::istringstream iss(line);
|
||||
|
||||
switch (m_state)
|
||||
{
|
||||
case STATE_NOT_CONNECTED:
|
||||
|
||||
localSend("451 Requested action aborted: invalid state\r\n");
|
||||
break;
|
||||
|
||||
case STATE_COMMAND:
|
||||
{
|
||||
std::string cmd;
|
||||
iss >> cmd;
|
||||
|
||||
if (cmd.empty())
|
||||
{
|
||||
localSend("500 Syntax error, command unrecognized\r\n");
|
||||
}
|
||||
else if (cmd == "HELO")
|
||||
{
|
||||
localSend("250 OK\r\n");
|
||||
}
|
||||
else if (cmd == "MAIL")
|
||||
{
|
||||
VASSERT_EQ("MAIL", std::string("MAIL FROM: <expeditor@test.vmime.org>"), line);
|
||||
|
||||
localSend("250 OK\r\n");
|
||||
}
|
||||
else if (cmd == "RCPT")
|
||||
{
|
||||
const vmime::string::size_type lt = line.find('<');
|
||||
const vmime::string::size_type gt = line.find('>');
|
||||
|
||||
VASSERT("RCPT <", lt != vmime::string::npos);
|
||||
VASSERT("RCPT >", gt != vmime::string::npos);
|
||||
VASSERT("RCPT ><", gt >= lt);
|
||||
|
||||
const vmime::string recip = vmime::string
|
||||
(line.begin() + lt + 1, line.begin() + gt);
|
||||
|
||||
std::set <vmime::string>::iterator it =
|
||||
m_recipients.find(recip);
|
||||
|
||||
VASSERT(std::string("Recipient not found: '") + recip + "'",
|
||||
it != m_recipients.end());
|
||||
|
||||
m_recipients.erase(it);
|
||||
|
||||
localSend("250 OK, recipient accepted\r\n");
|
||||
}
|
||||
else if (cmd == "DATA")
|
||||
{
|
||||
VASSERT("All recipients", m_recipients.empty());
|
||||
|
||||
localSend("354 Ready to accept data; end with <CRLF>.<CRLF>\r\n");
|
||||
|
||||
m_state = STATE_DATA;
|
||||
m_msgData.clear();
|
||||
}
|
||||
else if (cmd == "NOOP")
|
||||
{
|
||||
localSend("250 Completed\r\n");
|
||||
}
|
||||
else if (cmd == "QUIT")
|
||||
{
|
||||
localSend("221 test.vmime.org Service closing transmission channel\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
localSend("502 Command not implemented\r\n");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case STATE_DATA:
|
||||
{
|
||||
if (line == ".")
|
||||
{
|
||||
VASSERT_EQ("Data", "Message data\r\n", m_msgData);
|
||||
|
||||
localSend("250 Message accepted for delivery\r\n");
|
||||
m_state = STATE_COMMAND;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_msgData += line + "\r\n";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
processCommand();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
enum State
|
||||
{
|
||||
STATE_NOT_CONNECTED,
|
||||
STATE_COMMAND,
|
||||
STATE_DATA
|
||||
};
|
||||
|
||||
int m_state;
|
||||
|
||||
std::set <vmime::string> m_recipients;
|
||||
|
||||
std::string m_msgData;
|
||||
};
|
||||
|
||||
|
@ -210,7 +210,7 @@ int main(int argc, char* argv[])
|
||||
// Run the tests
|
||||
if (xmlOutput)
|
||||
{
|
||||
// Get the test suites from the registry and add them to the list of test to run
|
||||
// Get the test suites from the registry and add them to the list of tests to run
|
||||
CppUnit::TestRunner runner;
|
||||
|
||||
for (unsigned int i = 0 ; i < getTestModules().size() ; ++i)
|
||||
@ -231,7 +231,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
xmlListener->output(std::cout);
|
||||
|
||||
// Return error code 1 if the one of test failed
|
||||
// Return error code 1 if a test failed
|
||||
return result.wasSuccessful() ? 0 : 1;
|
||||
}
|
||||
else
|
||||
|
183
tests/testUtils.cpp
Normal file
183
tests/testUtils.cpp
Normal file
@ -0,0 +1,183 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#include "testUtils.hpp"
|
||||
|
||||
|
||||
|
||||
// testSocket
|
||||
|
||||
void testSocket::connect(const vmime::string& address, const vmime::port_t port)
|
||||
{
|
||||
m_address = address;
|
||||
m_port = port;
|
||||
m_connected = true;
|
||||
|
||||
onConnected();
|
||||
}
|
||||
|
||||
|
||||
void testSocket::disconnect()
|
||||
{
|
||||
m_address.clear();
|
||||
m_port = 0;
|
||||
m_connected = false;
|
||||
}
|
||||
|
||||
|
||||
const bool testSocket::isConnected() const
|
||||
{
|
||||
return m_connected;
|
||||
}
|
||||
|
||||
|
||||
void testSocket::receive(vmime::string& buffer)
|
||||
{
|
||||
buffer = m_inBuffer;
|
||||
m_inBuffer.clear();
|
||||
}
|
||||
|
||||
|
||||
void testSocket::send(const vmime::string& buffer)
|
||||
{
|
||||
m_outBuffer += buffer;
|
||||
|
||||
onDataReceived();
|
||||
}
|
||||
|
||||
|
||||
const int testSocket::receiveRaw(char* buffer, const int count)
|
||||
{
|
||||
const int n = std::min(count, static_cast <int>(m_inBuffer.size()));
|
||||
|
||||
std::copy(m_inBuffer.begin(), m_inBuffer.begin() + n, buffer);
|
||||
m_inBuffer.erase(m_inBuffer.begin(), m_inBuffer.begin() + n);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
void testSocket::sendRaw(const char* buffer, const int count)
|
||||
{
|
||||
send(vmime::string(buffer, count));
|
||||
}
|
||||
|
||||
|
||||
void testSocket::localSend(const vmime::string& buffer)
|
||||
{
|
||||
m_inBuffer += buffer;
|
||||
}
|
||||
|
||||
|
||||
void testSocket::localReceive(vmime::string& buffer)
|
||||
{
|
||||
buffer = m_outBuffer;
|
||||
m_outBuffer.clear();
|
||||
}
|
||||
|
||||
|
||||
void testSocket::onDataReceived()
|
||||
{
|
||||
// Override
|
||||
}
|
||||
|
||||
|
||||
void testSocket::onConnected()
|
||||
{
|
||||
// Override
|
||||
}
|
||||
|
||||
|
||||
// lineBasedTestSocket
|
||||
|
||||
void lineBasedTestSocket::onDataReceived()
|
||||
{
|
||||
vmime::string chunk;
|
||||
localReceive(chunk);
|
||||
|
||||
m_buffer += chunk;
|
||||
|
||||
vmime::string::size_type eol;
|
||||
|
||||
while ((eol = m_buffer.find('\n')) != vmime::string::npos)
|
||||
{
|
||||
vmime::string line(std::string(m_buffer.begin(), m_buffer.begin() + eol));
|
||||
|
||||
if (!line.empty() && line[line.length() - 1] == '\r')
|
||||
line.erase(line.end() - 1, line.end());
|
||||
|
||||
m_lines.push_back(line);
|
||||
m_buffer.erase(m_buffer.begin(), m_buffer.begin() + eol + 1);
|
||||
}
|
||||
|
||||
while (!m_lines.empty())
|
||||
processCommand();
|
||||
}
|
||||
|
||||
|
||||
const vmime::string lineBasedTestSocket::getNextLine()
|
||||
{
|
||||
const vmime::string line = m_lines.front();
|
||||
m_lines.erase(m_lines.begin(), m_lines.begin() + 1);
|
||||
return line;
|
||||
}
|
||||
|
||||
const bool lineBasedTestSocket::haveMoreLines() const
|
||||
{
|
||||
return !m_lines.empty();
|
||||
}
|
||||
|
||||
|
||||
// testTimeoutHandler
|
||||
|
||||
testTimeoutHandler::testTimeoutHandler(const unsigned int delay)
|
||||
: m_delay(delay), m_start(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const bool testTimeoutHandler::isTimeOut()
|
||||
{
|
||||
return (vmime::platformDependant::getHandler()->getUnixTime() - m_start) >= m_delay;
|
||||
}
|
||||
|
||||
|
||||
void testTimeoutHandler::resetTimeOut()
|
||||
{
|
||||
m_start = vmime::platformDependant::getHandler()->getUnixTime();
|
||||
}
|
||||
|
||||
|
||||
const bool testTimeoutHandler::handleTimeOut()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// testTimeoutHandlerFactory : public vmime::net::timeoutHandlerFactory
|
||||
|
||||
vmime::ref <vmime::net::timeoutHandler> testTimeoutHandlerFactory::create()
|
||||
{
|
||||
return vmime::create <testTimeoutHandler>();
|
||||
}
|
||||
|
@ -193,3 +193,113 @@ inline std::ostream& operator<<(std::ostream& os, const vmime::datetime& d)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Used to test network features.
|
||||
//
|
||||
// This works like a local pipe: client reads and writes data using receive()
|
||||
// and send(). Server reads incoming data with localReceive() and sends data
|
||||
// to client with localSend().
|
||||
|
||||
class testSocket : public vmime::net::socket
|
||||
{
|
||||
public:
|
||||
|
||||
void connect(const vmime::string& address, const vmime::port_t port);
|
||||
void disconnect();
|
||||
|
||||
const bool isConnected() const;
|
||||
|
||||
void receive(vmime::string& buffer);
|
||||
void send(const vmime::string& buffer);
|
||||
|
||||
const int receiveRaw(char* buffer, const int count);
|
||||
void sendRaw(const char* buffer, const int count);
|
||||
|
||||
/** Send data to client.
|
||||
*
|
||||
* @buffer data to send
|
||||
*/
|
||||
void localSend(const vmime::string& buffer);
|
||||
|
||||
/** Receive data from client.
|
||||
*
|
||||
* @buffer buffer in which to store received data
|
||||
*/
|
||||
void localReceive(vmime::string& buffer);
|
||||
|
||||
protected:
|
||||
|
||||
/** Called when the client has sent some data.
|
||||
*/
|
||||
virtual void onDataReceived();
|
||||
|
||||
/** Called when the client has connected.
|
||||
*/
|
||||
virtual void onConnected();
|
||||
|
||||
private:
|
||||
|
||||
vmime::string m_address;
|
||||
vmime::port_t m_port;
|
||||
bool m_connected;
|
||||
|
||||
vmime::string m_inBuffer;
|
||||
vmime::string m_outBuffer;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
class testSocketFactory : public vmime::net::socketFactory
|
||||
{
|
||||
public:
|
||||
|
||||
vmime::ref <vmime::net::socket> create()
|
||||
{
|
||||
return vmime::create <T>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class lineBasedTestSocket : public testSocket
|
||||
{
|
||||
public:
|
||||
|
||||
void onDataReceived();
|
||||
|
||||
const vmime::string getNextLine();
|
||||
const bool haveMoreLines() const;
|
||||
|
||||
virtual void processCommand() = 0;
|
||||
|
||||
private:
|
||||
|
||||
std::vector <vmime::string> m_lines;
|
||||
std::string m_buffer;
|
||||
};
|
||||
|
||||
|
||||
class testTimeoutHandler : public vmime::net::timeoutHandler
|
||||
{
|
||||
public:
|
||||
|
||||
testTimeoutHandler(const unsigned int delay = 3);
|
||||
|
||||
const bool isTimeOut();
|
||||
void resetTimeOut();
|
||||
const bool handleTimeOut();
|
||||
|
||||
private:
|
||||
|
||||
unsigned int m_delay;
|
||||
unsigned int m_start;
|
||||
};
|
||||
|
||||
|
||||
class testTimeoutHandlerFactory : public vmime::net::timeoutHandlerFactory
|
||||
{
|
||||
public:
|
||||
|
||||
vmime::ref <vmime::net::timeoutHandler> create();
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user