diff options
Diffstat (limited to 'tests/net/smtp/SMTPTransportTest.cpp')
-rw-r--r-- | tests/net/smtp/SMTPTransportTest.cpp | 442 |
1 files changed, 36 insertions, 406 deletions
diff --git a/tests/net/smtp/SMTPTransportTest.cpp b/tests/net/smtp/SMTPTransportTest.cpp index c91ffe90..70aaa4fd 100644 --- a/tests/net/smtp/SMTPTransportTest.cpp +++ b/tests/net/smtp/SMTPTransportTest.cpp @@ -26,11 +26,7 @@ #include "vmime/net/smtp/SMTPTransport.hpp" #include "vmime/net/smtp/SMTPChunkingOutputStreamAdapter.hpp" - -class greetingErrorSMTPTestSocket; -class MAILandRCPTSMTPTestSocket; -class chunkingSMTPTestSocket; -class SMTPTestMessage; +#include "SMTPTransportTestUtils.hpp" VMIME_TEST_SUITE_BEGIN(SMTPTransportTest) @@ -39,6 +35,8 @@ VMIME_TEST_SUITE_BEGIN(SMTPTransportTest) VMIME_TEST(testGreetingError) VMIME_TEST(testMAILandRCPT) VMIME_TEST(testChunking) + VMIME_TEST(testSize_Chunking) + VMIME_TEST(testSize_NoChunking) VMIME_TEST_LIST_END @@ -109,427 +107,59 @@ VMIME_TEST_SUITE_BEGIN(SMTPTransportTest) tr->send(msg, exp, recips); } -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() + void testSize_Chunking() { - m_recipients.insert("[email protected]"); - m_recipients.insert("[email protected]"); - m_recipients.insert("[email protected]"); - - m_state = STATE_NOT_CONNECTED; - m_ehloSent = m_heloSent = m_mailSent = m_rcptSent = m_dataSent = m_quitSent = false; - } - - ~MAILandRCPTSMTPTestSocket() - { - VASSERT("Client must send the DATA command", m_dataSent); - VASSERT("Client must send the QUIT command", m_quitSent); - } - - 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 == "EHLO") - { - localSend("502 Command not implemented\r\n"); - - m_ehloSent = true; - } - else if (cmd == "HELO") - { - VASSERT("Client must send the EHLO command before HELO", m_ehloSent); - - localSend("250 OK\r\n"); - - m_heloSent = true; - } - else if (cmd == "MAIL") - { - VASSERT("Client must send the HELO command", m_heloSent); - VASSERT("The MAIL command must be sent only one time", !m_mailSent); - - VASSERT_EQ("MAIL", std::string("MAIL FROM:<[email protected]>"), line); - - localSend("250 OK\r\n"); - - m_mailSent = true; - } - 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"); - - m_rcptSent = true; - } - else if (cmd == "DATA") - { - VASSERT("Client must send the MAIL command", m_mailSent); - VASSERT("Client must send the RCPT command", m_rcptSent); - 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(); - - m_dataSent = true; - } - else if (cmd == "NOOP") - { - localSend("250 Completed\r\n"); - } - else if (cmd == "QUIT") - { - m_quitSent = true; - - 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; - - bool m_ehloSent, m_heloSent, m_mailSent, m_rcptSent, - m_dataSent, m_quitSent; -}; - + vmime::ref <vmime::net::session> session = + vmime::create <vmime::net::session>(); + vmime::ref <vmime::net::transport> tr = session->getTransport + (vmime::utility::url("smtp://localhost")); -/** SMTP test server 2. - * - * Test CHUNKING extension/BDAT command. - */ -class chunkingSMTPTestSocket : public testSocket -{ -public: + tr->setSocketFactory(vmime::create <testSocketFactory <bigMessageSMTPTestSocket <true> > >()); + tr->setTimeoutHandlerFactory(vmime::create <testTimeoutHandlerFactory>()); - chunkingSMTPTestSocket() - { - m_state = STATE_NOT_CONNECTED; - m_bdatChunkCount = 0; - m_ehloSent = m_mailSent = m_rcptSent = m_quitSent = false; - } + tr->connect(); - ~chunkingSMTPTestSocket() - { - VASSERT_EQ("BDAT chunk count", 3, m_bdatChunkCount); - VASSERT("Client must send the QUIT command", m_quitSent); - } + VASSERT("Test server should report it supports the SIZE extension!", + tr.dynamicCast <vmime::net::smtp::SMTPTransport>()->getConnection()->hasExtension("SIZE")); - void onConnected() - { - localSend("220 test.vmime.org Service ready\r\n"); - processCommand(); + vmime::mailbox exp("[email protected]"); - m_state = STATE_COMMAND; - } + vmime::mailboxList recips; + recips.appendMailbox(vmime::create <vmime::mailbox>("[email protected]")); - void onDataReceived() - { - if (m_state == STATE_DATA) - { - if (m_bdatChunkReceived != m_bdatChunkSize) - { - const size_type remaining = m_bdatChunkSize - m_bdatChunkReceived; - const size_type received = localReceiveRaw(NULL, remaining); - - m_bdatChunkReceived += received; - } - - if (m_bdatChunkReceived == m_bdatChunkSize) - { - m_state = STATE_COMMAND; - } - } - - processCommand(); - } + vmime::ref <vmime::message> msg = vmime::create <SMTPBigTestMessage4MB>(); - void processCommand() - { - vmime::string line; - - if (!localReceiveLine(line)) - return; - - 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 == "EHLO") - { - localSend("250-test.vmime.org says hello\r\n"); - localSend("250 CHUNKING\r\n"); - - m_ehloSent = true; - } - else if (cmd == "HELO") - { - VASSERT("Client must not send the HELO command, as EHLO succeeded", false); - } - else if (cmd == "MAIL") - { - VASSERT("The MAIL command must be sent only one time", !m_mailSent); - - localSend("250 OK\r\n"); - - m_mailSent = true; - } - else if (cmd == "RCPT") - { - localSend("250 OK, recipient accepted\r\n"); - - m_rcptSent = true; - } - else if (cmd == "DATA") - { - VASSERT("BDAT must be used here!", false); - } - else if (cmd == "BDAT") - { - VASSERT("Client must send the MAIL command", m_mailSent); - VASSERT("Client must send the RCPT command", m_rcptSent); - - unsigned long chunkSize = 0; - iss >> chunkSize; - - std::string last; - iss >> last; - - if (m_bdatChunkCount == 0) - { - VASSERT_EQ("BDAT chunk1 size", 262144, chunkSize); - VASSERT_EQ("BDAT chunk1 last", "", last); - } - else if (m_bdatChunkCount == 1) - { - VASSERT_EQ("BDAT chunk2 size", 262144, chunkSize); - VASSERT_EQ("BDAT chunk2 last", "", last); - } - else if (m_bdatChunkCount == 2) - { - VASSERT_EQ("BDAT chunk3 size", 4712, chunkSize); - VASSERT_EQ("BDAT chunk3 last", "LAST", last); - } - else - { - VASSERT("No more BDAT command should be issued!", false); - } - - m_bdatChunkSize = chunkSize; - m_bdatChunkReceived = 0; - m_bdatChunkCount++; - m_state = STATE_DATA; - - localSend("250 chunk received\r\n"); - } - else if (cmd == "NOOP") - { - localSend("250 Completed\r\n"); - } - else if (cmd == "QUIT") - { - localSend("221 test.vmime.org Service closing transmission channel\r\n"); - - m_quitSent = true; - } - else - { - localSend("502 Command not implemented\r\n"); - } - - break; - } - - } - - processCommand(); + VASSERT_THROW("Connection", tr->send(msg, exp, recips), + vmime::exceptions::message_size_exceeds_max_limits); } -private: - - enum State + void testSize_NoChunking() { - STATE_NOT_CONNECTED, - STATE_COMMAND, - STATE_DATA - }; + vmime::ref <vmime::net::session> session = + vmime::create <vmime::net::session>(); - int m_state; - int m_bdatChunkCount; - int m_bdatChunkSize, m_bdatChunkReceived; + vmime::ref <vmime::net::transport> tr = session->getTransport + (vmime::utility::url("smtp://localhost")); - bool m_ehloSent, m_mailSent, m_rcptSent, m_quitSent; -}; + tr->setSocketFactory(vmime::create <testSocketFactory <bigMessageSMTPTestSocket <false> > >()); + tr->setTimeoutHandlerFactory(vmime::create <testTimeoutHandlerFactory>()); + tr->connect(); -class SMTPTestMessage : public vmime::message -{ -public: + VASSERT("Test server should report it supports the SIZE extension!", + tr.dynamicCast <vmime::net::smtp::SMTPTransport>()->getConnection()->hasExtension("SIZE")); - vmime::utility::stream::size_type getChunkBufferSize() const - { - static vmime::net::smtp::SMTPChunkingOutputStreamAdapter chunkStream(NULL); - return chunkStream.getBlockSize(); - } - - const std::vector <vmime::string>& getChunks() const - { - static std::vector <vmime::string> chunks; + vmime::mailbox exp("[email protected]"); - if (chunks.size() == 0) - { - chunks.push_back(vmime::string(1000, 'A')); - chunks.push_back(vmime::string(3000, 'B')); - chunks.push_back(vmime::string(500000, 'C')); - chunks.push_back(vmime::string(25000, 'D')); - } + vmime::mailboxList recips; + recips.appendMailbox(vmime::create <vmime::mailbox>("[email protected]")); - return chunks; - } + vmime::ref <vmime::message> msg = vmime::create <SMTPBigTestMessage4MB>(); - void generateImpl(const vmime::generationContext& /* ctx */, - vmime::utility::outputStream& outputStream, - const vmime::string::size_type /* curLinePos */ = 0, - vmime::string::size_type* /* newLinePos */ = NULL) const - { - for (unsigned int i = 0, n = getChunks().size() ; i < n ; ++i) - { - const vmime::string& chunk = getChunks()[i]; - outputStream.write(chunk.data(), chunk.size()); - } + VASSERT_THROW("Connection", tr->send(msg, exp, recips), + vmime::exceptions::message_size_exceeds_max_limits); } -}; +VMIME_TEST_SUITE_END |