1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/chromeos/crostini/crostini_util.h"
6 
7 #include "base/bind.h"
8 #include "base/run_loop.h"
9 #include "chrome/browser/browser_process_platform_part_base.h"
10 #include "chrome/browser/chromeos/crostini/crostini_test_helper.h"
11 #include "chrome/browser/component_updater/fake_cros_component_manager.h"
12 #include "chrome/test/base/browser_process_platform_part_test_api_chromeos.h"
13 #include "chrome/test/base/scoped_testing_local_state.h"
14 #include "chrome/test/base/testing_browser_process.h"
15 #include "chrome/test/base/testing_profile.h"
16 #include "chromeos/dbus/dbus_thread_manager.h"
17 #include "chromeos/dbus/dlcservice/dlcservice_client.h"
18 #include "chromeos/dbus/fake_concierge_client.h"
19 #include "content/public/test/browser_task_environment.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 
22 constexpr char kDesktopFileId[] = "dummy1";
23 constexpr int kDisplayId = 0;
24 
25 namespace crostini {
26 
27 class CrostiniUtilTest : public testing::Test {
28  public:
SuccessCallback(bool expected_success,const std::string & expected_failure_reason,bool success,const std::string & failure_reason)29   void SuccessCallback(bool expected_success,
30                        const std::string& expected_failure_reason,
31                        bool success,
32                        const std::string& failure_reason) {
33     EXPECT_EQ(expected_success, success);
34     EXPECT_EQ(expected_failure_reason, failure_reason);
35     run_loop_->Quit();
36   }
37 
CrostiniUtilTest()38   CrostiniUtilTest()
39       : app_id_(crostini::CrostiniTestHelper::GenerateAppId(kDesktopFileId)),
40         task_environment_(content::BrowserTaskEnvironment::REAL_IO_THREAD),
41         local_state_(std::make_unique<ScopedTestingLocalState>(
42             TestingBrowserProcess::GetGlobal())),
43         browser_part_(g_browser_process->platform_part()) {
44     chromeos::DBusThreadManager::Initialize();
45 
46     fake_concierge_client_ = static_cast<chromeos::FakeConciergeClient*>(
47         chromeos::DBusThreadManager::Get()->GetConciergeClient());
48   }
~CrostiniUtilTest()49   ~CrostiniUtilTest() override { chromeos::DBusThreadManager::Shutdown(); }
50   CrostiniUtilTest(const CrostiniUtilTest&) = delete;
51   CrostiniUtilTest& operator=(const CrostiniUtilTest&) = delete;
52 
SetUp()53   void SetUp() override {
54     chromeos::DlcserviceClient::InitializeFake();
55 
56     component_manager_ =
57         base::MakeRefCounted<component_updater::FakeCrOSComponentManager>();
58     component_manager_->set_supported_components({"cros-termina"});
59     component_manager_->ResetComponentState(
60         "cros-termina",
61         component_updater::FakeCrOSComponentManager::ComponentInfo(
62             component_updater::CrOSComponentManager::Error::NONE,
63             base::FilePath("/install/path"), base::FilePath("/mount/path")));
64     browser_part_.InitializeCrosComponentManager(component_manager_);
65 
66     run_loop_ = std::make_unique<base::RunLoop>();
67     profile_ = std::make_unique<TestingProfile>();
68     test_helper_ = std::make_unique<CrostiniTestHelper>(profile_.get());
69     test_helper_->SetupDummyApps();
70     g_browser_process->platform_part()
71         ->InitializeSchedulerConfigurationManager();
72   }
73 
TearDown()74   void TearDown() override {
75     g_browser_process->platform_part()->ShutdownSchedulerConfigurationManager();
76     test_helper_.reset();
77     run_loop_.reset();
78     profile_.reset();
79     browser_part_.ShutdownCrosComponentManager();
80     component_manager_.reset();
81     chromeos::DlcserviceClient::Shutdown();
82   }
83 
84  protected:
85   chromeos::FakeConciergeClient* fake_concierge_client_;
86 
87   std::unique_ptr<base::RunLoop> run_loop_;
88   std::unique_ptr<TestingProfile> profile_;
89   std::unique_ptr<CrostiniTestHelper> test_helper_;
90   std::string app_id_;
91 
92  private:
93   content::BrowserTaskEnvironment task_environment_;
94   std::unique_ptr<ScopedTestingLocalState> local_state_;
95   scoped_refptr<component_updater::FakeCrOSComponentManager> component_manager_;
96   BrowserProcessPlatformPartTestApi browser_part_;
97 };
98 
TEST_F(CrostiniUtilTest,ContainerIdEquality)99 TEST_F(CrostiniUtilTest, ContainerIdEquality) {
100   auto container1 = ContainerId{"test1", "test2"};
101   auto container2 = ContainerId{"test1", "test2"};
102   auto container3 = ContainerId{"test2", "test1"};
103 
104   ASSERT_TRUE(container1 == container2);
105   ASSERT_FALSE(container1 == container3);
106   ASSERT_FALSE(container2 == container3);
107 }
108 
TEST_F(CrostiniUtilTest,LaunchCallbackRunsOnRestartError)109 TEST_F(CrostiniUtilTest, LaunchCallbackRunsOnRestartError) {
110   // Set Restart to fail.
111   fake_concierge_client_->set_start_vm_response({});
112 
113   // Launch should fail and invoke callback.
114   LaunchCrostiniApp(profile_.get(), app_id_, kDisplayId, {},
115                     base::Bind(&CrostiniUtilTest::SuccessCallback,
116                                base::Unretained(this), false,
117                                "crostini restart to launch app "
118                                "pfdnkhehloenlegacemoalhjljmpllpc failed: 5"));
119 
120   run_loop_->Run();
121 }
122 
123 }  // namespace crostini
124