OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <map> | 5 #include <map> |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/memory/weak_ptr.h" |
10 #include "base/stl_util-inl.h" | 11 #include "base/stl_util-inl.h" |
11 #include "base/string_number_conversions.h" | 12 #include "base/string_number_conversions.h" |
12 #include "base/string_split.h" | 13 #include "base/string_split.h" |
13 #include "base/string_util.h" | 14 #include "base/string_util.h" |
14 #include "base/stringprintf.h" | 15 #include "base/stringprintf.h" |
15 #include "base/threading/thread.h" | 16 #include "base/threading/thread.h" |
16 #include "base/version.h" | 17 #include "base/version.h" |
| 18 #include "chrome/browser/extensions/crx_installer.h" |
17 #include "chrome/browser/extensions/extension_error_reporter.h" | 19 #include "chrome/browser/extensions/extension_error_reporter.h" |
18 #include "chrome/browser/extensions/extension_sync_data.h" | 20 #include "chrome/browser/extensions/extension_sync_data.h" |
19 #include "chrome/browser/extensions/extension_updater.h" | 21 #include "chrome/browser/extensions/extension_updater.h" |
20 #include "chrome/browser/extensions/test_extension_prefs.h" | 22 #include "chrome/browser/extensions/test_extension_prefs.h" |
21 #include "chrome/browser/extensions/test_extension_service.h" | 23 #include "chrome/browser/extensions/test_extension_service.h" |
22 #include "chrome/browser/prefs/pref_service.h" | 24 #include "chrome/browser/prefs/pref_service.h" |
23 #include "chrome/common/extensions/extension.h" | 25 #include "chrome/common/extensions/extension.h" |
24 #include "chrome/common/extensions/extension_constants.h" | 26 #include "chrome/common/extensions/extension_constants.h" |
25 #include "chrome/common/net/test_url_fetcher_factory.h" | 27 #include "chrome/common/net/test_url_fetcher_factory.h" |
26 #include "chrome/common/pref_names.h" | 28 #include "chrome/common/pref_names.h" |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 void set_extensions(ExtensionList extensions) { | 171 void set_extensions(ExtensionList extensions) { |
170 extensions_ = extensions; | 172 extensions_ = extensions; |
171 } | 173 } |
172 | 174 |
173 private: | 175 private: |
174 ExtensionList extensions_; | 176 ExtensionList extensions_; |
175 }; | 177 }; |
176 | 178 |
177 class ServiceForDownloadTests : public MockService { | 179 class ServiceForDownloadTests : public MockService { |
178 public: | 180 public: |
179 virtual void UpdateExtension(const std::string& id, | 181 ServiceForDownloadTests() |
180 const FilePath& extension_path, | 182 : MockService() { |
181 const GURL& download_url) { | 183 } |
| 184 |
| 185 // Add a fake crx installer to be returned by a call to UpdateExtension() |
| 186 // with a specific ID. Caller keeps ownership of |crx_installer|. |
| 187 void AddFakeCrxInstaller(std::string& id, |
| 188 CrxInstaller* crx_installer) { |
| 189 fake_crx_installers_[id] = crx_installer; |
| 190 } |
| 191 |
| 192 bool UpdateExtension( |
| 193 const std::string& id, |
| 194 const FilePath& extension_path, |
| 195 const GURL& download_url, |
| 196 CrxInstaller** out_crx_installer) OVERRIDE { |
182 extension_id_ = id; | 197 extension_id_ = id; |
183 install_path_ = extension_path; | 198 install_path_ = extension_path; |
184 download_url_ = download_url; | 199 download_url_ = download_url; |
| 200 |
| 201 if (ContainsKey(fake_crx_installers_, id)) { |
| 202 *out_crx_installer = fake_crx_installers_[id]; |
| 203 return true; |
| 204 } |
| 205 |
| 206 return false; |
185 } | 207 } |
186 | 208 |
187 virtual PendingExtensionManager* pending_extension_manager() OVERRIDE { | 209 virtual PendingExtensionManager* pending_extension_manager() OVERRIDE { |
188 return &pending_extension_manager_; | 210 return &pending_extension_manager_; |
189 } | 211 } |
190 | 212 |
191 virtual const Extension* GetExtensionById( | 213 virtual const Extension* GetExtensionById( |
192 const std::string& id, bool) const OVERRIDE { | 214 const std::string& id, bool) const OVERRIDE { |
193 last_inquired_extension_id_ = id; | 215 last_inquired_extension_id_ = id; |
194 return NULL; | 216 return NULL; |
195 } | 217 } |
196 | 218 |
197 const std::string& extension_id() const { return extension_id_; } | 219 const std::string& extension_id() const { return extension_id_; } |
198 const FilePath& install_path() const { return install_path_; } | 220 const FilePath& install_path() const { return install_path_; } |
199 const GURL& download_url() const { return download_url_; } | 221 const GURL& download_url() const { return download_url_; } |
200 const std::string& last_inquired_extension_id() const { | 222 const std::string& last_inquired_extension_id() const { |
201 return last_inquired_extension_id_; | 223 return last_inquired_extension_id_; |
202 } | 224 } |
203 | 225 |
204 private: | 226 private: |
| 227 // Hold the set of ids that UpdateExtension() should fake success on. |
| 228 // UpdateExtension(id, ...) will return true iff fake_crx_installers_ |
| 229 // contains key |id|. |out_install_notification_source| will be set |
| 230 // to Source<CrxInstaller(fake_crx_installers_[i]). |
| 231 std::map<std::string, CrxInstaller*> fake_crx_installers_; |
| 232 |
205 std::string extension_id_; | 233 std::string extension_id_; |
206 FilePath install_path_; | 234 FilePath install_path_; |
207 GURL download_url_; | 235 GURL download_url_; |
208 | 236 |
209 // The last extension ID that GetExtensionById was called with. | 237 // The last extension ID that GetExtensionById was called with. |
210 // Mutable because the method that sets it (GetExtensionById) is const | 238 // Mutable because the method that sets it (GetExtensionById) is const |
211 // in the actual extension service, but must record the last extension | 239 // in the actual extension service, but must record the last extension |
212 // ID in this test class. | 240 // ID in this test class. |
213 mutable std::string last_inquired_extension_id_; | 241 mutable std::string last_inquired_extension_id_; |
214 }; | 242 }; |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 BrowserThread ui_thread(BrowserThread::UI, &ui_loop); | 574 BrowserThread ui_thread(BrowserThread::UI, &ui_loop); |
547 BrowserThread file_thread(BrowserThread::FILE); | 575 BrowserThread file_thread(BrowserThread::FILE); |
548 file_thread.Start(); | 576 file_thread.Start(); |
549 BrowserThread io_thread(BrowserThread::IO); | 577 BrowserThread io_thread(BrowserThread::IO); |
550 io_thread.Start(); | 578 io_thread.Start(); |
551 | 579 |
552 TestURLFetcherFactory factory; | 580 TestURLFetcherFactory factory; |
553 TestURLFetcher* fetcher = NULL; | 581 TestURLFetcher* fetcher = NULL; |
554 URLFetcher::set_factory(&factory); | 582 URLFetcher::set_factory(&factory); |
555 scoped_ptr<ServiceForDownloadTests> service(new ServiceForDownloadTests); | 583 scoped_ptr<ServiceForDownloadTests> service(new ServiceForDownloadTests); |
556 ExtensionUpdater updater(service.get(), service->extension_prefs(), | 584 ExtensionUpdater updater(service.get(), |
| 585 service->extension_prefs(), |
557 service->pref_service(), | 586 service->pref_service(), |
558 service->profile(), | 587 service->profile(), |
559 kUpdateFrequencySecs); | 588 kUpdateFrequencySecs); |
560 updater.Start(); | 589 updater.Start(); |
561 | 590 |
562 GURL url1("http://localhost/manifest1"); | 591 GURL url1("http://localhost/manifest1"); |
563 GURL url2("http://localhost/manifest2"); | 592 GURL url2("http://localhost/manifest2"); |
564 | 593 |
565 // Request 2 update checks - the first should begin immediately and the | 594 // Request 2 update checks - the first should begin immediately and the |
566 // second one should be queued up. | 595 // second one should be queued up. |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
732 // The updater should have called extension service to process the | 761 // The updater should have called extension service to process the |
733 // blacklist. | 762 // blacklist. |
734 EXPECT_TRUE(service.processed_blacklist()); | 763 EXPECT_TRUE(service.processed_blacklist()); |
735 | 764 |
736 EXPECT_EQ(version, service.pref_service()-> | 765 EXPECT_EQ(version, service.pref_service()-> |
737 GetString(prefs::kExtensionBlacklistUpdateVersion)); | 766 GetString(prefs::kExtensionBlacklistUpdateVersion)); |
738 | 767 |
739 URLFetcher::set_factory(NULL); | 768 URLFetcher::set_factory(NULL); |
740 } | 769 } |
741 | 770 |
742 static void TestMultipleExtensionDownloading() { | 771 // Two extensions are updated. If |updates_start_running| is true, the |
| 772 // mock extensions service has UpdateExtension(...) return true, and |
| 773 // the test is responsible for creating fake CrxInstallers. Otherwise, |
| 774 // UpdateExtension() returns false, signaling install failures. |
| 775 static void TestMultipleExtensionDownloading(bool updates_start_running) { |
743 MessageLoopForUI message_loop; | 776 MessageLoopForUI message_loop; |
744 BrowserThread ui_thread(BrowserThread::UI, &message_loop); | 777 BrowserThread ui_thread(BrowserThread::UI, &message_loop); |
745 BrowserThread file_thread(BrowserThread::FILE, &message_loop); | 778 BrowserThread file_thread(BrowserThread::FILE, &message_loop); |
746 BrowserThread io_thread(BrowserThread::IO); | 779 BrowserThread io_thread(BrowserThread::IO); |
747 io_thread.Start(); | 780 io_thread.Start(); |
748 | 781 |
749 TestURLFetcherFactory factory; | 782 TestURLFetcherFactory factory; |
750 TestURLFetcher* fetcher = NULL; | 783 TestURLFetcher* fetcher = NULL; |
751 URLFetcher::set_factory(&factory); | 784 URLFetcher::set_factory(&factory); |
752 ServiceForDownloadTests service; | 785 ServiceForDownloadTests service; |
753 ExtensionUpdater updater( | 786 ExtensionUpdater updater( |
754 &service, service.extension_prefs(), service.pref_service(), | 787 &service, service.extension_prefs(), service.pref_service(), |
755 service.profile(), kUpdateFrequencySecs); | 788 service.profile(), kUpdateFrequencySecs); |
756 updater.Start(); | 789 updater.Start(); |
757 | 790 |
| 791 EXPECT_FALSE(updater.crx_install_is_running_); |
| 792 |
758 GURL url1("http://localhost/extension1.crx"); | 793 GURL url1("http://localhost/extension1.crx"); |
759 GURL url2("http://localhost/extension2.crx"); | 794 GURL url2("http://localhost/extension2.crx"); |
760 | 795 |
761 std::string id1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; | 796 std::string id1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; |
762 std::string id2 = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; | 797 std::string id2 = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; |
763 | 798 |
764 std::string hash1 = ""; | 799 std::string hash1 = ""; |
765 std::string hash2 = ""; | 800 std::string hash2 = ""; |
766 | 801 |
767 std::string version1 = "0.1"; | 802 std::string version1 = "0.1"; |
768 std::string version2 = "0.1"; | 803 std::string version2 = "0.1"; |
769 // Start two fetches | 804 // Start two fetches |
770 updater.FetchUpdatedExtension(id1, url1, hash1, version1); | 805 updater.FetchUpdatedExtension(id1, url1, hash1, version1); |
771 updater.FetchUpdatedExtension(id2, url2, hash2, version2); | 806 updater.FetchUpdatedExtension(id2, url2, hash2, version2); |
772 | 807 |
773 // Make the first fetch complete. | 808 // Make the first fetch complete. |
774 FilePath extension_file_path(FILE_PATH_LITERAL("/whatever")); | 809 FilePath extension_file_path(FILE_PATH_LITERAL("/whatever")); |
775 | 810 |
776 fetcher = factory.GetFetcherByID(ExtensionUpdater::kExtensionFetcherId); | 811 fetcher = factory.GetFetcherByID(ExtensionUpdater::kExtensionFetcherId); |
777 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL); | 812 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL); |
778 EXPECT_TRUE(fetcher->load_flags() == expected_load_flags); | 813 EXPECT_TRUE(fetcher->load_flags() == expected_load_flags); |
779 | 814 |
| 815 // We need some CrxInstallers, and CrxInstallers require a real |
| 816 // ExtensionService. Create one on the testing profile. Any action |
| 817 // the CrxInstallers take is on the testing profile's extension |
| 818 // service, not on our mock |service|. This allows us to fake |
| 819 // the CrxInstaller actions we want. |
| 820 TestingProfile profile; |
| 821 profile.CreateExtensionService( |
| 822 CommandLine::ForCurrentProcess(), |
| 823 FilePath(), |
| 824 false); |
| 825 profile.GetExtensionService()->set_extensions_enabled(true); |
| 826 profile.GetExtensionService()->set_show_extensions_prompts(false); |
| 827 |
| 828 scoped_refptr<CrxInstaller> fake_crx1( |
| 829 profile.GetExtensionService()->MakeCrxInstaller(NULL)); |
| 830 scoped_refptr<CrxInstaller> fake_crx2( |
| 831 profile.GetExtensionService()->MakeCrxInstaller(NULL)); |
| 832 |
| 833 if (updates_start_running) { |
| 834 // Add fake CrxInstaller to be returned by service.UpdateExtension(). |
| 835 service.AddFakeCrxInstaller(id1, fake_crx1.get()); |
| 836 service.AddFakeCrxInstaller(id2, fake_crx2.get()); |
| 837 } else { |
| 838 // If we don't add fake CRX installers, the mock service fakes a failure |
| 839 // starting the install. |
| 840 } |
| 841 |
780 fetcher->set_url(url1); | 842 fetcher->set_url(url1); |
781 fetcher->set_status(net::URLRequestStatus()); | 843 fetcher->set_status(net::URLRequestStatus()); |
782 fetcher->set_response_code(200); | 844 fetcher->set_response_code(200); |
783 fetcher->SetResponseFilePath(extension_file_path); | 845 fetcher->SetResponseFilePath(extension_file_path); |
784 fetcher->delegate()->OnURLFetchComplete(fetcher); | 846 fetcher->delegate()->OnURLFetchComplete(fetcher); |
785 | 847 |
786 message_loop.RunAllPending(); | 848 message_loop.RunAllPending(); |
787 | 849 |
788 // Expect that the service was asked to do an install with the right data. | 850 // Expect that the service was asked to do an install with the right data. |
789 FilePath tmpfile_path = service.install_path(); | 851 FilePath tmpfile_path = service.install_path(); |
790 EXPECT_FALSE(tmpfile_path.empty()); | 852 EXPECT_FALSE(tmpfile_path.empty()); |
791 EXPECT_EQ(id1, service.extension_id()); | 853 EXPECT_EQ(id1, service.extension_id()); |
792 EXPECT_EQ(url1, service.download_url()); | 854 EXPECT_EQ(url1, service.download_url()); |
793 message_loop.RunAllPending(); | 855 message_loop.RunAllPending(); |
794 | 856 |
795 // Make sure the second fetch finished and asked the service to do an | 857 // Make sure the second fetch finished and asked the service to do an |
796 // update. | 858 // update. |
797 FilePath extension_file_path2(FILE_PATH_LITERAL("/whatever2")); | 859 FilePath extension_file_path2(FILE_PATH_LITERAL("/whatever2")); |
798 fetcher = factory.GetFetcherByID(ExtensionUpdater::kExtensionFetcherId); | 860 fetcher = factory.GetFetcherByID(ExtensionUpdater::kExtensionFetcherId); |
799 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL); | 861 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL); |
800 EXPECT_TRUE(fetcher->load_flags() == expected_load_flags); | 862 EXPECT_TRUE(fetcher->load_flags() == expected_load_flags); |
801 | 863 |
802 fetcher->set_url(url2); | 864 fetcher->set_url(url2); |
803 fetcher->set_status(net::URLRequestStatus()); | 865 fetcher->set_status(net::URLRequestStatus()); |
804 fetcher->set_response_code(200); | 866 fetcher->set_response_code(200); |
805 fetcher->SetResponseFilePath(extension_file_path2); | 867 fetcher->SetResponseFilePath(extension_file_path2); |
806 fetcher->delegate()->OnURLFetchComplete(fetcher); | 868 fetcher->delegate()->OnURLFetchComplete(fetcher); |
807 message_loop.RunAllPending(); | 869 message_loop.RunAllPending(); |
| 870 |
| 871 if (updates_start_running) { |
| 872 EXPECT_TRUE(updater.crx_install_is_running_); |
| 873 |
| 874 // The second install should not have run, because the first has not |
| 875 // sent a notification that it finished. |
| 876 EXPECT_EQ(id1, service.extension_id()); |
| 877 EXPECT_EQ(url1, service.download_url()); |
| 878 |
| 879 // Fake install notice. This should start the second installation, |
| 880 // which will be checked below. |
| 881 fake_crx1->NotifyCrxInstallComplete(); |
| 882 |
| 883 EXPECT_TRUE(updater.crx_install_is_running_); |
| 884 } |
| 885 |
808 EXPECT_EQ(id2, service.extension_id()); | 886 EXPECT_EQ(id2, service.extension_id()); |
809 EXPECT_EQ(url2, service.download_url()); | 887 EXPECT_EQ(url2, service.download_url()); |
810 EXPECT_FALSE(service.install_path().empty()); | 888 EXPECT_FALSE(service.install_path().empty()); |
811 | 889 |
812 // Make sure the correct crx contents were passed for the update call. | 890 // Make sure the correct crx contents were passed for the update call. |
813 EXPECT_EQ(extension_file_path2, service.install_path()); | 891 EXPECT_EQ(extension_file_path2, service.install_path()); |
| 892 |
| 893 if (updates_start_running) { |
| 894 EXPECT_TRUE(updater.crx_install_is_running_); |
| 895 fake_crx2->NotifyCrxInstallComplete(); |
| 896 } |
| 897 EXPECT_FALSE(updater.crx_install_is_running_); |
814 } | 898 } |
815 | 899 |
816 // Test requests to both a Google server and a non-google server. This allows | 900 // Test requests to both a Google server and a non-google server. This allows |
817 // us to test various combinations of installed (ie roll call) and active | 901 // us to test various combinations of installed (ie roll call) and active |
818 // (ie app launch) ping scenarios. The invariant is that each type of ping | 902 // (ie app launch) ping scenarios. The invariant is that each type of ping |
819 // value should be present at most once per day, and can be calculated based | 903 // value should be present at most once per day, and can be calculated based |
820 // on the delta between now and the last ping time (or in the case of active | 904 // on the delta between now and the last ping time (or in the case of active |
821 // pings, that delta plus whether the app has been active). | 905 // pings, that delta plus whether the app has been active). |
822 static void TestGalleryRequests(int rollcall_ping_days, | 906 static void TestGalleryRequests(int rollcall_ping_days, |
823 int active_ping_days, | 907 int active_ping_days, |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1011 | 1095 |
1012 TEST(ExtensionUpdaterTest, TestSingleExtensionDownloadingPending) { | 1096 TEST(ExtensionUpdaterTest, TestSingleExtensionDownloadingPending) { |
1013 ExtensionUpdaterTest::TestSingleExtensionDownloading(true); | 1097 ExtensionUpdaterTest::TestSingleExtensionDownloading(true); |
1014 } | 1098 } |
1015 | 1099 |
1016 // This test is disabled on Mac, see http://crbug.com/26035. | 1100 // This test is disabled on Mac, see http://crbug.com/26035. |
1017 TEST(ExtensionUpdaterTest, TestBlacklistDownloading) { | 1101 TEST(ExtensionUpdaterTest, TestBlacklistDownloading) { |
1018 ExtensionUpdaterTest::TestBlacklistDownloading(); | 1102 ExtensionUpdaterTest::TestBlacklistDownloading(); |
1019 } | 1103 } |
1020 | 1104 |
1021 TEST(ExtensionUpdaterTest, TestMultipleExtensionDownloading) { | 1105 TEST(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesFail) { |
1022 ExtensionUpdaterTest::TestMultipleExtensionDownloading(); | 1106 ExtensionUpdaterTest::TestMultipleExtensionDownloading(false); |
| 1107 } |
| 1108 TEST(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesSucceed) { |
| 1109 ExtensionUpdaterTest::TestMultipleExtensionDownloading(true); |
1023 } | 1110 } |
1024 | 1111 |
1025 TEST(ExtensionUpdaterTest, TestGalleryRequests) { | 1112 TEST(ExtensionUpdaterTest, TestGalleryRequests) { |
1026 // We want to test a variety of combinations of expected ping conditions for | 1113 // We want to test a variety of combinations of expected ping conditions for |
1027 // rollcall and active pings. | 1114 // rollcall and active pings. |
1028 int ping_cases[] = { ManifestFetchData::kNeverPinged, 0, 1, 5 }; | 1115 int ping_cases[] = { ManifestFetchData::kNeverPinged, 0, 1, 5 }; |
1029 | 1116 |
1030 for (size_t i = 0; i < arraysize(ping_cases); i++) { | 1117 for (size_t i = 0; i < arraysize(ping_cases); i++) { |
1031 for (size_t j = 0; j < arraysize(ping_cases); j++) { | 1118 for (size_t j = 0; j < arraysize(ping_cases); j++) { |
1032 for (size_t k = 0; k < 2; k++) { | 1119 for (size_t k = 0; k < 2; k++) { |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1154 | 1241 |
1155 // TODO(asargent) - (http://crbug.com/12780) add tests for: | 1242 // TODO(asargent) - (http://crbug.com/12780) add tests for: |
1156 // -prodversionmin (shouldn't update if browser version too old) | 1243 // -prodversionmin (shouldn't update if browser version too old) |
1157 // -manifests & updates arriving out of order / interleaved | 1244 // -manifests & updates arriving out of order / interleaved |
1158 // -malformed update url (empty, file://, has query, has a # fragment, etc.) | 1245 // -malformed update url (empty, file://, has query, has a # fragment, etc.) |
1159 // -An extension gets uninstalled while updates are in progress (so it doesn't | 1246 // -An extension gets uninstalled while updates are in progress (so it doesn't |
1160 // "come back from the dead") | 1247 // "come back from the dead") |
1161 // -An extension gets manually updated to v3 while we're downloading v2 (ie | 1248 // -An extension gets manually updated to v3 while we're downloading v2 (ie |
1162 // you don't get downgraded accidentally) | 1249 // you don't get downgraded accidentally) |
1163 // -An update manifest mentions multiple updates | 1250 // -An update manifest mentions multiple updates |
OLD | NEW |