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