| Index: base/trace_event/event_filter_registry_unittest.cc
|
| diff --git a/base/trace_event/event_filter_registry_unittest.cc b/base/trace_event/event_filter_registry_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6c01571a3f22806fc5ca43f6638cda209d087b96
|
| --- /dev/null
|
| +++ b/base/trace_event/event_filter_registry_unittest.cc
|
| @@ -0,0 +1,102 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "base/trace_event/event_filter_registry.h"
|
| +
|
| +#include <string>
|
| +
|
| +#include "base/memory/ptr_util.h"
|
| +#include "base/trace_event/trace_event_filter.h"
|
| +#include "base/trace_event/trace_event_filter_test_utils.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace base {
|
| +namespace trace_event {
|
| +
|
| +class TraceEventFilterRegistryTest : public testing::Test {
|
| + public:
|
| + void SetUp() override { EventFilterRegistry::ResetForTesting(); }
|
| + void TearDown() override { EventFilterRegistry::ResetForTesting(); }
|
| +
|
| + uint32_t GetActiveFiltersCount() {
|
| + uint32_t count = 0;
|
| + for (auto it = EventFilterRegistry::GetActiveFilters(); it.IsValid();
|
| + it.MoveNext(), count++) {
|
| + }
|
| + return count;
|
| + }
|
| +
|
| + EventFilterRegistry::Iterator GetLastActiveFilter() {
|
| + EventFilterRegistry::Iterator it = EventFilterRegistry::GetActiveFilters();
|
| + uint32_t count = GetActiveFiltersCount();
|
| + for (uint32_t i = 1; i < count; i++)
|
| + it.MoveNext();
|
| + return it;
|
| + }
|
| +};
|
| +
|
| +TEST_F(TraceEventFilterRegistryTest, RegistrationAndUnregistration) {
|
| + // Register one instance of TestEventFilter.
|
| + TestEventFilter* filter_ptr = new TestEventFilter(nullptr);
|
| + EventFilterRegistry::RegisterFilter(WrapUnique(filter_ptr));
|
| + ASSERT_EQ(1u, GetActiveFiltersCount());
|
| + ASSERT_EQ(0u, GetLastActiveFilter().GetIndex());
|
| + ASSERT_EQ(filter_ptr, &*GetLastActiveFilter());
|
| +
|
| + // Register other 3 filters and check that the validity of the Iterator
|
| + // chain.
|
| + for (uint32_t i = 0; i < 3; i++) {
|
| + filter_ptr = new TestEventFilter(nullptr);
|
| + EventFilterRegistry::RegisterFilter(WrapUnique(filter_ptr));
|
| + ASSERT_EQ(i + 2, GetActiveFiltersCount());
|
| + ASSERT_EQ(i + 1, GetLastActiveFilter().GetIndex());
|
| + ASSERT_EQ(filter_ptr, &*GetLastActiveFilter());
|
| + }
|
| +
|
| + EventFilterRegistry::UnregisterAllFilters();
|
| + ASSERT_EQ(0u, GetActiveFiltersCount());
|
| +
|
| + for (uint32_t i = 0; i < 3; i++) {
|
| + filter_ptr = new TestEventFilter(nullptr);
|
| + EventFilterRegistry::RegisterFilter(WrapUnique(filter_ptr));
|
| + ASSERT_EQ(i + 1, GetActiveFiltersCount());
|
| + ASSERT_EQ(i + 4, GetLastActiveFilter().GetIndex());
|
| + ASSERT_EQ(filter_ptr, &*GetLastActiveFilter());
|
| + }
|
| +}
|
| +
|
| +// Tests that filters are destroyed at some point in the future (i.e. not leaked
|
| +// forever) but not immediately after unregistration (so that TRACE_EVENT macros
|
| +// that hit filters being unregistered from another thread don't race on UAF).
|
| +TEST_F(TraceEventFilterRegistryTest, DeferredDestruction) {
|
| + TestEventFilter::HitsCounter hits;
|
| + for (uint32_t i = 0; i < 3; i++)
|
| + EventFilterRegistry::RegisterFilter(MakeUnique<TestEventFilter>(nullptr));
|
| +
|
| + // Check that filters are not destroyed immediately after unregistration.
|
| + EventFilterRegistry::UnregisterAllFilters();
|
| + ASSERT_EQ(0u, hits.dtor_hit_count);
|
| +
|
| + // Register and unregister enough filters to run out of the circular buffer.
|
| + for (uint32_t i = 0; i < 256; i++) {
|
| + EventFilterRegistry::RegisterFilter(MakeUnique<TestEventFilter>(nullptr));
|
| + EventFilterRegistry::UnregisterAllFilters();
|
| + }
|
| + // A non-zero number of filters must have been desotryed at this point. The
|
| + // exact number depends on internal implementation details (i.e. kMaxFilter).
|
| + const uint32_t num_last_dtor_hits = hits.dtor_hit_count;
|
| + ASSERT_GT(num_last_dtor_hits, 0u);
|
| +
|
| + // Register and unregister other 11 filters. Assuming that we exhausted the
|
| + // circular buffer above, at least 11 of the previous filters should be
|
| + // destroyed.
|
| + for (uint32_t i = 0; i < 11; i++) {
|
| + EventFilterRegistry::RegisterFilter(MakeUnique<TestEventFilter>(nullptr));
|
| + EventFilterRegistry::UnregisterAllFilters();
|
| + }
|
| + ASSERT_GE(hits.dtor_hit_count - num_last_dtor_hits, 11u);
|
| +}
|
| +
|
| +} // namespace trace_event
|
| +} // namespace base
|
|
|