| Index: chrome/browser/power/process_power_collector_unittest.cc
|
| diff --git a/chrome/browser/power/process_power_collector_unittest.cc b/chrome/browser/power/process_power_collector_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..bdc271a97be08e05bd2e9eadd9d79e170de1cf64
|
| --- /dev/null
|
| +++ b/chrome/browser/power/process_power_collector_unittest.cc
|
| @@ -0,0 +1,345 @@
|
| +// Copyright 2014 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 "chrome/browser/power/process_power_collector.h"
|
| +
|
| +#include "apps/app_window_contents.h"
|
| +#include "apps/app_window_registry.h"
|
| +#include "apps/ui/native_app_window.h"
|
| +#include "chrome/browser/profiles/profile_manager.h"
|
| +#include "chrome/browser/ui/apps/chrome_app_delegate.h"
|
| +#include "chrome/browser/ui/browser_commands.h"
|
| +#include "chrome/browser/ui/tabs/tab_strip_model.h"
|
| +#include "chrome/test/base/browser_with_test_window_test.h"
|
| +#include "chrome/test/base/testing_browser_process.h"
|
| +#include "chrome/test/base/testing_profile_manager.h"
|
| +#include "components/power/origin_power_map.h"
|
| +#include "components/power/origin_power_map_factory.h"
|
| +#include "content/public/browser/site_instance.h"
|
| +#include "content/public/test/browser_test_utils.h"
|
| +#include "content/public/test/mock_render_process_host.h"
|
| +#include "extensions/common/extension.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "url/gurl.h"
|
| +
|
| +#if defined(OS_CHROMEOS)
|
| +#include "chrome/browser/chromeos/power/power_data_collector.h"
|
| +#include "chromeos/dbus/dbus_thread_manager.h"
|
| +#include "chromeos/dbus/fake_dbus_thread_manager.h"
|
| +#include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
|
| +#endif
|
| +
|
| +using power::OriginPowerMap;
|
| +using power::OriginPowerMapFactory;
|
| +
|
| +class BrowserProcessPowerTest : public BrowserWithTestWindowTest {
|
| + public:
|
| + BrowserProcessPowerTest() {}
|
| + virtual ~BrowserProcessPowerTest() {}
|
| +
|
| + virtual void SetUp() OVERRIDE {
|
| + BrowserWithTestWindowTest::SetUp();
|
| +#if defined(OS_CHROMEOS)
|
| + chromeos::DBusThreadManager::Shutdown();
|
| + chromeos::FakeDBusThreadManager* fake_dbus_thread_manager =
|
| + new chromeos::FakeDBusThreadManager;
|
| + fake_dbus_thread_manager->SetFakeClients();
|
| + chromeos::DBusThreadManager::InitializeForTesting(fake_dbus_thread_manager);
|
| + chromeos::PowerDataCollector::InitializeForTesting();
|
| +
|
| + power_manager::PowerSupplyProperties prop1;
|
| + prop1.set_external_power(
|
| + power_manager::PowerSupplyProperties::DISCONNECTED);
|
| + prop1.set_battery_percent(20.00);
|
| + prop1.set_battery_discharge_rate(1);
|
| + chromeos::PowerDataCollector::Get()->PowerChanged(prop1);
|
| +#endif
|
| +
|
| + profile_manager_.reset(
|
| + new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
|
| + ASSERT_TRUE(profile_manager_->SetUp());
|
| + }
|
| +
|
| + virtual void TearDown() OVERRIDE {
|
| +#if defined(OS_CHROMEOS)
|
| + chromeos::PowerDataCollector::Shutdown();
|
| +#endif
|
| + BrowserWithTestWindowTest::TearDown();
|
| + }
|
| +
|
| + protected:
|
| + scoped_ptr<TestingProfileManager> profile_manager_;
|
| +
|
| + content::MockRenderProcessHost* process(Browser* browser) {
|
| + return static_cast<content::MockRenderProcessHost*>(
|
| + browser->tab_strip_model()
|
| + ->GetActiveWebContents()
|
| + ->GetRenderViewHost()
|
| + ->GetProcess());
|
| + }
|
| +};
|
| +
|
| +class TestAppWindowContents : public apps::AppWindowContents {
|
| + public:
|
| + explicit TestAppWindowContents(content::WebContents* web_contents) {
|
| + web_contents_.reset(web_contents);
|
| + }
|
| + // apps:AppWindowContents
|
| + virtual void Initialize(content::BrowserContext* context,
|
| + const GURL& url) OVERRIDE{};
|
| + virtual void LoadContents(int32 creator_process_id) OVERRIDE{};
|
| + virtual void NativeWindowChanged(
|
| + apps::NativeAppWindow* native_app_window) OVERRIDE{};
|
| + virtual void NativeWindowClosed() OVERRIDE{};
|
| + virtual void DispatchWindowShownForTests() const OVERRIDE{};
|
| + virtual content::WebContents* GetWebContents() const OVERRIDE {
|
| + return web_contents_.get();
|
| + }
|
| +
|
| + private:
|
| + scoped_ptr<content::WebContents> web_contents_;
|
| +};
|
| +
|
| +TEST_F(BrowserProcessPowerTest, NoSite) {
|
| + ProcessPowerCollector collector;
|
| + collector.UpdateMetricsMap();
|
| + collector.PopulateCpuUsageByOrigin();
|
| + EXPECT_EQ(size_t(0), collector.GetMetricsMapForTesting()->size());
|
| +}
|
| +
|
| +TEST_F(BrowserProcessPowerTest, OneSite) {
|
| + GURL url("http://www.google.com");
|
| + AddTab(browser(), url);
|
| + ProcessPowerCollector collector;
|
| + collector.UpdateMetricsMap();
|
| + collector.PopulateCpuUsageByOrigin();
|
| + ProcessPowerCollector::ProcessMetricsMap* metrics_map =
|
| + collector.GetMetricsMapForTesting();
|
| + EXPECT_EQ(size_t(1), metrics_map->size());
|
| + collector.RecordCpuUsageByOrigin(0);
|
| +
|
| + OriginPowerMap* origin_power_map =
|
| + OriginPowerMapFactory::GetForBrowserContext(profile());
|
| + EXPECT_EQ(0, origin_power_map->GetPowerForOrigin(url));
|
| +
|
| + collector.UpdateMetricsMap();
|
| + collector.PopulateCpuUsageByOrigin();
|
| + // Manually update the map to make the CPU usage work.
|
| + for (ProcessPowerCollector::ProcessMetricsMap::iterator it =
|
| + metrics_map->begin();
|
| + it != metrics_map->end();
|
| + ++it) {
|
| + it->second->last_cpu = 5;
|
| + }
|
| + collector.RecordCpuUsageByOrigin(5);
|
| + EXPECT_EQ(100, origin_power_map->GetPowerForOrigin(url));
|
| +}
|
| +
|
| +TEST_F(BrowserProcessPowerTest, MultipleSites) {
|
| + Browser::CreateParams native_params(profile(),
|
| + chrome::HOST_DESKTOP_TYPE_NATIVE);
|
| + GURL url1("http://www.google.com");
|
| + GURL url2("http://www.example.com");
|
| + GURL url3("https://www.google.com");
|
| + scoped_ptr<Browser> browser2(
|
| + chrome::CreateBrowserWithTestWindowForParams(&native_params));
|
| + scoped_ptr<Browser> browser3(
|
| + chrome::CreateBrowserWithTestWindowForParams(&native_params));
|
| + AddTab(browser(), url1);
|
| + AddTab(browser2.get(), url2);
|
| + AddTab(browser3.get(), url3);
|
| +
|
| + // Create fake process numbers.
|
| + content::MockRenderProcessHost* rph = process(browser());
|
| + rph->SetProcessHandle(1);
|
| + rph = process(browser2.get());
|
| + rph->SetProcessHandle(2);
|
| + rph = process(browser3.get());
|
| + rph->SetProcessHandle(3);
|
| +
|
| + ProcessPowerCollector collector;
|
| + collector.UpdateMetricsMap();
|
| + ProcessPowerCollector::ProcessMetricsMap* metrics_map =
|
| + collector.GetMetricsMapForTesting();
|
| + EXPECT_EQ(size_t(3), metrics_map->size());
|
| +
|
| + // Since all handlers are uninitialized, this should be 0.
|
| + EXPECT_EQ(0, collector.PopulateCpuUsageByOrigin());
|
| + collector.RecordCpuUsageByOrigin(0);
|
| + OriginPowerMap* origin_power_map =
|
| + OriginPowerMapFactory::GetForBrowserContext(profile());
|
| + EXPECT_EQ(0, origin_power_map->GetPowerForOrigin(url1));
|
| + EXPECT_EQ(0, origin_power_map->GetPowerForOrigin(url2));
|
| + EXPECT_EQ(0, origin_power_map->GetPowerForOrigin(url3));
|
| +
|
| + collector.UpdateMetricsMap();
|
| + collector.PopulateCpuUsageByOrigin();
|
| + // Manually update the map to make the CPU usage work.
|
| + for (ProcessPowerCollector::ProcessMetricsMap::iterator it =
|
| + metrics_map->begin();
|
| + it != metrics_map->end();
|
| + ++it) {
|
| + it->second->last_cpu = 5;
|
| + }
|
| + collector.RecordCpuUsageByOrigin(15);
|
| + EXPECT_EQ(33, origin_power_map->GetPowerForOrigin(url1));
|
| + EXPECT_EQ(33, origin_power_map->GetPowerForOrigin(url2));
|
| + EXPECT_EQ(33, origin_power_map->GetPowerForOrigin(url3));
|
| +
|
| + // Close some tabs and verify that they are removed from the metrics map.
|
| + chrome::CloseTab(browser2.get());
|
| + chrome::CloseTab(browser3.get());
|
| +
|
| + collector.UpdateMetricsMap();
|
| + collector.PopulateCpuUsageByOrigin();
|
| + collector.RecordCpuUsageByOrigin(0);
|
| + EXPECT_EQ(size_t(1), metrics_map->size());
|
| +}
|
| +
|
| +TEST_F(BrowserProcessPowerTest, IncognitoDoesntRecordPowerUsage) {
|
| + Browser::CreateParams native_params(profile()->GetOffTheRecordProfile(),
|
| + chrome::HOST_DESKTOP_TYPE_NATIVE);
|
| + scoped_ptr<Browser> incognito_browser(
|
| + chrome::CreateBrowserWithTestWindowForParams(&native_params));
|
| + GURL url("http://www.google.com");
|
| + AddTab(browser(), url);
|
| +
|
| + GURL hidden_url("http://foo.com");
|
| + AddTab(incognito_browser.get(), hidden_url);
|
| +
|
| + ProcessPowerCollector collector;
|
| + collector.UpdateMetricsMap();
|
| + collector.PopulateCpuUsageByOrigin();
|
| + ProcessPowerCollector::ProcessMetricsMap* metrics_map =
|
| + collector.GetMetricsMapForTesting();
|
| + EXPECT_EQ(size_t(1), metrics_map->size());
|
| + collector.RecordCpuUsageByOrigin(0);
|
| +
|
| + OriginPowerMap* origin_power_map =
|
| + OriginPowerMapFactory::GetForBrowserContext(profile());
|
| + EXPECT_EQ(0, origin_power_map->GetPowerForOrigin(url));
|
| +
|
| + collector.UpdateMetricsMap();
|
| + collector.PopulateCpuUsageByOrigin();
|
| + // Manually update the map to make the CPU usage work.
|
| + for (ProcessPowerCollector::ProcessMetricsMap::iterator it =
|
| + metrics_map->begin();
|
| + it != metrics_map->end();
|
| + ++it) {
|
| + it->second->last_cpu = 5;
|
| + }
|
| + collector.RecordCpuUsageByOrigin(5);
|
| +
|
| + // Verify that the incognito data was not stored.
|
| + EXPECT_EQ(100, origin_power_map->GetPowerForOrigin(url));
|
| + EXPECT_EQ(0, origin_power_map->GetPowerForOrigin(hidden_url));
|
| +
|
| + chrome::CloseTab(incognito_browser.get());
|
| +}
|
| +
|
| +TEST_F(BrowserProcessPowerTest, MultipleProfilesRecordSeparately) {
|
| + scoped_ptr<Profile> other_profile(CreateProfile());
|
| + Browser::CreateParams native_params(other_profile.get(),
|
| + chrome::HOST_DESKTOP_TYPE_NATIVE);
|
| + scoped_ptr<Browser> other_user(
|
| + chrome::CreateBrowserWithTestWindowForParams(&native_params));
|
| +
|
| + GURL url("http://www.google.com");
|
| + AddTab(browser(), url);
|
| +
|
| + GURL hidden_url("http://foo.com");
|
| + AddTab(other_user.get(), hidden_url);
|
| +
|
| + // Create fake process numbers.
|
| + content::MockRenderProcessHost* rph = process(browser());
|
| + rph->SetProcessHandle(1);
|
| + rph = process(other_user.get());
|
| + rph->SetProcessHandle(2);
|
| +
|
| + ProcessPowerCollector collector;
|
| + collector.UpdateMetricsMap();
|
| + collector.PopulateCpuUsageByOrigin();
|
| +
|
| + EXPECT_EQ(size_t(2), collector.GetMetricsMapForTesting()->size());
|
| + collector.RecordCpuUsageByOrigin(0);
|
| +
|
| + // Manually update the map to make the CPU usage work.
|
| + ProcessPowerCollector::ProcessMetricsMap* metrics_map =
|
| + collector.GetMetricsMapForTesting();
|
| + for (ProcessPowerCollector::ProcessMetricsMap::iterator it =
|
| + metrics_map->begin();
|
| + it != metrics_map->end();
|
| + ++it) {
|
| + it->second->last_cpu = 5;
|
| + }
|
| + collector.RecordCpuUsageByOrigin(5);
|
| +
|
| + // profile() should have an entry for |url| but not |hidden_url|.
|
| + OriginPowerMap* origin_power_map_first =
|
| + OriginPowerMapFactory::GetForBrowserContext(profile());
|
| + EXPECT_EQ(100, origin_power_map_first->GetPowerForOrigin(url));
|
| + EXPECT_EQ(0, origin_power_map_first->GetPowerForOrigin(hidden_url));
|
| +
|
| + // |other_profile| should have an entry for |hidden_url| but not |url|.
|
| + OriginPowerMap* origin_power_map_second =
|
| + OriginPowerMapFactory::GetForBrowserContext(other_profile.get());
|
| + EXPECT_EQ(0, origin_power_map_second->GetPowerForOrigin(url));
|
| + EXPECT_EQ(100, origin_power_map_second->GetPowerForOrigin(hidden_url));
|
| +
|
| + // Clean up
|
| + chrome::CloseTab(other_user.get());
|
| +}
|
| +
|
| +const char kTestAppId[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
| +
|
| +TEST_F(BrowserProcessPowerTest, AppsRecordPowerUsage) {
|
| + Profile* current_profile =
|
| + profile_manager_->CreateTestingProfile("Test user");
|
| +
|
| +// Install an app (an extension*).
|
| +#if defined(OS_WIN)
|
| + base::FilePath extension_path(FILE_PATH_LITERAL("c:\\foo"));
|
| +#elif defined(OS_POSIX)
|
| + base::FilePath extension_path(FILE_PATH_LITERAL("/foo"));
|
| +#endif
|
| + base::DictionaryValue manifest;
|
| + manifest.SetString("name", "Fake Name");
|
| + manifest.SetString("version", "1");
|
| + std::string error;
|
| + scoped_refptr<extensions::Extension> extension(
|
| + extensions::Extension::Create(extension_path,
|
| + extensions::Manifest::INTERNAL,
|
| + manifest,
|
| + extensions::Extension::NO_FLAGS,
|
| + kTestAppId,
|
| + &error));
|
| + EXPECT_TRUE(extension.get()) << error;
|
| +
|
| + GURL url("chrome-extension://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
| + // Use that to create a new AppWindow -- hopefully that can avoid
|
| + // dependencies.
|
| + apps::AppWindow* window =
|
| + new apps::AppWindow(current_profile, new ChromeAppDelegate(), extension);
|
| + scoped_ptr<content::WebContents> web_contents(
|
| + content::WebContents::Create(content::WebContents::CreateParams(
|
| + current_profile,
|
| + content::SiteInstance::CreateForURL(current_profile, url))));
|
| + window->SetAppWindowContentsForTesting(scoped_ptr<apps::AppWindowContents>(
|
| + new TestAppWindowContents(web_contents.get())));
|
| + apps::AppWindowRegistry* app_registry =
|
| + apps::AppWindowRegistry::Get(current_profile);
|
| + app_registry->AddAppWindow(window);
|
| +
|
| + ProcessPowerCollector collector;
|
| + collector.UpdateMetricsMap();
|
| + collector.PopulateCpuUsageByOrigin();
|
| + EXPECT_EQ(size_t(1), collector.GetMetricsMapForTesting()->size());
|
| + collector.RecordCpuUsageByOrigin(0);
|
| +
|
| + app_registry->RemoveAppWindow(window);
|
| + collector.UpdateMetricsMap();
|
| + collector.PopulateCpuUsageByOrigin();
|
| + EXPECT_EQ(size_t(0), collector.GetMetricsMapForTesting()->size());
|
| + collector.RecordCpuUsageByOrigin(0);
|
| +}
|
|
|