extension_loading_browsertest.cc revision 868fa2fe829687343ffae624259930155e16dbd8
1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file. 4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// This file contains tests for extension loading, reloading, and 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// unloading behavior. 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/json/json_writer.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/run_loop.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/safe_numerics.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/test/values_test_util.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/extensions/extension_browsertest.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/extensions/extension_creator.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/extensions/extension_system.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/test/embedded_test_server/embedded_test_server.h" 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace extensions { 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace { 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Provides a temporary directory to build an extension into. This lets all of 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// an extension's code live inside the test instead of in a separate directory. 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class TestExtensionDir { 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TestExtensionDir() { 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(dir_.CreateUniqueTempDir()); 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(crx_dir_.CreateUniqueTempDir()); 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Writes |contents| to path()/filename, overwriting anything that was already 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // there. 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void WriteFile(base::FilePath::StringType filename, 37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::StringPiece contents) { 38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ( 39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::checked_numeric_cast<int>(contents.size()), 40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_util::WriteFile( 41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) dir_.path().Append(filename), contents.data(), contents.size())); 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Converts |value| to JSON, and then writes it to path()/filename with 45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // WriteFile(). 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void WriteJson(base::FilePath::StringType filename, const Value& value) { 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string json; 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::JSONWriter::Write(&value, &json); 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WriteFile(filename, json); 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // This function packs the extension into a .crx, and returns the path to that 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // .crx. Multiple calls to Pack() will produce extensions with the same ID. 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FilePath Pack() { 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ExtensionCreator creator; 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FilePath crx_path = 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) crx_dir_.path().Append(FILE_PATH_LITERAL("ext.crx")); 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FilePath pem_path = 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) crx_dir_.path().Append(FILE_PATH_LITERAL("ext.pem")); 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FilePath pem_in_path, pem_out_path; 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (file_util::PathExists(pem_path)) 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pem_in_path = pem_path; 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) else 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pem_out_path = pem_path; 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!creator.Run(dir_.path(), 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) crx_path, 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pem_in_path, 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pem_out_path, 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ExtensionCreator::kOverwriteCRX)) { 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ADD_FAILURE() 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << "ExtensionCreator::Run() failed: " << creator.error_message(); 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return base::FilePath(); 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!file_util::PathExists(crx_path)) { 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ADD_FAILURE() << crx_path.value() << " was not created."; 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return base::FilePath(); 77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return crx_path; 79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Stores files that make up the extension. 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::ScopedTempDir dir_; 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Stores the generated .crx and .pem. 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::ScopedTempDir crx_dir_; 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class ExtensionLoadingTest : public ExtensionBrowserTest { 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Check the fix for http://crbug.com/178542. 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExtensionLoadingTest, 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) UpgradeAfterNavigatingFromOverriddenNewTabPage) { 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) embedded_test_server()->ServeFilesFromDirectory( 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TestExtensionDir extension_dir; 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<base::Value> manifest = 100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::test::ParseJson("{" 101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) " \"name\": \"Overrides New Tab\"," 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) " \"version\": \"1\"," 103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) " \"description\": \"Overrides New Tab\"," 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) " \"manifest_version\": 2," 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) " \"background\": {" 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) " \"persistent\": false," 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) " \"scripts\": [\"event.js\"]" 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) " }," 109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) " \"chrome_url_overrides\": {" 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) " \"newtab\": \"newtab.html\"" 111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) " }" 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "}"); 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension_dir.WriteJson(FILE_PATH_LITERAL("manifest.json"), *manifest); 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension_dir.WriteFile(FILE_PATH_LITERAL("event.js"), ""); 115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension_dir.WriteFile(FILE_PATH_LITERAL("newtab.html"), 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "<h1>Overridden New Tab Page</h1>"); 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const Extension* new_tab_extension = 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) InstallExtension(extension_dir.Pack(), 1 /*new install*/); 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_TRUE(new_tab_extension); 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Visit the New Tab Page to get a renderer using the extension into history. 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ui_test_utils::NavigateToURL(browser(), GURL("chrome://newtab")); 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Navigate that tab to a non-extension URL to swap out the extension's 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // renderer. 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const GURL test_link_from_NTP = 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) embedded_test_server()->GetURL("/README.chromium"); 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_THAT(test_link_from_NTP.spec(), testing::EndsWith("/README.chromium")) 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << "Check that the test server started."; 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NavigateInRenderer(browser()->tab_strip_model()->GetActiveWebContents(), 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) test_link_from_NTP); 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Increase the extension's version. 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static_cast<base::DictionaryValue&>(*manifest).SetString("version", "2"); 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension_dir.WriteJson(FILE_PATH_LITERAL("manifest.json"), *manifest); 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Upgrade the extension. 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new_tab_extension = UpdateExtension( 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new_tab_extension->id(), extension_dir.Pack(), 0 /*expected upgrade*/); 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_THAT(new_tab_extension->version()->components(), 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) testing::ElementsAre(2)); 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The extension takes a couple round-trips to the renderer in order 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // to crash, so open a new tab to wait long enough. 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddTabAtIndex(browser()->tab_strip_model()->count(), 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GURL("http://www.google.com/"), 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content::PAGE_TRANSITION_TYPED); 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Check that the extension hasn't crashed. 151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ExtensionService* service = 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ExtensionSystem::Get(profile())->extension_service(); 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(0U, service->terminated_extensions()->size()); 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(service->extensions()->Contains(new_tab_extension->id())); 155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace extensions 159