summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/extensions_service_unittest.cc
diff options
context:
space:
mode:
authorfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-16 04:20:42 +0000
committerfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-16 04:20:42 +0000
commitd55e76095697233ab43bb8ddce9cc65bb82d0b7f (patch)
treea6e411cb35564dd51862089031df8e4f7bc8de0f /chrome/browser/extensions/extensions_service_unittest.cc
parentf21f89e9551c521934ff2c86277503094468eca7 (diff)
downloadchromium_src-d55e76095697233ab43bb8ddce9cc65bb82d0b7f.zip
chromium_src-d55e76095697233ab43bb8ddce9cc65bb82d0b7f.tar.gz
chromium_src-d55e76095697233ab43bb8ddce9cc65bb82d0b7f.tar.bz2
Fix browser crash in extension system.
When an external extension is removed from the json file (for example by a 3rd party installer) after the user has explicitly uninstalled it, Chrome would start crashing and crashing. This is now fixed. Also added a couple of unit tests for this case (for each external provider) and cleaned up one of those unit tests to make it match what the other was doing. BUG=http://crbug.com/30505 TEST=Covered by unit test. Review URL: http://codereview.chromium.org/504016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34649 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions/extensions_service_unittest.cc')
-rw-r--r--chrome/browser/extensions/extensions_service_unittest.cc166
1 files changed, 49 insertions, 117 deletions
diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc
index dc8bdd6..74709ed 100644
--- a/chrome/browser/extensions/extensions_service_unittest.cc
+++ b/chrome/browser/extensions/extensions_service_unittest.cc
@@ -327,6 +327,9 @@ class ExtensionsServiceTest
}
protected:
+ void TestExternalProvider(MockExtensionProvider* provider,
+ Extension::Location location);
+
void InstallExtension(const FilePath& path,
bool should_succeed) {
ASSERT_TRUE(file_util::PathExists(path));
@@ -1286,30 +1289,20 @@ TEST_F(ExtensionsServiceTest, GenerateID) {
ASSERT_EQ(previous_id, loaded_[0]->id());
}
-// Tests the external installation feature
-#if defined(OS_WIN)
-
-TEST_F(ExtensionsServiceTest, ExternalInstallRegistry) {
- // This should all work, even when normal extension installation is disabled.
- InitializeEmptyExtensionsService();
- set_extensions_enabled(false);
+void ExtensionsServiceTest::TestExternalProvider(
+ MockExtensionProvider* provider, Extension::Location location) {
// Verify that starting with no providers loads no extensions.
service_->Init();
loop_.RunAllPending();
ASSERT_EQ(0u, loaded_.size());
- // Now add providers. Extension system takes ownership of the objects.
- MockExtensionProvider* reg_provider =
- new MockExtensionProvider(Extension::EXTERNAL_REGISTRY);
- SetMockExternalProvider(Extension::EXTERNAL_REGISTRY, reg_provider);
-
// Register a test extension externally using the mock registry provider.
FilePath source_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_path));
source_path = source_path.AppendASCII("extensions").AppendASCII("good.crx");
// Add the extension.
- reg_provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
+ provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
// Reloading extensions should find our externally registered extension
// and install it.
@@ -1318,11 +1311,11 @@ TEST_F(ExtensionsServiceTest, ExternalInstallRegistry) {
ASSERT_EQ(0u, GetErrors().size());
ASSERT_EQ(1u, loaded_.size());
- ASSERT_EQ(Extension::EXTERNAL_REGISTRY, loaded_[0]->location());
+ ASSERT_EQ(location, loaded_[0]->location());
ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
ValidatePrefKeyCount(1);
ValidateIntegerPref(good_crx, L"state", Extension::ENABLED);
- ValidateIntegerPref(good_crx, L"location", Extension::EXTERNAL_REGISTRY);
+ ValidateIntegerPref(good_crx, L"location", location);
// Reload extensions without changing anything. The extension should be
// loaded again.
@@ -1333,11 +1326,11 @@ TEST_F(ExtensionsServiceTest, ExternalInstallRegistry) {
ASSERT_EQ(1u, loaded_.size());
ValidatePrefKeyCount(1);
ValidateIntegerPref(good_crx, L"state", Extension::ENABLED);
- ValidateIntegerPref(good_crx, L"location", Extension::EXTERNAL_REGISTRY);
+ ValidateIntegerPref(good_crx, L"location", location);
// Now update the extension with a new version. We should get upgraded.
source_path = source_path.DirName().AppendASCII("good2.crx");
- reg_provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
+ provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
loaded_.clear();
service_->CheckForExternalUpdates();
@@ -1347,7 +1340,7 @@ TEST_F(ExtensionsServiceTest, ExternalInstallRegistry) {
ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
ValidatePrefKeyCount(1);
ValidateIntegerPref(good_crx, L"state", Extension::ENABLED);
- ValidateIntegerPref(good_crx, L"location", Extension::EXTERNAL_REGISTRY);
+ ValidateIntegerPref(good_crx, L"location", location);
// Uninstall the extension and reload. Nothing should happen because the
// preference should prevent us from reinstalling.
@@ -1365,10 +1358,9 @@ TEST_F(ExtensionsServiceTest, ExternalInstallRegistry) {
ASSERT_EQ(0u, loaded_.size());
ValidatePrefKeyCount(1);
ValidateIntegerPref(good_crx, L"state", Extension::KILLBIT);
- ValidateIntegerPref(good_crx, L"location", Extension::EXTERNAL_REGISTRY);
+ ValidateIntegerPref(good_crx, L"location", location);
- // Now clear the preference, reinstall, then remove the reg key. The extension
- // should be uninstalled.
+ // Now clear the preference and reinstall.
SetPrefInteg(good_crx, L"state", Extension::ENABLED);
prefs_->ScheduleSavePersistentPrefs();
@@ -1378,10 +1370,11 @@ TEST_F(ExtensionsServiceTest, ExternalInstallRegistry) {
ASSERT_EQ(1u, loaded_.size());
ValidatePrefKeyCount(1);
ValidateIntegerPref(good_crx, L"state", Extension::ENABLED);
- ValidateIntegerPref(good_crx, L"location", Extension::EXTERNAL_REGISTRY);
+ ValidateIntegerPref(good_crx, L"location", location);
- // Now test an externally triggered uninstall (deleting the registry key).
- reg_provider->RemoveExtension(good_crx);
+ // Now test an externally triggered uninstall (deleting the registry key or
+ // the pref entry).
+ provider->RemoveExtension(good_crx);
loaded_.clear();
service_->LoadAllExtensions();
@@ -1391,120 +1384,59 @@ TEST_F(ExtensionsServiceTest, ExternalInstallRegistry) {
// The extension should also be gone from the install directory.
ASSERT_FALSE(file_util::PathExists(install_path));
-}
-
-#endif
-
-TEST_F(ExtensionsServiceTest, ExternalInstallPref) {
- InitializeEmptyExtensionsService();
- // Verify that starting with no providers loads no extensions.
- service_->Init();
- loop_.RunAllPending();
- ASSERT_EQ(0u, loaded_.size());
-
- // Now add providers. Extension system takes ownership of the objects.
- MockExtensionProvider* pref_provider =
- new MockExtensionProvider(Extension::EXTERNAL_PREF);
- SetMockExternalProvider(Extension::EXTERNAL_PREF, pref_provider);
- // Register a external extension using preinstalled preferences.
- FilePath source_path;
- ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_path));
- source_path = source_path.AppendASCII("extensions").AppendASCII("good.crx");
-
- // Add the extension.
- pref_provider->UpdateOrAddExtension(good_crx, "1.0", source_path);
+ // Now test the case where user uninstalls and then the extension is removed
+ // from the external provider.
- // Checking for updates should find our externally registered extension
- // and install it.
+ provider->UpdateOrAddExtension(good_crx, "1.0", source_path);
service_->CheckForExternalUpdates();
loop_.RunAllPending();
- ASSERT_EQ(0u, GetErrors().size());
ASSERT_EQ(1u, loaded_.size());
- ASSERT_EQ(Extension::EXTERNAL_PREF, loaded_[0]->location());
- ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
- ValidatePrefKeyCount(1);
- ValidateIntegerPref(good_crx, L"state", Extension::ENABLED);
- ValidateIntegerPref(good_crx, L"location", Extension::EXTERNAL_PREF);
-
- // Reload extensions without changing anything. The extension should be
- // loaded again.
- loaded_.clear();
- service_->ReloadExtensions();
- loop_.RunAllPending();
- ASSERT_EQ(0u, GetErrors().size());
- ASSERT_EQ(1u, loaded_.size());
- ValidatePrefKeyCount(1);
- ValidateIntegerPref(good_crx, L"state", Extension::ENABLED);
- ValidateIntegerPref(good_crx, L"location", Extension::EXTERNAL_PREF);
-
- // Now update the extension with a new version. We should get upgraded.
- source_path = source_path.DirName().AppendASCII("good2.crx");
- pref_provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
+ ASSERT_EQ(1u, GetErrors().size());
+ // User uninstalls.
loaded_.clear();
- service_->CheckForExternalUpdates();
- loop_.RunAllPending();
- ASSERT_EQ(0u, GetErrors().size());
- ASSERT_EQ(1u, loaded_.size());
- ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
- ValidatePrefKeyCount(1);
- ValidateIntegerPref(good_crx, L"state", Extension::ENABLED);
- ValidateIntegerPref(good_crx, L"location", Extension::EXTERNAL_PREF);
-
- // Uninstall the extension and reload. Nothing should happen because the
- // preference should prevent us from reinstalling.
- std::string id = loaded_[0]->id();
service_->UninstallExtension(id, false);
loop_.RunAllPending();
-
- // The extension should also be gone from the install directory.
- FilePath install_path = extensions_install_dir_.AppendASCII(id);
- ASSERT_FALSE(file_util::PathExists(install_path));
-
- loaded_.clear();
- service_->CheckForExternalUpdates();
- loop_.RunAllPending();
ASSERT_EQ(0u, loaded_.size());
- ValidatePrefKeyCount(1);
- ValidateIntegerPref(good_crx, L"state", Extension::KILLBIT);
- ValidateIntegerPref(good_crx, L"location", Extension::EXTERNAL_PREF);
-
- // Now clear the preference and reinstall.
- SetPrefInteg(good_crx, L"state", Extension::ENABLED);
- prefs_->ScheduleSavePersistentPrefs();
-
- loaded_.clear();
- service_->CheckForExternalUpdates();
- loop_.RunAllPending();
- ASSERT_EQ(1u, loaded_.size());
- ValidatePrefKeyCount(1);
- ValidateIntegerPref(good_crx, L"state", Extension::ENABLED);
- ValidateIntegerPref(good_crx, L"location", Extension::EXTERNAL_PREF);
- // Now test an externally triggered uninstall (deleting id from json file).
- pref_provider->RemoveExtension(good_crx);
+ // Then remove the extension from the extension provider.
+ provider->RemoveExtension(good_crx);
+ // Should still be at 0.
loaded_.clear();
service_->LoadAllExtensions();
loop_.RunAllPending();
ASSERT_EQ(0u, loaded_.size());
- ValidatePrefKeyCount(0);
-
- // The extension should also be gone from the install directory.
- ASSERT_FALSE(file_util::PathExists(install_path));
+ ValidatePrefKeyCount(1);
+}
- // It should still work if extensions are disabled (disableness doesn't
- // apply to externally registered extensions).
+// Tests the external installation feature
+#if defined(OS_WIN)
+TEST_F(ExtensionsServiceTest, ExternalInstallRegistry) {
+ // This should all work, even when normal extension installation is disabled.
+ InitializeEmptyExtensionsService();
set_extensions_enabled(false);
- pref_provider->UpdateOrAddExtension(good_crx, "1.0", source_path);
- service_->CheckForExternalUpdates();
- loop_.RunAllPending();
+ // Now add providers. Extension system takes ownership of the objects.
+ MockExtensionProvider* reg_provider =
+ new MockExtensionProvider(Extension::EXTERNAL_REGISTRY);
+ SetMockExternalProvider(Extension::EXTERNAL_REGISTRY, reg_provider);
+ TestExternalProvider(reg_provider, Extension::EXTERNAL_REGISTRY);
+}
+#endif
- ASSERT_EQ(1u, loaded_.size());
- ASSERT_EQ(1u, GetErrors().size());
+TEST_F(ExtensionsServiceTest, ExternalInstallPref) {
+ // This should all work, even when normal extension installation is disabled.
+ InitializeEmptyExtensionsService();
+ set_extensions_enabled(false);
+
+ // Now add providers. Extension system takes ownership of the objects.
+ MockExtensionProvider* pref_provider =
+ new MockExtensionProvider(Extension::EXTERNAL_PREF);
+ SetMockExternalProvider(Extension::EXTERNAL_PREF, pref_provider);
+ TestExternalProvider(pref_provider, Extension::EXTERNAL_PREF);
}
TEST_F(ExtensionsServiceTest, ExternalPrefProvider) {