TEST_F(AutoPacketFactoryTest, AutoPacketStatistics) { // Create a context, fill it up, kick it off: AutoCurrentContext ctxt; AutoRequired<DelaysAutoPacketsOneMS> dapoms; AutoRequired<AutoPacketFactory> factory; ctxt->Initiate(); int numPackets = 20; // Send 20 packets which should all be delayed 1ms for (int i = 0; i < numPackets; ++i) { auto packet = factory->NewPacket(); packet->Decorate(i); } // Shutdown our context, and rundown our factory ctxt->SignalShutdown(); factory->Wait(); // Ensure that the statistics are not too wrong // We delayed each packet by one ms, and our statistics are given in nanoseconds double packetDelay = (double) std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::milliseconds(1)).count(); ASSERT_EQ(numPackets, factory->GetTotalPacketCount()) << "The factory did not get enough packets"; ASSERT_LE(packetDelay, factory->GetMeanPacketLifetime()) << "The mean packet lifetime was less than the delay on each packet"; }
TEST_F(AutoPacketFactoryTest, WaitRunsDownAllPackets) { AutoCurrentContext()->Initiate(); // Create a factory in our context, factory had better be started: AutoRequired<AutoPacketFactory> factory; ASSERT_TRUE(factory->IsRunning()) << "Factory was not started even though it was a member of an initiated context"; // Make the thread create and hold a packet, and then return AutoRequired<IssuesPacketWaitsThenQuits> ipwtq; // Shutdown context AutoCurrentContext()->SignalShutdown(); // Now we're going to try to run down the factory: factory->Wait(); // Verify that the thread has quit: ASSERT_TRUE(ipwtq->m_hasQuit) << "AutoPacketFactory::Wait returned prematurely"; }
TEST_F(ObjectPoolTest, VerifyAsynchronousUsage) { AutoCreateContext ctxt; CurrentContextPusher pshr(ctxt); AutoRequired<SimpleThreadedT<PooledObject>> obj; AutoFired<SharedPtrReceiver<PooledObject>> spr; ObjectPool<PooledObject> pool(3); { // Obtain the pool limit in objects: std::shared_ptr<PooledObject> obj1, obj2, obj3; pool(obj1); pool(obj2); pool(obj3); ASSERT_TRUE(nullptr != obj1.get()) << "Failed to obtain an entry from a new object pool"; // Block--verify that we _do not_ get any of those objects back while they are // still outstanding. { auto obj4 = pool.WaitFor(std::chrono::milliseconds(1)); EXPECT_TRUE(obj4 == nullptr) << "Pool issued another element even though it should have hit its outstanding limit"; } // Now we kick off threads: AutoCurrentContext()->Initiate(); // Fire off a few events: spr(&SharedPtrReceiver<PooledObject>::OnEvent)(obj1); spr(&SharedPtrReceiver<PooledObject>::OnEvent)(obj2); spr(&SharedPtrReceiver<PooledObject>::OnEvent)(obj3); } // This should return more or less right away as objects become available: { auto obj4 = pool.WaitFor(std::chrono::milliseconds(10)); EXPECT_TRUE(obj4 != nullptr) << "Object pool failed to be notified that it received a new element"; } // Cause the thread to quit: *obj += [&obj] { obj->Stop(); }; obj->Wait(); }