chromium/base/allocator/partition_alloc_support_unittest.cc

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/allocator/partition_alloc_support.h"

#include <array>
#include <string>
#include <utility>
#include <vector>

#include "base/allocator/partition_alloc_features.h"
#include "base/test/gtest_util.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "build/build_config.h"
#include "partition_alloc/buildflags.h"
#include "partition_alloc/dangling_raw_ptr_checks.h"
#include "partition_alloc/partition_alloc_base/cpu.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base::allocator {

AllOf;
HasSubstr;

TEST(PartitionAllocSupportTest,
     ProposeSyntheticFinchTrials_DanglingPointerDetector) {}

// - Death tests misbehave on Android, http://crbug.com/643760.
#if PA_BUILDFLAG(ENABLE_DANGLING_RAW_PTR_CHECKS) && !BUILDFLAG(IS_ANDROID) && \
    defined(GTEST_HAS_DEATH_TEST)

namespace {

// Install dangling raw_ptr handler and restore them when going out of scope.
class ScopedInstallDanglingRawPtrChecks {};

}  // namespace

TEST(PartitionAllocDanglingPtrChecks, Basic) {}

// The StackTrace buffer might run out of storage and not record where the
// memory was freed. Anyway, it must still report the error.
TEST(PartitionAllocDanglingPtrChecks, FreeNotRecorded) {}

// TODO(crbug.com/40260713): Check for leaked refcount on Android.
#if BUILDFLAG(IS_ANDROID)
// Some raw_ptr might never release their refcount. Make sure this cause a
// crash on exit.
TEST(PartitionAllocDanglingPtrChecks, ReleaseNotRecorded) {
  EXPECT_DEATH(
      {
        ScopedInstallDanglingRawPtrChecks scoped_install_dangling_checks;
        partition_alloc::GetDanglingRawPtrDetectedFn()(42);
      },
      HasSubstr("A freed allocation is still referenced by a dangling pointer "
                "at exit, or at test end. Leaked raw_ptr/raw_ref "
                "could cause PartitionAlloc's quarantine memory bloat."
                "\n\n"
                "Memory was released on:"));
}
#endif

// Getting the same allocation reported twice in a row, without matching
// `DanglingRawPtrReleased` in between is unexpected. Make sure this kind of
// potential regression would be detected.
TEST(PartitionAllocDanglingPtrChecks, DoubleDetection) {}

// Free and release from two different tasks with cross task dangling pointer
// detection enabled.
TEST(PartitionAllocDanglingPtrChecks, CrossTask) {}

TEST(PartitionAllocDanglingPtrChecks, CrossTaskIgnoredFailuresClearsCache) {}

TEST(PartitionAllocDanglingPtrChecks, CrossTaskIgnoresNoTask) {}

TEST(PartitionAllocDanglingPtrChecks, CrossTaskIgnoresSameTask) {}

TEST(PartitionAllocDanglingPtrChecks, CrossTaskNoFreeConsideredCrossTask) {}

TEST(PartitionAllocDanglingPtrChecks,
     ExtractDanglingPtrSignatureMacStackTrace) {}

TEST(PartitionAllocDanglingPtrChecks, ExtractDanglingPtrSignatureMacTaskTrace) {}

TEST(PartitionAllocDanglingPtrChecks,
     ExtractDanglingPtrSignatureWindowsStackTrace) {}

TEST(PartitionAllocDanglingPtrChecks,
     ExtractDanglingPtrSignatureWindowsTaskTrace) {}

#endif

#if PA_BUILDFLAG(HAS_MEMORY_TAGGING)
TEST(PartitionAllocSupportTest,
     ProposeSyntheticFinchTrials_MemoryTaggingDogfood) {
  {
    test::ScopedFeatureList scope;
    scope.InitWithFeatures({}, {features::kPartitionAllocMemoryTagging});

    auto trials = ProposeSyntheticFinchTrials();

    auto group_iter = trials.find("MemoryTaggingDogfood");
    EXPECT_EQ(group_iter, trials.end());
  }

  {
    test::ScopedFeatureList scope;
    scope.InitWithFeatures({features::kPartitionAllocMemoryTagging}, {});

    auto trials = ProposeSyntheticFinchTrials();

    std::string expectation =
        partition_alloc::internal::base::CPU::GetInstanceNoAllocation()
                .has_mte()
            ? "Enabled"
            : "Disabled";
    auto group_iter = trials.find("MemoryTaggingDogfood");
    EXPECT_NE(group_iter, trials.end());
    EXPECT_EQ(group_iter->second, expectation);
  }
}
#endif  // PA_BUILDFLAG(HAS_MEMORY_TAGGING)

class MemoryReclaimerSupportTest : public ::testing::Test {};

TEST_F(MemoryReclaimerSupportTest, StartSeveralTimes) {}

TEST_F(MemoryReclaimerSupportTest, ForegroundToBackground) {}

TEST_F(MemoryReclaimerSupportTest, ForegroundToBackgroundAndBack) {}

}  // namespace base::allocator