MORDOR_UNITTEST(SSLStream, forceDuplex) { WorkerPool pool; std::pair<Stream::ptr, Stream::ptr> pipes = pipeStream(); SSLStream::ptr sslserver(new SSLStream(pipes.first, false)); SSLStream::ptr sslclient(new SSLStream(pipes.second, true)); Stream::ptr server = sslserver, client = sslclient; int sequence = 0; pool.schedule(boost::bind(&accept, sslserver)); sslclient->connect(); pool.dispatch(); pool.schedule(boost::bind(&readWorld, client, boost::ref(sequence))); pool.dispatch(); MORDOR_TEST_ASSERT_EQUAL(++sequence, 2); // Read is pending client->write("hello"); client->flush(false); pool.dispatch(); server->write("world"); server->flush(false); pool.dispatch(); MORDOR_TEST_ASSERT_EQUAL(++sequence, 4); }
// Similar to above, but after the scheduler has stopped, yielding // to it again should implicitly restart it MORDOR_UNITTEST(Scheduler, hijackMultipleDispatch) { Fiber::ptr doNothingFiber(new Fiber(&doNothing)); WorkerPool pool; MORDOR_TEST_ASSERT_EQUAL(Scheduler::getThis(), &pool); pool.schedule(doNothingFiber); MORDOR_TEST_ASSERT_EQUAL(doNothingFiber->state(), Fiber::INIT); pool.dispatch(); MORDOR_TEST_ASSERT_EQUAL(doNothingFiber->state(), Fiber::TERM); doNothingFiber->reset(); pool.schedule(doNothingFiber); MORDOR_TEST_ASSERT_EQUAL(doNothingFiber->state(), Fiber::INIT); pool.dispatch(); MORDOR_TEST_ASSERT_EQUAL(doNothingFiber->state(), Fiber::TERM); }
MORDOR_UNITTEST(SSLStream, duplexStress) { WorkerPool pool; // Force more fiber context switches by having a smaller buffer std::pair<Stream::ptr, Stream::ptr> pipes = pipeStream(1024); SSLStream::ptr sslserver(new SSLStream(pipes.first, false)); SSLStream::ptr sslclient(new SSLStream(pipes.second, true)); pool.schedule(boost::bind(&accept, sslserver)); sslclient->connect(); pool.dispatch(); // Transfer 1 MB long long toTransfer = 1024 * 1024; std::vector<boost::function<void ()> > dgs; bool complete1 = false, complete2 = false, complete3 = false, complete4 = false; dgs.push_back(boost::bind(&writeLotsaData, sslserver, toTransfer, boost::ref(complete1))); dgs.push_back(boost::bind(&readLotsaData, sslserver, toTransfer, boost::ref(complete2))); dgs.push_back(boost::bind(&writeLotsaData, sslclient, toTransfer, boost::ref(complete3))); dgs.push_back(boost::bind(&readLotsaData, sslclient, toTransfer, boost::ref(complete4))); parallel_do(dgs); MORDOR_ASSERT(complete1); MORDOR_ASSERT(complete2); MORDOR_ASSERT(complete3); MORDOR_ASSERT(complete4); }
MORDOR_UNITTEST(SSLStream, basic) { WorkerPool pool; std::pair<Stream::ptr, Stream::ptr> pipes = pipeStream(); SSLStream::ptr sslserver(new SSLStream(pipes.first, false)); SSLStream::ptr sslclient(new SSLStream(pipes.second, true)); pool.schedule(boost::bind(&accept, sslserver)); sslclient->connect(); pool.dispatch(); Stream::ptr server = sslserver, client = sslclient; char buf[6]; buf[5] = '\0'; client->write("hello"); client->flush(false); MORDOR_TEST_ASSERT_EQUAL(server->read(buf, 5), 5u); MORDOR_TEST_ASSERT_EQUAL((const char *)buf, "hello"); server->write("world"); server->flush(false); MORDOR_TEST_ASSERT_EQUAL(client->read(buf, 5), 5u); MORDOR_TEST_ASSERT_EQUAL((const char *)buf, "world"); }
MORDOR_UNITTEST(PipeStream, cancelOnBlockingWriter) { std::pair<Stream::ptr, Stream::ptr> pipe = pipeStream(5); WorkerPool pool; int sequence = 1; pool.schedule(Fiber::ptr(new Fiber(boost::bind(&cancelOnBlockingWriter, pipe.first, boost::ref(sequence))))); Scheduler::yield(); MORDOR_TEST_ASSERT_EQUAL(++sequence, 3); pipe.first->cancelWrite(); pool.dispatch(); MORDOR_TEST_ASSERT_EQUAL(++sequence, 5); }
// When hijacking the calling thread, you can stop() from anywhere within // it MORDOR_UNITTEST(Scheduler, stopScheduledHijack) { WorkerPool pool; pool.schedule(boost::bind(&Scheduler::stop, &pool)); pool.dispatch(); }