示例#1
0
TEST(RequestContext, SimpleTest) {
  TEventBase base;

  EXPECT_FALSE(RequestContext::create());
  EXPECT_TRUE(RequestContext::create());
  EXPECT_TRUE(RequestContext::get() != nullptr);

  EXPECT_EQ(nullptr, RequestContext::get()->getContextData("test"));

  RequestContext::get()->setContextData(
    "test",
    std::unique_ptr<TestData>(new TestData(10)));
  base.runInEventBaseThread([&](){
      EXPECT_TRUE(RequestContext::get() != nullptr);
      auto data = dynamic_cast<TestData*>(
        RequestContext::get()->getContextData("test"))->data_;
      EXPECT_EQ(10, data);
      base.terminateLoopSoon();
    });
  auto th = std::thread([&](){
      base.loopForever();
  });
  th.join();
  EXPECT_TRUE(RequestContext::get() != nullptr);
  auto a = dynamic_cast<TestData*>(
    RequestContext::get()->getContextData("test"));
  auto data = a->data_;
  EXPECT_EQ(10, data);

  RequestContext::setContext(std::shared_ptr<RequestContext>());
  // There should always be a default context
  EXPECT_TRUE(nullptr != RequestContext::get());
}
 void async_tm_update(unique_ptr<HandlerCallback<int32_t>> callback,
                      int32_t currentIndex) override {
   auto callbackp = callback.release();
   EXPECT_EQ(currentIndex, expectIndex_);
   expectIndex_++;
   TEventBase *eb = callbackp->getEventBase();
   callbackp->resultInThread(currentIndex);
   if (expectIndex_ == lastIndex_) {
     success_ = true;
     eb->runInEventBaseThread([eb] { eb->terminateLoopSoon(); });
   }
 }
void QueueTest::multiConsumer() {
  uint32_t numConsumers = 8;
  int numMessages = 10000;

  // Create several consumers each running in their own TEventBase thread
  vector<QueueConsumer> consumers(numConsumers);
  vector<ScopedEventBaseThread> threads(numConsumers);

  for (uint32_t consumerIdx = 0; consumerIdx < numConsumers; ++consumerIdx) {
    QueueConsumer* consumer = &consumers[consumerIdx];

    consumer->fn = [consumer, consumerIdx, this](int value) {
      // Treat 0 as a signal to stop.
      if (value == 0) {
        consumer->stopConsuming();
        // Put a message on the terminationQueue to indicate we have stopped
        terminationQueue.putMessage(consumerIdx);
      }
    };

    TEventBase* eventBase = threads[consumerIdx].getEventBase();
    eventBase->runInEventBaseThread([eventBase, consumer, this] {
      consumer->startConsuming(eventBase, &queue);
    });
  }

  // Now add a number of messages from this thread
  // Start at 1 rather than 0, since 0 is the signal to stop.
  for (int n = 1; n < numMessages; ++n) {
    queue.putMessage(n);
  }
  // Now add a 0 for each consumer, to signal them to stop
  for (int n = 0; n < numConsumers; ++n) {
    queue.putMessage(0);
  }

  // Wait until we get notified that all of the consumers have stopped
  // We use a separate notification queue for this.
  QueueConsumer terminationConsumer;
  vector<uint32_t> consumersStopped(numConsumers, 0);
  uint32_t consumersRemaining = numConsumers;
  terminationConsumer.fn = [&](int consumerIdx) {
    --consumersRemaining;
    if (consumersRemaining == 0) {
      terminationConsumer.stopConsuming();
    }

    BOOST_REQUIRE(consumerIdx >= 0);
    BOOST_REQUIRE(consumerIdx < numConsumers);
    ++consumersStopped[consumerIdx];
  };
  TEventBase eventBase;
  terminationConsumer.startConsuming(&eventBase, &terminationQueue);
  eventBase.loop();

  // Verify that we saw exactly 1 stop message for each consumer
  for (uint32_t n = 0; n < numConsumers; ++n) {
    BOOST_CHECK_EQUAL(consumersStopped[n], 1);
  }

  // Validate that every message sent to the main queue was received exactly
  // once.
  vector<int> messageCount(numMessages, 0);
  for (uint32_t n = 0; n < numConsumers; ++n) {
    for (int msg : consumers[n].messages) {
      BOOST_REQUIRE(msg >= 0);
      BOOST_REQUIRE(msg < numMessages);
      ++messageCount[msg];
    }
  }

  // 0 is the signal to stop, and should have been received once by each
  // consumer
  BOOST_CHECK_EQUAL(messageCount[0], numConsumers);
  // All other messages should have been received exactly once
  for (int n = 1; n < numMessages; ++n) {
    BOOST_CHECK_EQUAL(messageCount[n], 1);
  }
}