PageRenderTime 305ms CodeModel.GetById 120ms app.highlight 82ms RepoModel.GetById 99ms app.codeStats 0ms

/mordor/tests/ssl_stream.cpp

http://github.com/mozy/mordor
C++ | 139 lines | 115 code | 20 blank | 4 comment | 0 complexity | 5e85b08a2fcf1b48ec4e0b0a520f0337 MD5 | raw file
  1// Copyright (c) 2009 - Mozy, Inc.
  2
  3#include "mordor/iomanager.h"
  4#include "mordor/parallel.h"
  5#include "mordor/streams/hash.h"
  6#include "mordor/streams/null.h"
  7#include "mordor/streams/pipe.h"
  8#include "mordor/streams/random.h"
  9#include "mordor/streams/ssl.h"
 10#include "mordor/streams/transfer.h"
 11#include "mordor/test/test.h"
 12#include "mordor/workerpool.h"
 13
 14using namespace Mordor;
 15
 16static void accept(SSLStream::ptr server)
 17{
 18    server->accept();
 19}
 20
 21MORDOR_UNITTEST(SSLStream, basic)
 22{
 23    WorkerPool pool;
 24    std::pair<Stream::ptr, Stream::ptr> pipes = pipeStream();
 25
 26    SSLStream::ptr sslserver(new SSLStream(pipes.first, false));
 27    SSLStream::ptr sslclient(new SSLStream(pipes.second, true));
 28
 29    pool.schedule(boost::bind(&accept, sslserver));
 30    sslclient->connect();
 31    pool.dispatch();
 32
 33    Stream::ptr server = sslserver, client = sslclient;
 34
 35    char buf[6];
 36    buf[5] = '\0';
 37    client->write("hello");
 38    client->flush(false);
 39    MORDOR_TEST_ASSERT_EQUAL(server->read(buf, 5), 5u);
 40    MORDOR_TEST_ASSERT_EQUAL((const char *)buf, "hello");
 41    server->write("world");
 42    server->flush(false);
 43    MORDOR_TEST_ASSERT_EQUAL(client->read(buf, 5), 5u);
 44    MORDOR_TEST_ASSERT_EQUAL((const char *)buf, "world");
 45}
 46
 47static void writeLotsaData(
 48    Stream::ptr stream, unsigned long long toTransfer, bool &complete, std::string &hash)
 49{
 50    RandomStream::ptr random(new RandomStream());
 51    MD5Stream::ptr src(new MD5Stream(random));
 52    MORDOR_TEST_ASSERT_EQUAL(transferStream(src, stream, toTransfer), toTransfer);
 53    stream->flush();
 54    hash = src->hash();
 55    complete = true;
 56}
 57
 58static void readLotsaData(
 59    Stream::ptr stream, unsigned long long toTransfer, bool &complete, std::string &hash)
 60{
 61    MD5Stream::ptr dest(new MD5Stream(NullStream::get_ptr()));
 62    MORDOR_TEST_ASSERT_EQUAL(transferStream(stream, dest, toTransfer), toTransfer);
 63    hash = dest->hash();
 64    complete = true;
 65}
 66
 67MORDOR_UNITTEST(SSLStream, duplexStress)
 68{
 69    WorkerPool pool;
 70    // Force more fiber context switches by having a smaller buffer
 71    std::pair<Stream::ptr, Stream::ptr> pipes = pipeStream(1024);
 72
 73    SSLStream::ptr sslserver(new SSLStream(pipes.first, false));
 74    SSLStream::ptr sslclient(new SSLStream(pipes.second, true));
 75
 76    pool.schedule(boost::bind(&accept, sslserver));
 77    sslclient->connect();
 78    pool.dispatch();
 79
 80    // Transfer 1 MB
 81    long long toTransfer = 1024 * 1024;
 82    std::vector<boost::function<void ()> > dgs;
 83    bool complete1 = false, complete2 = false, complete3 = false, complete4 = false;
 84    std::string hash1, hash2, hash3, hash4;
 85    dgs.push_back(
 86        boost::bind(&writeLotsaData, sslserver, toTransfer, boost::ref(complete1), boost::ref(hash1)));
 87    dgs.push_back(
 88        boost::bind(&readLotsaData, sslserver, toTransfer, boost::ref(complete2), boost::ref(hash2)));
 89    dgs.push_back(
 90        boost::bind(&writeLotsaData, sslclient, toTransfer, boost::ref(complete3), boost::ref(hash3)));
 91    dgs.push_back(
 92        boost::bind(&readLotsaData, sslclient, toTransfer, boost::ref(complete4), boost::ref(hash4)));
 93    parallel_do(dgs);
 94    MORDOR_ASSERT(complete1);
 95    MORDOR_ASSERT(complete2);
 96    MORDOR_ASSERT(complete3);
 97    MORDOR_ASSERT(complete4);
 98    MORDOR_TEST_ASSERT_EQUAL(hash1, hash4);
 99    MORDOR_TEST_ASSERT_EQUAL(hash2, hash3);
100}
101
102static void readWorld(Stream::ptr stream, int &sequence)
103{
104    MORDOR_TEST_ASSERT_EQUAL(++sequence, 1);
105    char buf[6];
106    buf[5] = '\0';
107    MORDOR_TEST_ASSERT_EQUAL(stream->read(buf, 5), 5u);
108    MORDOR_TEST_ASSERT_EQUAL(++sequence, 3);
109    MORDOR_TEST_ASSERT_EQUAL((const char *)buf, "world");
110}
111
112MORDOR_UNITTEST(SSLStream, forceDuplex)
113{
114    WorkerPool pool;
115    std::pair<Stream::ptr, Stream::ptr> pipes = pipeStream();
116
117    SSLStream::ptr sslserver(new SSLStream(pipes.first, false));
118    SSLStream::ptr sslclient(new SSLStream(pipes.second, true));
119
120    Stream::ptr server = sslserver, client = sslclient;
121
122    int sequence = 0;
123    pool.schedule(boost::bind(&accept, sslserver));
124    sslclient->connect();
125    pool.dispatch();
126
127    pool.schedule(boost::bind(&readWorld, client,
128        boost::ref(sequence)));
129    pool.dispatch();
130    MORDOR_TEST_ASSERT_EQUAL(++sequence, 2);
131    // Read is pending
132    client->write("hello");
133    client->flush(false);
134    pool.dispatch();
135    server->write("world");
136    server->flush(false);
137    pool.dispatch();
138    MORDOR_TEST_ASSERT_EQUAL(++sequence, 4);
139}