| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/extension_service_unittest.h" | 5 #include "chrome/browser/extensions/extension_service_unittest.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 // VisitRegisteredExtension(), which must be a const method to inherit | 228 // VisitRegisteredExtension(), which must be a const method to inherit |
| 229 // from the class being mocked. | 229 // from the class being mocked. |
| 230 mutable int visit_count_; | 230 mutable int visit_count_; |
| 231 | 231 |
| 232 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider); | 232 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider); |
| 233 }; | 233 }; |
| 234 | 234 |
| 235 class MockProviderVisitor | 235 class MockProviderVisitor |
| 236 : public ExternalExtensionProviderInterface::VisitorInterface { | 236 : public ExternalExtensionProviderInterface::VisitorInterface { |
| 237 public: | 237 public: |
| 238 |
| 238 // The provider will return |fake_base_path| from | 239 // The provider will return |fake_base_path| from |
| 239 // GetBaseCrxFilePath(). User can test the behavior with | 240 // GetBaseCrxFilePath(). User can test the behavior with |
| 240 // and without an empty path using this parameter. | 241 // and without an empty path using this parameter. |
| 241 explicit MockProviderVisitor(FilePath fake_base_path) | 242 explicit MockProviderVisitor(FilePath fake_base_path) |
| 242 : ids_found_(0), | 243 : ids_found_(0), |
| 243 fake_base_path_(fake_base_path), | 244 fake_base_path_(fake_base_path), |
| 244 expected_creation_flags_(Extension::NO_FLAGS) { | 245 expected_creation_flags_(Extension::NO_FLAGS) { |
| 245 } | 246 } |
| 246 | 247 |
| 247 MockProviderVisitor(FilePath fake_base_path, int expected_creation_flags) | 248 MockProviderVisitor(FilePath fake_base_path, int expected_creation_flags) |
| (...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 ASSERT_TRUE(file_util::PathExists(private_key_path)); | 1000 ASSERT_TRUE(file_util::PathExists(private_key_path)); |
| 1000 } | 1001 } |
| 1001 | 1002 |
| 1002 // The tests are designed so that we never expect to see a packing error. | 1003 // The tests are designed so that we never expect to see a packing error. |
| 1003 void PackExtensionTestClient::OnPackFailure(const std::string& error_message, | 1004 void PackExtensionTestClient::OnPackFailure(const std::string& error_message, |
| 1004 ExtensionCreator::ErrorType type) { | 1005 ExtensionCreator::ErrorType type) { |
| 1005 if (type == ExtensionCreator::kCRXExists) | 1006 if (type == ExtensionCreator::kCRXExists) |
| 1006 FAIL() << "Packing should not fail."; | 1007 FAIL() << "Packing should not fail."; |
| 1007 else | 1008 else |
| 1008 FAIL() << "Existing CRX should have been overwritten."; | 1009 FAIL() << "Existing CRX should have been overwritten."; |
| 1010 |
| 1009 } | 1011 } |
| 1010 | 1012 |
| 1011 // Test loading good extensions from the profile directory. | 1013 // Test loading good extensions from the profile directory. |
| 1012 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) { | 1014 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) { |
| 1013 PluginService::GetInstance()->Init(); | 1015 PluginService::GetInstance()->Init(); |
| 1014 | 1016 |
| 1015 // Initialize the test dir with a good Preferences/extensions. | 1017 // Initialize the test dir with a good Preferences/extensions. |
| 1016 FilePath source_install_dir = data_dir_ | 1018 FilePath source_install_dir = data_dir_ |
| 1017 .AppendASCII("good") | 1019 .AppendASCII("good") |
| 1018 .AppendASCII("Extensions"); | 1020 .AppendASCII("Extensions"); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1142 std::string("Could not load extension from '*'. ") + | 1144 std::string("Could not load extension from '*'. ") + |
| 1143 extension_manifest_errors::kMissingFile)) << | 1145 extension_manifest_errors::kMissingFile)) << |
| 1144 UTF16ToUTF8(GetErrors()[2]); | 1146 UTF16ToUTF8(GetErrors()[2]); |
| 1145 | 1147 |
| 1146 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[3]), | 1148 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[3]), |
| 1147 std::string("Could not load extension from '*'. ") + | 1149 std::string("Could not load extension from '*'. ") + |
| 1148 extension_manifest_errors::kManifestUnreadable)) << | 1150 extension_manifest_errors::kManifestUnreadable)) << |
| 1149 UTF16ToUTF8(GetErrors()[3]); | 1151 UTF16ToUTF8(GetErrors()[3]); |
| 1150 }; | 1152 }; |
| 1151 | 1153 |
| 1152 // Test that old versions of extensions are deleted during garbage collection. | 1154 // Test that partially deleted extensions are cleaned up during startup |
| 1153 TEST_F(ExtensionServiceTest, GarbageCollectOldVersions) { | 1155 // Test loading bad extensions from the profile directory. |
| 1156 TEST_F(ExtensionServiceTest, CleanupOnStartup) { |
| 1154 PluginService::GetInstance()->Init(); | 1157 PluginService::GetInstance()->Init(); |
| 1155 | 1158 |
| 1156 FilePath source_install_dir = data_dir_ | 1159 FilePath source_install_dir = data_dir_ |
| 1157 .AppendASCII("garbage_collection") | |
| 1158 .AppendASCII("Extensions"); | |
| 1159 | |
| 1160 FilePath pref_path = source_install_dir | |
| 1161 .DirName() | |
| 1162 .AppendASCII("Preferences"); | |
| 1163 | |
| 1164 InitializeInstalledExtensionService(pref_path, source_install_dir); | |
| 1165 | |
| 1166 // Verify that there are two versions present initially. | |
| 1167 ASSERT_TRUE(file_util::PathExists( | |
| 1168 extensions_install_dir_.AppendASCII("fdoajpacpdeapbmhbblepcnilfkpmkff") | |
| 1169 .AppendASCII("1.0_0"))); | |
| 1170 ASSERT_TRUE(file_util::PathExists( | |
| 1171 extensions_install_dir_.AppendASCII("fdoajpacpdeapbmhbblepcnilfkpmkff") | |
| 1172 .AppendASCII("1.1_0"))); | |
| 1173 | |
| 1174 ValidatePrefKeyCount(1u); | |
| 1175 | |
| 1176 service_->Init(); | |
| 1177 loop_.RunAllPending(); | |
| 1178 | |
| 1179 // Garbage collection should have deleted the old version. | |
| 1180 ASSERT_FALSE(file_util::PathExists( | |
| 1181 extensions_install_dir_.AppendASCII("fdoajpacpdeapbmhbblepcnilfkpmkff") | |
| 1182 .AppendASCII("1.0_0"))); | |
| 1183 ASSERT_TRUE(file_util::PathExists( | |
| 1184 extensions_install_dir_.AppendASCII("fdoajpacpdeapbmhbblepcnilfkpmkff") | |
| 1185 .AppendASCII("1.1_0"))); | |
| 1186 } | |
| 1187 | |
| 1188 // Test that extensions which were deleted from the preferences are cleaned up | |
| 1189 // during startup. | |
| 1190 // Test loading bad extensions from the profile directory. | |
| 1191 TEST_F(ExtensionServiceTest, GarbageCollectOnStartup) { | |
| 1192 PluginService::GetInstance()->Init(); | |
| 1193 | |
| 1194 FilePath source_install_dir = data_dir_ | |
| 1195 .AppendASCII("good") | 1160 .AppendASCII("good") |
| 1196 .AppendASCII("Extensions"); | 1161 .AppendASCII("Extensions"); |
| 1197 FilePath pref_path = source_install_dir | 1162 FilePath pref_path = source_install_dir |
| 1198 .DirName() | 1163 .DirName() |
| 1199 .AppendASCII("Preferences"); | 1164 .AppendASCII("Preferences"); |
| 1200 | 1165 |
| 1201 InitializeInstalledExtensionService(pref_path, source_install_dir); | 1166 InitializeInstalledExtensionService(pref_path, source_install_dir); |
| 1202 | 1167 |
| 1203 ValidatePrefKeyCount(3u); | |
| 1204 | |
| 1205 // Simulate that one of them got partially deleted by clearing its pref. | 1168 // Simulate that one of them got partially deleted by clearing its pref. |
| 1206 { | 1169 { |
| 1207 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings"); | 1170 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings"); |
| 1208 DictionaryValue* dict = update.Get(); | 1171 DictionaryValue* dict = update.Get(); |
| 1209 ASSERT_TRUE(dict); | 1172 ASSERT_TRUE(dict != NULL); |
| 1210 dict->Remove("behllobkkfkfnphdnhnkndlbkcpglgmj", NULL); | 1173 dict->Remove("behllobkkfkfnphdnhnkndlbkcpglgmj", NULL); |
| 1211 } | 1174 } |
| 1212 | 1175 |
| 1213 service_->Init(); | 1176 service_->Init(); |
| 1214 // Wait for GarbageCollectExtensions task to complete. | 1177 // Wait for GarbageCollectExtensions task to complete. |
| 1215 loop_.RunAllPending(); | 1178 loop_.RunAllPending(); |
| 1216 | 1179 |
| 1217 file_util::FileEnumerator dirs(extensions_install_dir_, false, | 1180 file_util::FileEnumerator dirs(extensions_install_dir_, false, |
| 1218 file_util::FileEnumerator::DIRECTORIES); | 1181 file_util::FileEnumerator::DIRECTORIES); |
| 1219 size_t count = 0; | 1182 size_t count = 0; |
| 1220 while (!dirs.Next().empty()) | 1183 while (!dirs.Next().empty()) |
| 1221 count++; | 1184 count++; |
| 1222 | 1185 |
| 1223 // We should have only gotten two extensions now. | 1186 // We should have only gotten two extensions now. |
| 1224 EXPECT_EQ(2u, count); | 1187 EXPECT_EQ(2u, count); |
| 1225 | 1188 |
| 1226 // And extension1 dir should now be toast. | 1189 // And extension1 dir should now be toast. |
| 1227 FilePath extension_dir = extensions_install_dir_ | 1190 FilePath extension_dir = extensions_install_dir_ |
| 1228 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj"); | 1191 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj"); |
| 1229 ASSERT_FALSE(file_util::PathExists(extension_dir)); | 1192 ASSERT_FALSE(file_util::PathExists(extension_dir)); |
| 1230 } | 1193 } |
| 1231 | 1194 |
| 1232 // Test that internal extensions which are referenced in the preferences but | |
| 1233 // had their content deleted are cleaned up during startup. | |
| 1234 TEST_F(ExtensionServiceTest, GarbageCollectInternalExtensionsMissingContent) { | |
| 1235 PluginService::GetInstance()->Init(); | |
| 1236 | |
| 1237 FilePath source_dir = data_dir_.AppendASCII("good").AppendASCII("Extensions"); | |
| 1238 FilePath pref_path = source_dir.DirName().AppendASCII("Preferences"); | |
| 1239 | |
| 1240 InitializeInstalledExtensionService(pref_path, source_dir); | |
| 1241 | |
| 1242 ValidatePrefKeyCount(3u); | |
| 1243 | |
| 1244 // Delete the extension's directory. | |
| 1245 FilePath extension_dir = extensions_install_dir_ | |
| 1246 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj"); | |
| 1247 ASSERT_TRUE(file_util::Delete(extension_dir, true)); | |
| 1248 | |
| 1249 // Run GarbageCollectExtensions. | |
| 1250 service_->Init(); | |
| 1251 loop_.RunAllPending(); | |
| 1252 | |
| 1253 file_util::FileEnumerator dirs(extensions_install_dir_, false, | |
| 1254 file_util::FileEnumerator::DIRECTORIES); | |
| 1255 size_t count = 0; | |
| 1256 while (!dirs.Next().empty()) | |
| 1257 count++; | |
| 1258 | |
| 1259 // We should have only gotten two extensions now. | |
| 1260 EXPECT_EQ(2u, count); | |
| 1261 | |
| 1262 const DictionaryValue* dictionary = | |
| 1263 profile_->GetPrefs()->GetDictionary("extensions.settings"); | |
| 1264 ASSERT_TRUE(dictionary); | |
| 1265 ASSERT_FALSE(dictionary->HasKey("behllobkkfkfnphdnhnkndlbkcpglgmj")); | |
| 1266 } | |
| 1267 | |
| 1268 // Test that unpacked extensions which are referenced in the preferences but | |
| 1269 // had their content deleted are cleaned up during startup. | |
| 1270 TEST_F(ExtensionServiceTest, GarbageCollectUnpackedExtensionsMissingContent) { | |
| 1271 InitializeEmptyExtensionService(); | |
| 1272 | |
| 1273 ScopedTempDir temp; | |
| 1274 ASSERT_TRUE(temp.CreateUniqueTempDir()); | |
| 1275 | |
| 1276 // Write the manifest dynamically, since we have to delete the file anyway. | |
| 1277 FilePath extension_path = temp.path(); | |
| 1278 FilePath manifest_path = extension_path.Append(Extension::kManifestFilename); | |
| 1279 ASSERT_FALSE(file_util::PathExists(manifest_path)); | |
| 1280 | |
| 1281 // Construct a simple manifest and install it. | |
| 1282 DictionaryValue manifest; | |
| 1283 manifest.SetString("version", "1.0"); | |
| 1284 manifest.SetString("name", "Cleanup Unpacked Extensions Missing Content"); | |
| 1285 manifest.SetInteger("manifest_version", 2); | |
| 1286 | |
| 1287 JSONFileValueSerializer serializer(manifest_path); | |
| 1288 ASSERT_TRUE(serializer.Serialize(manifest)); | |
| 1289 | |
| 1290 extensions::UnpackedInstaller::Create(service_)->Load(extension_path); | |
| 1291 loop_.RunAllPending(); | |
| 1292 | |
| 1293 // Make sure it installed correctly. | |
| 1294 EXPECT_EQ(0u, GetErrors().size()); | |
| 1295 ASSERT_EQ(1u, loaded_.size()); | |
| 1296 EXPECT_EQ(Extension::LOAD, loaded_[0]->location()); | |
| 1297 EXPECT_EQ(1u, service_->extensions()->size()); | |
| 1298 | |
| 1299 std::string extension_id = loaded_[0]->id(); | |
| 1300 | |
| 1301 // Make sure it is in the preferences at this point. | |
| 1302 const DictionaryValue* initial_dictionary = | |
| 1303 profile_->GetPrefs()->GetDictionary("extensions.settings"); | |
| 1304 ASSERT_TRUE(initial_dictionary); | |
| 1305 ASSERT_TRUE(initial_dictionary->HasKey(extension_id)); | |
| 1306 | |
| 1307 // Delete local content, GarbageCollectExtensions, and test whether the key | |
| 1308 // is still in the preferences. | |
| 1309 ASSERT_TRUE(file_util::Delete(extension_path, true)); | |
| 1310 service_->GarbageCollectExtensions(); | |
| 1311 loop_.RunAllPending(); | |
| 1312 | |
| 1313 const DictionaryValue* final_dictionary = | |
| 1314 profile_->GetPrefs()->GetDictionary("extensions.settings"); | |
| 1315 ASSERT_TRUE(final_dictionary); | |
| 1316 ASSERT_FALSE(final_dictionary->HasKey(extension_id)); | |
| 1317 } | |
| 1318 | |
| 1319 // Test installing extensions. This test tries to install few extensions using | 1195 // Test installing extensions. This test tries to install few extensions using |
| 1320 // crx files. If you need to change those crx files, feel free to repackage | 1196 // crx files. If you need to change those crx files, feel free to repackage |
| 1321 // them, throw away the key used and change the id's above. | 1197 // them, throw away the key used and change the id's above. |
| 1322 TEST_F(ExtensionServiceTest, InstallExtension) { | 1198 TEST_F(ExtensionServiceTest, InstallExtension) { |
| 1323 InitializeEmptyExtensionService(); | 1199 InitializeEmptyExtensionService(); |
| 1324 | 1200 |
| 1325 // Extensions not enabled. | 1201 // Extensions not enabled. |
| 1326 set_extensions_enabled(false); | 1202 set_extensions_enabled(false); |
| 1327 FilePath path = data_dir_.AppendASCII("good.crx"); | 1203 FilePath path = data_dir_.AppendASCII("good.crx"); |
| 1328 InstallCRX(path, INSTALL_FAILED); | 1204 InstallCRX(path, INSTALL_FAILED); |
| (...skipping 3983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5312 provider->UpdateOrAddExtension(hosted_app, "1.0.0.0", | 5188 provider->UpdateOrAddExtension(hosted_app, "1.0.0.0", |
| 5313 data_dir_.AppendASCII("hosted_app.crx")); | 5189 data_dir_.AppendASCII("hosted_app.crx")); |
| 5314 | 5190 |
| 5315 service_->CheckForExternalUpdates(); | 5191 service_->CheckForExternalUpdates(); |
| 5316 loop_.RunAllPending(); | 5192 loop_.RunAllPending(); |
| 5317 | 5193 |
| 5318 ASSERT_TRUE(service_->PopulateExtensionGlobalError( | 5194 ASSERT_TRUE(service_->PopulateExtensionGlobalError( |
| 5319 extension_global_error.get())); | 5195 extension_global_error.get())); |
| 5320 ASSERT_EQ(1u, extension_global_error->get_external_extension_ids()->size()); | 5196 ASSERT_EQ(1u, extension_global_error->get_external_extension_ids()->size()); |
| 5321 } | 5197 } |
| OLD | NEW |