TEST_F(ContextEnumeratorTest, ComplexRemovalInterference) { static const size_t nChildren = 50; // This time we use a vector, and we pop from the back of the vector unpredictably: std::vector<std::shared_ptr<CoreContext>> children(nChildren); for(size_t i = nChildren; i--;) children.push_back(AutoCreateContext()); // Shuffle the collection to prevent the order here from being equivalent to the order in the context std::random_shuffle(children.begin(), children.end()); // These are the elements actually encountered in the enumeration, held here to prevent expiration in the // event that we enumerate a context which should have already been evicted std::unordered_set<std::shared_ptr<CoreContext>> enumerated; // These are the elements eliminated from the vector. By the time we're done the should all be expired. std::vector<std::weak_ptr<CoreContext>> eliminated; // Go through the enumeration, the totals should line up by the time we're done: for(const auto& cur : CurrentContextEnumerator()) { enumerated.insert(cur); // Pull off the last element: auto removed = children.back(); children.pop_back(); // If we haven't enumerated this element already, we want to mark it as eliminated-before-enumerated if(!enumerated.count(removed)) eliminated.push_back(removed); } // Now verify that nothing we eliminated was enumerated: for(auto& cur : eliminated) ASSERT_TRUE(cur.expired()) << "Found an element that was iterated after it should have been unreachable"; }
static std::vector<std::shared_ptr<CoreContext>> create(void) { // Create a bunch of subcontexts from here std::vector<std::shared_ptr<CoreContext>> contexts(n); for (size_t i = n; i--;) contexts[i] = AutoCreateContext(); return contexts; }
TEST_F(ContextEnumeratorTest, SimpleRemovalInterference) { static const size_t nChildren = 5; // Create a few contexts which we intend to destroy as we go along: std::unordered_set<std::shared_ptr<CoreContext>> contexts; for(size_t i = nChildren; i--;) contexts.insert(AutoCreateContext()); // Also add ourselves: contexts.insert(AutoCurrentContext()); // Enumerate contexts, and remove them from the set: size_t nRemoved = 0; for(const auto& cur : CurrentContextEnumerator()) { ASSERT_TRUE(!!contexts.count(cur)) << "Failed to find a context enumerated by the context enumerator"; contexts.erase(cur); nRemoved++; } // Verify we got the number removed we expected: ASSERT_EQ(nChildren + 1UL, nRemoved) << "Context enumerator did not remove the expected number of children"; }