#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "components/metrics/metrics_service.h"
#include <string>
#include "base/command_line.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/process/memory.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
#include "chrome/browser/metrics/chrome_metrics_service_client.h"
#include "chrome/browser/metrics/chrome_metrics_services_manager_client.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/metrics/enabled_state_provider.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/metrics/metrics_reporting_default_state.h"
#include "components/metrics/metrics_service.h"
#include "components/metrics/metrics_switches.h"
#include "components/metrics/persistent_histograms.h"
#include "components/metrics/stability_metrics_helper.h"
#include "components/metrics_services_manager/metrics_services_manager.h"
#include "components/prefs/json_pref_store.h"
#include "components/prefs/pref_service.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "net/base/filename_util.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/blink/public/common/chrome_debug_urls.h"
#include "ui/base/window_open_disposition.h"
#include "url/gurl.h"
#if BUILDFLAG(IS_POSIX)
#include <sys/wait.h>
#endif
#if BUILDFLAG(IS_WIN)
#include "sandbox/win/src/sandbox_types.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_LACROS)
#include "chromeos/startup/browser_params_proxy.h"
#endif
namespace {
#if BUILDFLAG(IS_WIN)
void VerifyRendererExitCodeIsSignal(
const base::HistogramTester& histogram_tester,
int signal) {
histogram_tester.ExpectUniqueSample(
"CrashExitCodes.Renderer", std::abs(static_cast<int32_t>(signal)), 1);
}
#elif BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
void VerifyRendererExitCodeIsSignal(
const base::HistogramTester& histogram_tester,
int signal) { … }
#endif
}
class MetricsServiceBrowserTest : public InProcessBrowserTest { … };
IN_PROC_BROWSER_TEST_F(MetricsServiceBrowserTest, CloseRenderersNormally) { … }
#if defined(ADDRESS_SANITIZER)
#define MAYBE_CrashRenderers …
#define MAYBE_CheckCrashRenderers …
#else
#define MAYBE_CrashRenderers …
#define MAYBE_CheckCrashRenderers …
#endif
IN_PROC_BROWSER_TEST_F(MetricsServiceBrowserTest, MAYBE_CrashRenderers) { … }
#if BUILDFLAG(IS_WIN)
#if defined(ARCH_CPU_ARM64)
#define MAYBE_HeapCorruptionInRenderer …
#else
#define MAYBE_HeapCorruptionInRenderer …
#endif
IN_PROC_BROWSER_TEST_F(MetricsServiceBrowserTest,
MAYBE_HeapCorruptionInRenderer) {
base::HistogramTester histogram_tester;
OpenTabsAndNavigateToCrashyUrl(blink::kChromeUIHeapCorruptionCrashURL);
histogram_tester.ExpectBucketCount("Stability.Counts2",
metrics::StabilityEventType::kPageLoad, 3);
histogram_tester.ExpectBucketCount(
"Stability.Counts2", metrics::StabilityEventType::kRendererCrash, 1);
histogram_tester.ExpectUniqueSample(
"CrashExitCodes.Renderer",
std::abs(static_cast<int32_t>(STATUS_HEAP_CORRUPTION)), 1);
LOG(INFO) << histogram_tester.GetAllHistogramsRecorded();
}
#endif
IN_PROC_BROWSER_TEST_F(MetricsServiceBrowserTest, MAYBE_CheckCrashRenderers) { … }
#if BUILDFLAG(ENABLE_RUST_CRASH)
IN_PROC_BROWSER_TEST_F(MetricsServiceBrowserTest, CrashRenderersInRust) { … }
#endif
#if BUILDFLAG(IS_WIN) && !defined(ADDRESS_SANITIZER)
IN_PROC_BROWSER_TEST_F(MetricsServiceBrowserTest, OOMRenderers) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kDisableInProcessStackTraces);
base::HistogramTester histogram_tester;
OpenTabsAndNavigateToCrashyUrl(blink::kChromeUIMemoryExhaustURL);
histogram_tester.ExpectBucketCount("Stability.Counts2",
metrics::StabilityEventType::kPageLoad, 3);
histogram_tester.ExpectBucketCount(
"Stability.Counts2", metrics::StabilityEventType::kRendererCrash, 1);
#if defined(ARCH_CPU_64_BITS)
const base::Bucket expected_possible_exit_codes[] = {
base::Bucket(
std::abs(static_cast<int32_t>(sandbox::SBOX_FATAL_MEMORY_EXCEEDED)),
1),
base::Bucket(std::abs(static_cast<int32_t>(base::win::kOomExceptionCode)),
1)};
#else
const base::Bucket expected_possible_exit_codes[] = {base::Bucket(
std::abs(static_cast<int32_t>(base::win::kOomExceptionCode)), 1)};
#endif
EXPECT_THAT(histogram_tester.GetAllSamples("CrashExitCodes.Renderer"),
::testing::IsSubsetOf(expected_possible_exit_codes));
}
#endif
class MetricsServiceBrowserFilesTest : public InProcessBrowserTest { … };
class MetricsServiceBrowserDoUploadTest
: public MetricsServiceBrowserFilesTest { … };
IN_PROC_BROWSER_TEST_F(MetricsServiceBrowserDoUploadTest, FilesRemain) { … }
class MetricsServiceBrowserNoUploadTest
: public MetricsServiceBrowserFilesTest { … };
IN_PROC_BROWSER_TEST_F(MetricsServiceBrowserNoUploadTest, FilesRemoved) { … }
class MetricsServiceBrowserSampledOutTest
: public MetricsServiceBrowserFilesTest { … };
IN_PROC_BROWSER_TEST_F(MetricsServiceBrowserSampledOutTest, FilesRemoved) { … }
#if BUILDFLAG(IS_CHROMEOS_LACROS)
IN_PROC_BROWSER_TEST_F(MetricsServiceBrowserTest, EntropyTransfer) {
auto* init_params = chromeos::BrowserParamsProxy::Get();
metrics::MetricsService* metrics_service =
g_browser_process->GetMetricsServicesManager()->GetMetricsService();
if (init_params->EntropySource()) {
EXPECT_EQ(metrics_service->GetLowEntropySource(),
init_params->EntropySource()->low_entropy);
EXPECT_NE(init_params->EntropySource()->low_entropy, -1);
EXPECT_EQ(metrics_service->GetOldLowEntropySource(),
init_params->EntropySource()->old_low_entropy);
EXPECT_EQ(metrics_service->GetPseudoLowEntropySource(),
init_params->EntropySource()->pseudo_low_entropy);
} else {
LOG(WARNING) << "MetricsReportingLacrosBrowserTest.EntropyTransfer "
<< "- Ash version does not support entropy transfer yet";
}
}
#endif