123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- // Copyright 2022 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 "ash/system/diagnostics/diagnostics_log_controller.h"
- #include <memory>
- #include <string>
- #include <vector>
- #include "ash/constants/ash_features.h"
- #include "ash/public/cpp/session/session_types.h"
- #include "ash/session/session_controller_impl.h"
- #include "ash/shell.h"
- #include "ash/system/diagnostics/diagnostics_browser_delegate.h"
- #include "ash/system/diagnostics/log_test_helpers.h"
- #include "ash/system/diagnostics/networking_log.h"
- #include "ash/system/diagnostics/routine_log.h"
- #include "ash/system/diagnostics/telemetry_log.h"
- #include "ash/test/ash_test_base.h"
- #include "ash/webui/diagnostics_ui/mojom/network_health_provider.mojom-forward.h"
- #include "ash/webui/diagnostics_ui/mojom/network_health_provider.mojom-shared.h"
- #include "base/files/file_path.h"
- #include "base/files/file_util.h"
- #include "base/files/scoped_temp_dir.h"
- #include "base/test/scoped_feature_list.h"
- #include "components/user_manager/user_type.h"
- #include "testing/gtest/include/gtest/gtest.h"
- namespace ash {
- namespace diagnostics {
- namespace {
- const char kTestSessionLogFileName[] = "test_session_log.txt";
- const char kDiangosticsDirName[] = "diagnostics";
- const char kDefaultUserDir[] = "/fake/user-dir";
- const char kTmpDiagnosticsDir[] = "/tmp/diagnostics";
- const char kTestUserEmail[] = "test-user@gmail.com";
- const char kFakeUserDir[] = "fake-user";
- // Log headers content.
- const char kRoutineLogSubsectionHeader[] = "--- Test Routines ---";
- const char kSystemLogSectionHeader[] = "=== System ===";
- const char kNetworkingLogSectionHeader[] = "=== Networking ===";
- const char kNetworkingLogNetworkInfoHeader[] = "--- Network Info ---";
- const char kNetworkingLogNetworkEventsHeader[] = "--- Network Events ---";
- // Fake delegate used to set the expected user directory path.
- class FakeDiagnosticsBrowserDelegate : public DiagnosticsBrowserDelegate {
- public:
- explicit FakeDiagnosticsBrowserDelegate(
- const base::FilePath path = base::FilePath(kDefaultUserDir))
- : active_user_dir_(path) {}
- ~FakeDiagnosticsBrowserDelegate() override = default;
- base::FilePath GetActiveUserProfileDir() override { return active_user_dir_; }
- private:
- base::FilePath active_user_dir_;
- };
- } // namespace
- class DiagnosticsLogControllerTest : public NoSessionAshTestBase {
- public:
- DiagnosticsLogControllerTest() = default;
- DiagnosticsLogControllerTest(DiagnosticsLogControllerTest&) = delete;
- DiagnosticsLogControllerTest& operator=(DiagnosticsLogControllerTest&) =
- delete;
- ~DiagnosticsLogControllerTest() override = default;
- void SetUp() override {
- feature_list_.InitAndEnableFeature(
- ash::features::kEnableLogControllerForDiagnosticsApp);
- NoSessionAshTestBase::SetUp();
- }
- protected:
- base::FilePath GetSessionLogPath() {
- EXPECT_TRUE(save_dir_.CreateUniqueTempDir());
- return save_dir_.GetPath().Append(kTestSessionLogFileName);
- }
- void ResetLogBasePath() {
- return DiagnosticsLogController::Get()->ResetLogBasePath();
- }
- base::FilePath log_base_path() {
- return DiagnosticsLogController::Get()->log_base_path_;
- }
- void SetBrowserDelegate(
- std::unique_ptr<DiagnosticsBrowserDelegate> delegate) {
- DiagnosticsLogController::Get()->delegate_ = std::move(delegate);
- }
- void InitializeWithFakeDelegate() {
- std::unique_ptr<DiagnosticsBrowserDelegate> delegate =
- std::make_unique<FakeDiagnosticsBrowserDelegate>();
- DiagnosticsLogController::Initialize(std::move(delegate));
- }
- void SimulateLockScreen() {
- DCHECK(!Shell::Get()->session_controller()->IsScreenLocked());
- Shell::Get()->session_controller()->LockScreen();
- task_environment()->RunUntilIdle();
- EXPECT_TRUE(Shell::Get()->session_controller()->IsScreenLocked());
- }
- void SimulateUnlockScreen() {
- DCHECK(Shell::Get()->session_controller()->IsScreenLocked());
- SessionInfo info;
- info.state = session_manager::SessionState::ACTIVE;
- Shell::Get()->session_controller()->SetSessionInfo(std::move(info));
- task_environment()->RunUntilIdle();
- EXPECT_FALSE(Shell::Get()->session_controller()->IsScreenLocked());
- }
- void SimulateLogoutActiveUser() {
- Shell::Get()->session_controller()->RequestSignOut();
- task_environment()->RunUntilIdle();
- EXPECT_FALSE(
- Shell::Get()->session_controller()->IsActiveUserSessionStarted());
- }
- private:
- base::test::ScopedFeatureList feature_list_;
- base::ScopedTempDir save_dir_;
- };
- TEST_F(DiagnosticsLogControllerTest,
- ShellProvidesControllerWhenFeatureEnabled) {
- EXPECT_NO_FATAL_FAILURE(DiagnosticsLogController::Get());
- EXPECT_NE(nullptr, DiagnosticsLogController::Get());
- }
- TEST_F(DiagnosticsLogControllerTest, IsInitializedAfterDelegateProvided) {
- EXPECT_NE(nullptr, DiagnosticsLogController::Get());
- EXPECT_FALSE(DiagnosticsLogController::IsInitialized());
- InitializeWithFakeDelegate();
- EXPECT_TRUE(DiagnosticsLogController::IsInitialized());
- }
- TEST_F(DiagnosticsLogControllerTest, GenerateSessionLogOnBlockingPoolFile) {
- base::ScopedTempDir scoped_diagnostics_log_dir;
- EXPECT_TRUE(scoped_diagnostics_log_dir.CreateUniqueTempDir());
- const base::FilePath expected_path_regular_user =
- base::FilePath(scoped_diagnostics_log_dir.GetPath().Append(kFakeUserDir));
- const base::FilePath expected_diagnostics_log_path =
- expected_path_regular_user.Append(kDiangosticsDirName);
- SimulateUserLogin(kTestUserEmail);
- DiagnosticsLogController::Initialize(
- std::make_unique<FakeDiagnosticsBrowserDelegate>(
- expected_path_regular_user));
- const base::FilePath save_file_path = GetSessionLogPath();
- EXPECT_TRUE(DiagnosticsLogController::Get()->GenerateSessionLogOnBlockingPool(
- save_file_path));
- EXPECT_TRUE(base::PathExists(save_file_path));
- std::string contents;
- EXPECT_TRUE(base::ReadFileToString(save_file_path, &contents));
- const std::vector<std::string> log_lines = GetLogLines(contents);
- EXPECT_EQ(8u, log_lines.size());
- EXPECT_EQ(kSystemLogSectionHeader, log_lines[0]);
- EXPECT_EQ(kRoutineLogSubsectionHeader, log_lines[1]);
- const std::string expected_no_routine_msg =
- "No routines of this type were run in the session.";
- EXPECT_EQ(expected_no_routine_msg, log_lines[2]);
- EXPECT_EQ(kNetworkingLogSectionHeader, log_lines[3]);
- EXPECT_EQ(kNetworkingLogNetworkInfoHeader, log_lines[4]);
- EXPECT_EQ(kRoutineLogSubsectionHeader, log_lines[5]);
- EXPECT_EQ(expected_no_routine_msg, log_lines[6]);
- EXPECT_EQ(kNetworkingLogNetworkEventsHeader, log_lines[7]);
- }
- TEST_F(DiagnosticsLogControllerTest,
- GenerateWithRoutinesSessionLogOnBlockingPoolFile) {
- base::ScopedTempDir scoped_diagnostics_log_dir;
- EXPECT_TRUE(scoped_diagnostics_log_dir.CreateUniqueTempDir());
- const base::FilePath expected_path_regular_user =
- base::FilePath(scoped_diagnostics_log_dir.GetPath().Append(kFakeUserDir));
- const base::FilePath expected_diagnostics_log_path =
- expected_path_regular_user.Append(kDiangosticsDirName);
- SimulateUserLogin(kTestUserEmail);
- DiagnosticsLogController::Initialize(
- std::make_unique<FakeDiagnosticsBrowserDelegate>(
- expected_path_regular_user));
- RoutineLog* routine_log = DiagnosticsLogController::Get()->GetRoutineLog();
- routine_log->LogRoutineCancelled(mojom::RoutineType::kArcHttp);
- routine_log->LogRoutineCancelled(mojom::RoutineType::kBatteryCharge);
- task_environment()->RunUntilIdle();
- // Generate log file at test path.
- const base::FilePath save_file_path = GetSessionLogPath();
- EXPECT_TRUE(DiagnosticsLogController::Get()->GenerateSessionLogOnBlockingPool(
- save_file_path));
- EXPECT_TRUE(base::PathExists(save_file_path));
- std::string contents;
- EXPECT_TRUE(base::ReadFileToString(save_file_path, &contents));
- const std::vector<std::string> log_lines = GetLogLines(contents);
- EXPECT_EQ(8u, log_lines.size());
- // System state and routine data.
- EXPECT_EQ(kSystemLogSectionHeader, log_lines[0]);
- EXPECT_EQ(kRoutineLogSubsectionHeader, log_lines[1]);
- const std::string expected_canceled_routine_msg =
- "Inflight Routine Cancelled";
- auto system_routine_line = GetLogLineContents(log_lines[2]);
- EXPECT_EQ(2u, system_routine_line.size());
- EXPECT_EQ(expected_canceled_routine_msg, system_routine_line[1]);
- // Network state and routine data.
- EXPECT_EQ(kNetworkingLogSectionHeader, log_lines[3]);
- EXPECT_EQ(kNetworkingLogNetworkInfoHeader, log_lines[4]);
- EXPECT_EQ(kRoutineLogSubsectionHeader, log_lines[5]);
- auto network_routine_line = GetLogLineContents(log_lines[6]);
- EXPECT_EQ(2u, network_routine_line.size());
- EXPECT_EQ(expected_canceled_routine_msg, network_routine_line[1]);
- EXPECT_EQ(kNetworkingLogNetworkEventsHeader, log_lines[7]);
- }
- TEST_F(DiagnosticsLogControllerTest,
- ResetAndInitializeShouldNotLookupProfilePath) {
- const base::FilePath expected_path_not_regular_user =
- base::FilePath(kTmpDiagnosticsDir);
- // Simulate called before delegate configured.
- DiagnosticsLogController::Get()->ResetAndInitializeLogWriters();
- EXPECT_EQ(expected_path_not_regular_user, log_base_path());
- InitializeWithFakeDelegate();
- // Simulate sign-in user.
- ClearLogin();
- DiagnosticsLogController::Get()->ResetAndInitializeLogWriters();
- EXPECT_EQ(expected_path_not_regular_user, log_base_path());
- SimulateGuestLogin();
- DiagnosticsLogController::Get()->ResetAndInitializeLogWriters();
- EXPECT_EQ(expected_path_not_regular_user, log_base_path());
- SimulateKioskMode(user_manager::UserType::USER_TYPE_KIOSK_APP);
- DiagnosticsLogController::Get()->ResetAndInitializeLogWriters();
- EXPECT_EQ(expected_path_not_regular_user, log_base_path());
- SimulateKioskMode(user_manager::UserType::USER_TYPE_ARC_KIOSK_APP);
- DiagnosticsLogController::Get()->ResetAndInitializeLogWriters();
- EXPECT_EQ(expected_path_not_regular_user, log_base_path());
- }
- TEST_F(DiagnosticsLogControllerTest,
- ResetAndInitializeShouldLookupProfileUserEmptyPath) {
- const base::FilePath expected_path_not_regular_user =
- base::FilePath(kTmpDiagnosticsDir);
- // Simulate DiagnosticsBrowserDelegate returning empty path.
- std::unique_ptr<DiagnosticsBrowserDelegate> delegate_with_empty_file_path =
- std::make_unique<FakeDiagnosticsBrowserDelegate>(base::FilePath());
- SetBrowserDelegate(std::move(delegate_with_empty_file_path));
- SimulateUserLogin(kTestUserEmail);
- DiagnosticsLogController::Get()->ResetAndInitializeLogWriters();
- EXPECT_EQ(expected_path_not_regular_user, log_base_path());
- }
- TEST_F(DiagnosticsLogControllerTest,
- ResetAndInitializeForShouldLookupProfileUserNonEmptyPath) {
- InitializeWithFakeDelegate();
- const base::FilePath expected_path_regular_user =
- base::FilePath(kDefaultUserDir).Append(kDiangosticsDirName);
- SimulateUserLogin(kTestUserEmail);
- DiagnosticsLogController::Get()->ResetAndInitializeLogWriters();
- EXPECT_EQ(expected_path_regular_user, log_base_path());
- }
- TEST_F(DiagnosticsLogControllerTest,
- LogBaseCorrectlyUpdatedOnActiveUserSessionChanged) {
- const base::FilePath expected_path_not_regular_user =
- base::FilePath(kTmpDiagnosticsDir);
- InitializeWithFakeDelegate();
- // Simulate sign-in user.
- ClearLogin();
- EXPECT_EQ(expected_path_not_regular_user, log_base_path());
- SimulateGuestLogin();
- EXPECT_EQ(expected_path_not_regular_user, log_base_path());
- SimulateKioskMode(user_manager::UserType::USER_TYPE_KIOSK_APP);
- EXPECT_EQ(expected_path_not_regular_user, log_base_path());
- SimulateKioskMode(user_manager::UserType::USER_TYPE_ARC_KIOSK_APP);
- EXPECT_EQ(expected_path_not_regular_user, log_base_path());
- SimulateUserLogin(kTestUserEmail);
- const base::FilePath expected_path_regular_user =
- base::FilePath(kDefaultUserDir).Append(kDiangosticsDirName);
- EXPECT_EQ(expected_path_regular_user, log_base_path());
- SimulateLockScreen();
- EXPECT_EQ(expected_path_regular_user, log_base_path());
- SimulateUnlockScreen();
- EXPECT_EQ(expected_path_regular_user, log_base_path());
- SimulateLogoutActiveUser();
- EXPECT_EQ(expected_path_not_regular_user, log_base_path());
- }
- TEST_F(DiagnosticsLogControllerTest, SetLogWritersUsingLogBasePath) {
- base::ScopedTempDir scoped_dir;
- EXPECT_TRUE(scoped_dir.CreateUniqueTempDir());
- const base::FilePath expected_path_regular_user =
- base::FilePath(scoped_dir.GetPath().Append(kFakeUserDir));
- const base::FilePath expected_diagnostics_log_path =
- expected_path_regular_user.Append(kDiangosticsDirName);
- SimulateUserLogin(kTestUserEmail);
- DiagnosticsLogController::Initialize(
- std::make_unique<FakeDiagnosticsBrowserDelegate>(
- expected_path_regular_user));
- // After initialize log writers exist.
- EXPECT_EQ(expected_diagnostics_log_path, log_base_path());
- NetworkingLog* networking_log =
- DiagnosticsLogController::Get()->GetNetworkingLog();
- RoutineLog* routine_log = DiagnosticsLogController::Get()->GetRoutineLog();
- TelemetryLog* telemetry_log =
- DiagnosticsLogController::Get()->GetTelemetryLog();
- EXPECT_NE(nullptr, networking_log);
- EXPECT_NE(nullptr, routine_log);
- EXPECT_NE(nullptr, telemetry_log);
- // Simulate events to write files.
- const std::vector<std::string> networks{"fake_guid", "other_fake_guid"};
- networking_log->UpdateNetworkList(networks, "fake_guid");
- networking_log->UpdateNetworkState(mojom::Network::New());
- routine_log->LogRoutineCancelled(mojom::RoutineType::kDnsResolution);
- routine_log->LogRoutineCancelled(mojom::RoutineType::kCpuStress);
- // Wait for Append tasks which create the logs to complete.
- task_environment()->RunUntilIdle();
- EXPECT_FALSE(
- routine_log->GetContentsForCategory(RoutineLog::RoutineCategory::kNetwork)
- .empty());
- EXPECT_FALSE(
- routine_log->GetContentsForCategory(RoutineLog::RoutineCategory::kSystem)
- .empty());
- EXPECT_TRUE(base::PathExists(
- expected_diagnostics_log_path.Append("network_events.log")));
- EXPECT_TRUE(base::PathExists(expected_diagnostics_log_path.Append(
- "diagnostics_routines_network.log")));
- EXPECT_TRUE(base::PathExists(
- expected_diagnostics_log_path.Append("diagnostics_routines_system.log")));
- }
- TEST_F(DiagnosticsLogControllerTest, ClearLogDirectoryOnInitialize) {
- base::ScopedTempDir scoped_dir;
- EXPECT_TRUE(scoped_dir.CreateUniqueTempDir());
- const base::FilePath expected_path_regular_user =
- base::FilePath(scoped_dir.GetPath().Append(kFakeUserDir));
- const base::FilePath expected_diagnostics_log_path =
- expected_path_regular_user.Append(kDiangosticsDirName);
- EXPECT_TRUE(base::CreateDirectory(expected_diagnostics_log_path));
- EXPECT_TRUE(base::PathExists(expected_diagnostics_log_path));
- SimulateUserLogin(kTestUserEmail);
- DiagnosticsLogController::Initialize(
- std::make_unique<FakeDiagnosticsBrowserDelegate>(
- expected_path_regular_user));
- // Wait for delete to complete.
- task_environment()->RunUntilIdle();
- EXPECT_FALSE(base::PathExists(expected_diagnostics_log_path));
- // Before routines updated log file does not exist.
- RoutineLog* routine_log = DiagnosticsLogController::Get()->GetRoutineLog();
- routine_log->LogRoutineCancelled(mojom::RoutineType::kDnsResolution);
- // Wait for append to write logs.
- task_environment()->RunUntilIdle();
- EXPECT_EQ(expected_diagnostics_log_path, log_base_path());
- EXPECT_TRUE(base::PathExists(expected_diagnostics_log_path));
- }
- } // namespace diagnostics
- } // namespace ash
|