activity_log_unittest.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
1// Copyright (c) 2012 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 "base/command_line.h" 6#include "base/memory/scoped_ptr.h" 7#include "base/message_loop.h" 8#include "base/run_loop.h" 9#include "base/synchronization/waitable_event.h" 10#include "chrome/browser/extensions/activity_log/activity_log.h" 11#include "chrome/browser/extensions/activity_log/dom_actions.h" 12#include "chrome/browser/extensions/extension_service.h" 13#include "chrome/browser/extensions/test_extension_system.h" 14#include "chrome/browser/prerender/prerender_handle.h" 15#include "chrome/browser/prerender/prerender_manager.h" 16#include "chrome/browser/prerender/prerender_manager_factory.h" 17#include "chrome/common/chrome_constants.h" 18#include "chrome/common/chrome_switches.h" 19#include "chrome/common/extensions/dom_action_types.h" 20#include "chrome/common/extensions/extension_builder.h" 21#include "chrome/test/base/chrome_render_view_host_test_harness.h" 22#include "chrome/test/base/testing_profile.h" 23#include "content/public/test/test_browser_thread_bundle.h" 24#include "sql/statement.h" 25#include "testing/gtest/include/gtest/gtest.h" 26 27#if defined(OS_CHROMEOS) 28#include "chrome/browser/chromeos/login/user_manager.h" 29#include "chrome/browser/chromeos/settings/cros_settings.h" 30#include "chrome/browser/chromeos/settings/device_settings_service.h" 31#endif 32 33namespace { 34 35const char kExtensionId[] = "abc"; 36 37} // namespace 38 39namespace extensions { 40 41class ActivityLogTest : public testing::Test { 42 protected: 43 ActivityLogTest() 44 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), 45 saved_cmdline_(CommandLine::NO_PROGRAM) { 46#if defined OS_CHROMEOS 47 test_user_manager_.reset(new chromeos::ScopedTestUserManager()); 48#endif 49 CommandLine command_line(CommandLine::NO_PROGRAM); 50 saved_cmdline_ = *CommandLine::ForCurrentProcess(); 51 profile_.reset(new TestingProfile()); 52 CommandLine::ForCurrentProcess()->AppendSwitch( 53 switches::kEnableExtensionActivityLogging); 54 CommandLine::ForCurrentProcess()->AppendSwitch( 55 switches::kEnableExtensionActivityLogTesting); 56 extension_service_ = static_cast<TestExtensionSystem*>( 57 ExtensionSystem::Get(profile_.get()))->CreateExtensionService 58 (&command_line, base::FilePath(), false); 59 ActivityLog::RecomputeLoggingIsEnabled(false); 60 } 61 62 virtual ~ActivityLogTest() { 63#if defined OS_CHROMEOS 64 test_user_manager_.reset(); 65#endif 66 base::RunLoop().RunUntilIdle(); 67 profile_.reset(NULL); 68 base::RunLoop().RunUntilIdle(); 69 // Restore the original command line and undo the affects of SetUp(). 70 *CommandLine::ForCurrentProcess() = saved_cmdline_; 71 ActivityLog::RecomputeLoggingIsEnabled(false); 72 } 73 74 static void RetrieveActions_LogAndFetchActions( 75 scoped_ptr<std::vector<scoped_refptr<Action> > > i) { 76 ASSERT_EQ(2, static_cast<int>(i->size())); 77 } 78 79 static void RetrieveActions_LogAndFetchPathActions( 80 scoped_ptr<std::vector<scoped_refptr<Action> > > i) { 81 std::string args; 82 ASSERT_EQ(1U, i->size()); 83 scoped_refptr<Action> last = i->front(); 84 if (CommandLine::ForCurrentProcess()->HasSwitch( 85 switches::kEnableExtensionActivityLogTesting)) 86 args = "Injected scripts () onto " 87 "http://www.google.com/foo?bar extra"; 88 else 89 args = "Injected scripts () onto " 90 "http://www.google.com/foo extra"; 91 ASSERT_EQ(args, last->PrintForDebug()); 92 } 93 94 static void Arguments_Missing( 95 scoped_ptr<std::vector<scoped_refptr<Action> > > i) { 96 scoped_refptr<Action> last = i->front(); 97 std::string id(kExtensionId); 98 std::string noargs = "ID: " + id + ", CATEGORY: " 99 "call, API: tabs.testMethod, ARGS: "; 100 ASSERT_EQ(noargs, last->PrintForDebug()); 101 } 102 103 static void Arguments_Present( 104 scoped_ptr<std::vector<scoped_refptr<Action> > > i) { 105 scoped_refptr<Action> last = i->front(); 106 std::string id(kExtensionId); 107 std::string args = "ID: " + id + ", CATEGORY: " 108 "call, API: extension.connect, ARGS: \"hello\", \"world\""; 109 ASSERT_EQ(args, last->PrintForDebug()); 110 } 111 112 protected: 113 scoped_ptr<TestingProfile> profile_; 114 ExtensionService* extension_service_; 115 116 content::TestBrowserThreadBundle thread_bundle_; 117 118 // Used to preserve a copy of the original command line. 119 // The test framework will do this itself as well. However, by then, 120 // it is too late to call ActivityLog::RecomputeLoggingIsEnabled() in 121 // TearDown(). 122 CommandLine saved_cmdline_; 123 124#if defined OS_CHROMEOS 125 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_; 126 chromeos::ScopedTestCrosSettings test_cros_settings_; 127 scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_; 128#endif 129}; 130 131class RenderViewActivityLogTest : public ChromeRenderViewHostTestHarness { 132 protected: 133 RenderViewActivityLogTest() : saved_cmdline_(CommandLine::NO_PROGRAM) {} 134 135 virtual void SetUp() OVERRIDE { 136 ChromeRenderViewHostTestHarness::SetUp(); 137#if defined OS_CHROMEOS 138 test_user_manager_.reset(new chromeos::ScopedTestUserManager()); 139#endif 140 CommandLine command_line(CommandLine::NO_PROGRAM); 141 saved_cmdline_ = *CommandLine::ForCurrentProcess(); 142 CommandLine::ForCurrentProcess()->AppendSwitch( 143 switches::kEnableExtensionActivityLogging); 144 CommandLine::ForCurrentProcess()->AppendSwitch( 145 switches::kEnableExtensionActivityLogTesting); 146 ActivityLog::RecomputeLoggingIsEnabled(false); 147 extension_service_ = static_cast<TestExtensionSystem*>( 148 ExtensionSystem::Get(profile()))->CreateExtensionService( 149 &command_line, base::FilePath(), false); 150 } 151 152 virtual void TearDown() OVERRIDE { 153#if defined OS_CHROMEOS 154 test_user_manager_.reset(); 155#endif 156 ChromeRenderViewHostTestHarness::TearDown(); 157 *CommandLine::ForCurrentProcess() = saved_cmdline_; 158 ActivityLog::RecomputeLoggingIsEnabled(false); 159 } 160 161 static void Arguments_Prerender( 162 scoped_ptr<std::vector<scoped_refptr<Action> > > i) { 163 ASSERT_EQ(1U, i->size()); 164 scoped_refptr<Action> last = i->front(); 165 std::string args = "Injected scripts (\"script \") " 166 "onto http://www.google.com/ (prerender)"; 167 ASSERT_EQ(args, last->PrintForDebug()); 168 } 169 170 ExtensionService* extension_service_; 171 // Used to preserve a copy of the original command line. 172 // The test framework will do this itself as well. However, by then, 173 // it is too late to call ActivityLog::RecomputeLoggingIsEnabled() in 174 // TearDown(). 175 CommandLine saved_cmdline_; 176 177 private: 178#if defined OS_CHROMEOS 179 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_; 180 chromeos::ScopedTestCrosSettings test_cros_settings_; 181 scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_; 182#endif 183}; 184 185TEST_F(ActivityLogTest, Enabled) { 186 ASSERT_TRUE(ActivityLog::IsLogEnabledOnAnyProfile()); 187} 188 189TEST_F(ActivityLogTest, Construct) { 190 ActivityLog* activity_log = ActivityLog::GetInstance(profile_.get()); 191 scoped_ptr<base::ListValue> args(new base::ListValue()); 192 ASSERT_TRUE(activity_log->IsLogEnabled()); 193 activity_log->LogAPIAction( 194 kExtensionId, std::string("tabs.testMethod"), args.get(), std::string()); 195} 196 197TEST_F(ActivityLogTest, LogAndFetchActions) { 198 ActivityLog* activity_log = ActivityLog::GetInstance(profile_.get()); 199 scoped_ptr<base::ListValue> args(new base::ListValue()); 200 ASSERT_TRUE(activity_log->IsLogEnabled()); 201 202 // Write some API calls 203 activity_log->LogAPIAction( 204 kExtensionId, std::string("tabs.testMethod"), args.get(), std::string()); 205 activity_log->LogDOMAction(kExtensionId, 206 GURL("http://www.google.com"), 207 string16(), 208 std::string("document.write"), 209 args.get(), 210 DomActionType::METHOD, 211 std::string("extra")); 212 activity_log->GetActions( 213 kExtensionId, 214 0, 215 base::Bind(ActivityLogTest::RetrieveActions_LogAndFetchActions)); 216} 217 218TEST_F(ActivityLogTest, LogAndFetchPathActions) { 219 ActivityLog* activity_log = ActivityLog::GetInstance(profile_.get()); 220 scoped_ptr<base::ListValue> args(new base::ListValue()); 221 ASSERT_TRUE(activity_log->IsLogEnabled()); 222 223 activity_log->LogDOMAction(kExtensionId, 224 GURL("http://www.google.com/foo?bar"), 225 string16(), 226 std::string("document.write"), 227 args.get(), 228 DomActionType::INSERTED, 229 std::string("extra")); 230 activity_log->GetActions( 231 kExtensionId, 232 0, 233 base::Bind(ActivityLogTest::RetrieveActions_LogAndFetchPathActions)); 234} 235 236TEST_F(ActivityLogTest, LogWithoutArguments) { 237 ActivityLog* activity_log = ActivityLog::GetInstance(profile_.get()); 238 activity_log->SetArgumentLoggingForTesting(false); 239 ASSERT_TRUE(activity_log->IsLogEnabled()); 240 activity_log->SetDefaultPolicy(ActivityLogPolicy::POLICY_NOARGS); 241 scoped_ptr<base::ListValue> args(new base::ListValue()); 242 args->Set(0, new base::StringValue("hello")); 243 args->Set(1, new base::StringValue("world")); 244 activity_log->LogAPIAction( 245 kExtensionId, std::string("tabs.testMethod"), args.get(), std::string()); 246 activity_log->GetActions( 247 kExtensionId, 0, base::Bind(ActivityLogTest::Arguments_Missing)); 248} 249 250TEST_F(ActivityLogTest, LogWithArguments) { 251 ActivityLog* activity_log = ActivityLog::GetInstance(profile_.get()); 252 activity_log->SetDefaultPolicy(ActivityLogPolicy::POLICY_FULLSTREAM); 253 ASSERT_TRUE(activity_log->IsLogEnabled()); 254 255 scoped_ptr<base::ListValue> args(new base::ListValue()); 256 args->Set(0, new base::StringValue("hello")); 257 args->Set(1, new base::StringValue("world")); 258 activity_log->LogAPIAction(kExtensionId, 259 std::string("extension.connect"), 260 args.get(), 261 std::string()); 262 activity_log->GetActions( 263 kExtensionId, 0, base::Bind(ActivityLogTest::Arguments_Present)); 264} 265 266TEST_F(RenderViewActivityLogTest, LogPrerender) { 267 scoped_refptr<const Extension> extension = 268 ExtensionBuilder() 269 .SetManifest(DictionaryBuilder() 270 .Set("name", "Test extension") 271 .Set("version", "1.0.0") 272 .Set("manifest_version", 2)) 273 .Build(); 274 extension_service_->AddExtension(extension.get()); 275 ActivityLog* activity_log = ActivityLog::GetInstance(profile()); 276 activity_log->SetDefaultPolicy(ActivityLogPolicy::POLICY_FULLSTREAM); 277 ASSERT_TRUE(activity_log->IsLogEnabled()); 278 GURL url("http://www.google.com"); 279 280 prerender::PrerenderManager* prerender_manager = 281 prerender::PrerenderManagerFactory::GetForProfile( 282 Profile::FromBrowserContext(profile())); 283 284 const gfx::Size kSize(640, 480); 285 scoped_ptr<prerender::PrerenderHandle> prerender_handle( 286 prerender_manager->AddPrerenderFromLocalPredictor( 287 url, 288 web_contents()->GetController().GetDefaultSessionStorageNamespace(), 289 kSize)); 290 291 const std::vector<content::WebContents*> contentses = 292 prerender_manager->GetAllPrerenderingContents(); 293 ASSERT_EQ(1U, contentses.size()); 294 content::WebContents *contents = contentses[0]; 295 ASSERT_TRUE(prerender_manager->IsWebContentsPrerendering(contents, NULL)); 296 297 TabHelper::ScriptExecutionObserver::ExecutingScriptsMap executing_scripts; 298 executing_scripts[extension->id()].insert("script"); 299 300 static_cast<TabHelper::ScriptExecutionObserver*>(activity_log)-> 301 OnScriptsExecuted(contents, executing_scripts, 0, url); 302 303 activity_log->GetActions( 304 extension->id(), 0, base::Bind( 305 RenderViewActivityLogTest::Arguments_Prerender)); 306 307 prerender_manager->CancelAllPrerenders(); 308} 309 310} // namespace extensions 311 312