#include "components/heap_profiling/in_process/heap_profiler_controller.h"
#include <atomic>
#include <iomanip>
#include <memory>
#include <optional>
#include <ostream>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include "base/allocator/dispatcher/notification_data.h"
#include "base/allocator/dispatcher/subsystem.h"
#include "base/auto_reset.h"
#include "base/barrier_closure.h"
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/containers/enum_set.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/json/json_writer.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/metrics_hashes.h"
#include "base/notreached.h"
#include "base/process/launch.h"
#include "base/process/process.h"
#include "base/profiler/process_type.h"
#include "base/sampling_heap_profiler/poisson_allocation_sampler.h"
#include "base/sampling_heap_profiler/sampling_heap_profiler.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/bind_post_task.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/multiprocess_test.h"
#include "base/test/scoped_command_line.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/test/test_timeouts.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "components/heap_profiling/in_process/browser_process_snapshot_controller.h"
#include "components/heap_profiling/in_process/child_process_snapshot_controller.h"
#include "components/heap_profiling/in_process/heap_profiler_parameters.h"
#include "components/heap_profiling/in_process/mojom/snapshot_controller.mojom.h"
#include "components/heap_profiling/in_process/mojom/test_connector.mojom.h"
#include "components/heap_profiling/in_process/switches.h"
#include "components/metrics/call_stacks/call_stack_profile_builder.h"
#include "components/metrics/public/mojom/call_stack_profile_collector.mojom.h"
#include "components/version_info/channel.h"
#include "mojo/core/embedder/scoped_ipc_support.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote_set.h"
#include "mojo/public/cpp/bindings/unique_receiver_set.h"
#include "mojo/public/cpp/platform/platform_channel.h"
#include "mojo/public/cpp/system/invitation.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"
#include "third_party/metrics_proto/call_stack_profile.pb.h"
#include "third_party/metrics_proto/execution_context.pb.h"
#include "third_party/metrics_proto/sampled_profile.pb.h"
namespace metrics {
void PrintTo(const SampledProfile& profile, std::ostream* os) { … }
}
namespace heap_profiling {
namespace {
#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID)
#define ENABLE_MULTIPROCESS_TESTS …
#else
#define ENABLE_MULTIPROCESS_TESTS …
#endif
FeatureRef;
FeatureRefAndParams;
ProcessType;
using ProcessTypeSet =
base::EnumSet<ProcessType, ProcessType::kUnknown, ProcessType::kMax>;
ProfileCollectorCallback;
AllocationNotificationData;
AllocationSubsystem;
FreeNotificationData;
ScopedMuteHookedSamplesForTesting;
ScopedSuppressRandomnessForTesting;
_;
AllOf;
Conditional;
ElementsAre;
Ge;
IsEmpty;
Lt;
Optional;
Property;
ResultOf;
UnorderedElementsAreArray;
constexpr size_t kSamplingRate = …;
constexpr size_t kAllocationSize = …;
class TestCallStackProfileCollector final
: public metrics::mojom::CallStackProfileCollector { … };
class ScopedCallbacks { … };
class ProfilerSetUpMixin { … };
#if ENABLE_MULTIPROCESS_TESTS
constexpr char kTestChildTypeSwitch[] = …;
constexpr char kTestNumAllocationsSwitch[] = …;
class MultiprocessTestChild final : public mojom::TestConnector,
public ProfilerSetUpMixin { … };
class MultiprocessTestParent { … };
#endif
class MockSnapshotController : public mojom::SnapshotController { … };
struct FeatureTestParams { … };
base::FieldTrialParams FeatureTestParams::ToFieldTrialParams() const { … }
std::vector<FeatureRefAndParams> FeatureTestParams::GetEnabledFeatures() const { … }
std::vector<FeatureRef> FeatureTestParams::GetDisabledFeatures() const { … }
std::ostream& operator<<(std::ostream& os, const FeatureTestParams& params) { … }
class HeapProfilerControllerTest
: public ::testing::TestWithParam<FeatureTestParams>,
public ProfilerSetUpMixin { … };
INSTANTIATE_TEST_SUITE_P(…);
#if !BUILDFLAG(IS_ANDROID)
TEST_P(HeapProfilerControllerTest, ProfileCollectionsScheduler) { … }
#endif
TEST_P(HeapProfilerControllerTest, UnhandledProcess) { … }
TEST_P(HeapProfilerControllerTest, EmptyProfile) { … }
constexpr FeatureTestParams kChannelConfigs[] = …;
HeapProfilerControllerChannelTest;
INSTANTIATE_TEST_SUITE_P(…);
TEST_P(HeapProfilerControllerChannelTest, StableChannel) { … }
TEST_P(HeapProfilerControllerChannelTest, CanaryChannel) { … }
TEST_P(HeapProfilerControllerChannelTest, UnknownChannel) { … }
constexpr FeatureTestParams kProcessConfigs[] = …;
HeapProfilerControllerProcessTest;
INSTANTIATE_TEST_SUITE_P(…);
TEST_P(HeapProfilerControllerProcessTest, BrowserProcess) { … }
TEST_P(HeapProfilerControllerProcessTest, ChildProcess) { … }
#if ENABLE_MULTIPROCESS_TESTS
auto GetProfileMetadataFunc(std::string_view name) { … }
constexpr FeatureTestParams kMultipleChildConfigs[] = …;
HeapProfilerControllerMultipleChildTest;
INSTANTIATE_TEST_SUITE_P(…);
MULTIPROCESS_TEST_MAIN(HeapProfilerControllerChildMain) { … }
TEST_P(HeapProfilerControllerMultipleChildTest, EndToEnd) { … }
#endif
}
}