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 <list> | 5 #include <list> |
6 #include <map> | 6 #include <map> |
7 #include <set> | 7 #include <set> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
780 downloader.DetermineUpdates(fetch_data, updates, &updateable); | 780 downloader.DetermineUpdates(fetch_data, updates, &updateable); |
781 // All the apps should be updateable. | 781 // All the apps should be updateable. |
782 EXPECT_EQ(3u, updateable.size()); | 782 EXPECT_EQ(3u, updateable.size()); |
783 for (std::vector<int>::size_type i = 0; i < updateable.size(); ++i) { | 783 for (std::vector<int>::size_type i = 0; i < updateable.size(); ++i) { |
784 EXPECT_EQ(static_cast<int>(i), updateable[i]); | 784 EXPECT_EQ(static_cast<int>(i), updateable[i]); |
785 } | 785 } |
786 } | 786 } |
787 | 787 |
788 void TestMultipleManifestDownloading() { | 788 void TestMultipleManifestDownloading() { |
789 net::TestURLFetcherFactory factory; | 789 net::TestURLFetcherFactory factory; |
| 790 factory.set_remove_fetcher_on_delete(true); |
790 net::TestURLFetcher* fetcher = NULL; | 791 net::TestURLFetcher* fetcher = NULL; |
791 NotificationsObserver observer; | |
792 MockService service(prefs_.get()); | 792 MockService service(prefs_.get()); |
793 MockExtensionDownloaderDelegate delegate; | 793 MockExtensionDownloaderDelegate delegate; |
794 ExtensionDownloader downloader(&delegate, service.request_context()); | 794 ExtensionDownloader downloader(&delegate, service.request_context()); |
795 downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy); | 795 downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy); |
796 | 796 |
797 GURL kUpdateUrl("http://localhost/manifest1"); | 797 GURL kUpdateUrl("http://localhost/manifest1"); |
798 | 798 |
799 scoped_ptr<ManifestFetchData> fetch1(new ManifestFetchData(kUpdateUrl, 0)); | 799 scoped_ptr<ManifestFetchData> fetch1(new ManifestFetchData(kUpdateUrl, 0)); |
800 scoped_ptr<ManifestFetchData> fetch2(new ManifestFetchData(kUpdateUrl, 0)); | 800 scoped_ptr<ManifestFetchData> fetch2(new ManifestFetchData(kUpdateUrl, 0)); |
801 scoped_ptr<ManifestFetchData> fetch3(new ManifestFetchData(kUpdateUrl, 0)); | 801 scoped_ptr<ManifestFetchData> fetch3(new ManifestFetchData(kUpdateUrl, 0)); |
802 scoped_ptr<ManifestFetchData> fetch4(new ManifestFetchData(kUpdateUrl, 0)); | 802 scoped_ptr<ManifestFetchData> fetch4(new ManifestFetchData(kUpdateUrl, 0)); |
803 ManifestFetchData::PingData zeroDays(0, 0, true); | 803 ManifestFetchData::PingData zeroDays(0, 0, true); |
804 fetch1->AddExtension( | 804 fetch1->AddExtension( |
805 "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string()); | 805 "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string()); |
806 fetch2->AddExtension( | 806 fetch2->AddExtension( |
807 "2222", "2.0", &zeroDays, kEmptyUpdateUrlData, std::string()); | 807 "2222", "2.0", &zeroDays, kEmptyUpdateUrlData, std::string()); |
808 fetch3->AddExtension( | 808 fetch3->AddExtension( |
809 "3333", "3.0", &zeroDays, kEmptyUpdateUrlData, std::string()); | 809 "3333", "3.0", &zeroDays, kEmptyUpdateUrlData, std::string()); |
810 fetch4->AddExtension( | 810 fetch4->AddExtension( |
811 "4444", "4.0", &zeroDays, kEmptyUpdateUrlData, std::string()); | 811 "4444", "4.0", &zeroDays, kEmptyUpdateUrlData, std::string()); |
812 | 812 |
813 // This will start the first fetcher and queue the others. The next in queue | 813 // This will start the first fetcher and queue the others. The next in queue |
814 // is started as each fetcher receives its response. | 814 // is started as each fetcher receives its response. Note that the fetchers |
| 815 // don't necessarily run in the order that they are started from here. |
| 816 GURL fetch1_url = fetch1->full_url(); |
| 817 GURL fetch2_url = fetch2->full_url(); |
| 818 GURL fetch3_url = fetch3->full_url(); |
| 819 GURL fetch4_url = fetch4->full_url(); |
815 downloader.StartUpdateCheck(fetch1.Pass()); | 820 downloader.StartUpdateCheck(fetch1.Pass()); |
816 downloader.StartUpdateCheck(fetch2.Pass()); | 821 downloader.StartUpdateCheck(fetch2.Pass()); |
817 downloader.StartUpdateCheck(fetch3.Pass()); | 822 downloader.StartUpdateCheck(fetch3.Pass()); |
818 downloader.StartUpdateCheck(fetch4.Pass()); | 823 downloader.StartUpdateCheck(fetch4.Pass()); |
819 RunUntilIdle(); | 824 RunUntilIdle(); |
820 | 825 |
821 // The first fetch will fail. | 826 for (int i = 0; i < 4; ++i) { |
| 827 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId); |
| 828 ASSERT_TRUE(fetcher); |
| 829 ASSERT_TRUE(fetcher->delegate()); |
| 830 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags); |
| 831 EXPECT_FALSE(fetcher->GetOriginalURL().is_empty()); |
| 832 |
| 833 if (fetcher->GetOriginalURL() == fetch1_url) { |
| 834 // The first fetch will fail. |
| 835 EXPECT_CALL(delegate, OnExtensionDownloadFailed( |
| 836 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _)); |
| 837 fetcher->set_url(kUpdateUrl); |
| 838 fetcher->set_status(net::URLRequestStatus()); |
| 839 fetcher->set_response_code(400); |
| 840 fetcher->delegate()->OnURLFetchComplete(fetcher); |
| 841 RunUntilIdle(); |
| 842 Mock::VerifyAndClearExpectations(&delegate); |
| 843 fetch1_url = GURL(); |
| 844 } else if (fetcher->GetOriginalURL() == fetch2_url) { |
| 845 // The second fetch gets invalid data. |
| 846 const std::string kInvalidXml = "invalid xml"; |
| 847 EXPECT_CALL(delegate, OnExtensionDownloadFailed( |
| 848 "2222", ExtensionDownloaderDelegate::MANIFEST_INVALID, _, _)) |
| 849 .WillOnce(InvokeWithoutArgs( |
| 850 &delegate, |
| 851 &MockExtensionDownloaderDelegate::Quit)); |
| 852 fetcher->set_url(kUpdateUrl); |
| 853 fetcher->set_status(net::URLRequestStatus()); |
| 854 fetcher->set_response_code(200); |
| 855 fetcher->SetResponseString(kInvalidXml); |
| 856 fetcher->delegate()->OnURLFetchComplete(fetcher); |
| 857 delegate.Wait(); |
| 858 Mock::VerifyAndClearExpectations(&delegate); |
| 859 fetch2_url = GURL(); |
| 860 } else if (fetcher->GetOriginalURL() == fetch3_url) { |
| 861 // The third fetcher doesn't have an update available. |
| 862 const std::string kNoUpdate = |
| 863 "<?xml version='1.0' encoding='UTF-8'?>" |
| 864 "<gupdate xmlns='http://www.google.com/update2/response'" |
| 865 " protocol='2.0'>" |
| 866 " <app appid='3333'>" |
| 867 " <updatecheck codebase='http://example.com/extension_3.0.0.0.crx'" |
| 868 " version='3.0.0.0' prodversionmin='3.0.0.0' />" |
| 869 " </app>" |
| 870 "</gupdate>"; |
| 871 EXPECT_CALL(delegate, IsExtensionPending("3333")) |
| 872 .WillOnce(Return(false)); |
| 873 EXPECT_CALL(delegate, GetExtensionExistingVersion("3333", _)) |
| 874 .WillOnce(DoAll(SetArgPointee<1>("3.0.0.0"), |
| 875 Return(true))); |
| 876 EXPECT_CALL(delegate, OnExtensionDownloadFailed( |
| 877 "3333", ExtensionDownloaderDelegate::NO_UPDATE_AVAILABLE, _, _)) |
| 878 .WillOnce(InvokeWithoutArgs( |
| 879 &delegate, |
| 880 &MockExtensionDownloaderDelegate::Quit)); |
| 881 fetcher->set_url(kUpdateUrl); |
| 882 fetcher->set_status(net::URLRequestStatus()); |
| 883 fetcher->set_response_code(200); |
| 884 fetcher->SetResponseString(kNoUpdate); |
| 885 fetcher->delegate()->OnURLFetchComplete(fetcher); |
| 886 delegate.Wait(); |
| 887 Mock::VerifyAndClearExpectations(&delegate); |
| 888 fetch3_url = GURL(); |
| 889 } else if (fetcher->GetOriginalURL() == fetch4_url) { |
| 890 // The last fetcher has an update. |
| 891 NotificationsObserver observer; |
| 892 const std::string kUpdateAvailable = |
| 893 "<?xml version='1.0' encoding='UTF-8'?>" |
| 894 "<gupdate xmlns='http://www.google.com/update2/response'" |
| 895 " protocol='2.0'>" |
| 896 " <app appid='4444'>" |
| 897 " <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'" |
| 898 " version='4.0.42.0' prodversionmin='4.0.42.0' />" |
| 899 " </app>" |
| 900 "</gupdate>"; |
| 901 EXPECT_CALL(delegate, IsExtensionPending("4444")) |
| 902 .WillOnce(Return(false)); |
| 903 EXPECT_CALL(delegate, GetExtensionExistingVersion("4444", _)) |
| 904 .WillOnce(DoAll(SetArgPointee<1>("4.0.0.0"), |
| 905 Return(true))); |
| 906 fetcher->set_url(kUpdateUrl); |
| 907 fetcher->set_status(net::URLRequestStatus()); |
| 908 fetcher->set_response_code(200); |
| 909 fetcher->SetResponseString(kUpdateAvailable); |
| 910 fetcher->delegate()->OnURLFetchComplete(fetcher); |
| 911 observer.Wait(); |
| 912 Mock::VerifyAndClearExpectations(&delegate); |
| 913 |
| 914 // Verify that the downloader decided to update this extension. |
| 915 EXPECT_EQ(1u, observer.UpdatedCount()); |
| 916 EXPECT_TRUE(observer.Updated("4444")); |
| 917 fetch4_url = GURL(); |
| 918 } else { |
| 919 ADD_FAILURE() << "Unexpected fetch: " << fetcher->GetOriginalURL(); |
| 920 } |
| 921 } |
| 922 |
822 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId); | 923 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId); |
823 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL); | 924 if (fetcher) |
824 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags); | 925 ADD_FAILURE() << "Unexpected fetch: " << fetcher->GetOriginalURL(); |
825 EXPECT_CALL(delegate, OnExtensionDownloadFailed( | |
826 "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _)); | |
827 fetcher->set_url(kUpdateUrl); | |
828 fetcher->set_status(net::URLRequestStatus()); | |
829 fetcher->set_response_code(400); | |
830 fetcher->delegate()->OnURLFetchComplete(fetcher); | |
831 RunUntilIdle(); | |
832 Mock::VerifyAndClearExpectations(&delegate); | |
833 | |
834 // The second fetch gets invalid data. | |
835 const std::string kInvalidXml = "invalid xml"; | |
836 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId); | |
837 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL); | |
838 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags); | |
839 EXPECT_CALL(delegate, OnExtensionDownloadFailed( | |
840 "2222", ExtensionDownloaderDelegate::MANIFEST_INVALID, _, _)) | |
841 .WillOnce(InvokeWithoutArgs(&delegate, | |
842 &MockExtensionDownloaderDelegate::Quit)); | |
843 fetcher->set_url(kUpdateUrl); | |
844 fetcher->set_status(net::URLRequestStatus()); | |
845 fetcher->set_response_code(200); | |
846 fetcher->SetResponseString(kInvalidXml); | |
847 fetcher->delegate()->OnURLFetchComplete(fetcher); | |
848 delegate.Wait(); | |
849 Mock::VerifyAndClearExpectations(&delegate); | |
850 | |
851 // The third fetcher doesn't have an update available. | |
852 const std::string kNoUpdate = | |
853 "<?xml version='1.0' encoding='UTF-8'?>" | |
854 "<gupdate xmlns='http://www.google.com/update2/response'" | |
855 " protocol='2.0'>" | |
856 " <app appid='3333'>" | |
857 " <updatecheck codebase='http://example.com/extension_3.0.0.0.crx'" | |
858 " version='3.0.0.0' prodversionmin='3.0.0.0' />" | |
859 " </app>" | |
860 "</gupdate>"; | |
861 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId); | |
862 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL); | |
863 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags); | |
864 EXPECT_CALL(delegate, IsExtensionPending("3333")).WillOnce(Return(false)); | |
865 EXPECT_CALL(delegate, GetExtensionExistingVersion("3333", _)) | |
866 .WillOnce(DoAll(SetArgPointee<1>("3.0.0.0"), | |
867 Return(true))); | |
868 EXPECT_CALL(delegate, OnExtensionDownloadFailed( | |
869 "3333", ExtensionDownloaderDelegate::NO_UPDATE_AVAILABLE, _, _)) | |
870 .WillOnce(InvokeWithoutArgs(&delegate, | |
871 &MockExtensionDownloaderDelegate::Quit)); | |
872 fetcher->set_url(kUpdateUrl); | |
873 fetcher->set_status(net::URLRequestStatus()); | |
874 fetcher->set_response_code(200); | |
875 fetcher->SetResponseString(kNoUpdate); | |
876 fetcher->delegate()->OnURLFetchComplete(fetcher); | |
877 delegate.Wait(); | |
878 Mock::VerifyAndClearExpectations(&delegate); | |
879 | |
880 // The last fetcher has an update. | |
881 const std::string kUpdateAvailable = | |
882 "<?xml version='1.0' encoding='UTF-8'?>" | |
883 "<gupdate xmlns='http://www.google.com/update2/response'" | |
884 " protocol='2.0'>" | |
885 " <app appid='4444'>" | |
886 " <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'" | |
887 " version='4.0.42.0' prodversionmin='4.0.42.0' />" | |
888 " </app>" | |
889 "</gupdate>"; | |
890 fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId); | |
891 EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL); | |
892 EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags); | |
893 EXPECT_CALL(delegate, IsExtensionPending("4444")).WillOnce(Return(false)); | |
894 EXPECT_CALL(delegate, GetExtensionExistingVersion("4444", _)) | |
895 .WillOnce(DoAll(SetArgPointee<1>("4.0.0.0"), | |
896 Return(true))); | |
897 fetcher->set_url(kUpdateUrl); | |
898 fetcher->set_status(net::URLRequestStatus()); | |
899 fetcher->set_response_code(200); | |
900 fetcher->SetResponseString(kUpdateAvailable); | |
901 fetcher->delegate()->OnURLFetchComplete(fetcher); | |
902 observer.Wait(); | |
903 Mock::VerifyAndClearExpectations(&delegate); | |
904 | |
905 // Verify that the downloader decided to update this extension. | |
906 EXPECT_EQ(1u, observer.UpdatedCount()); | |
907 EXPECT_TRUE(observer.Updated("4444")); | |
908 } | 926 } |
909 | 927 |
910 void TestManifestRetryDownloading() { | 928 void TestManifestRetryDownloading() { |
911 net::TestURLFetcherFactory factory; | 929 net::TestURLFetcherFactory factory; |
912 net::TestURLFetcher* fetcher = NULL; | 930 net::TestURLFetcher* fetcher = NULL; |
913 NotificationsObserver observer; | 931 NotificationsObserver observer; |
914 MockService service(prefs_.get()); | 932 MockService service(prefs_.get()); |
915 MockExtensionDownloaderDelegate delegate; | 933 MockExtensionDownloaderDelegate delegate; |
916 ExtensionDownloader downloader(&delegate, service.request_context()); | 934 ExtensionDownloader downloader(&delegate, service.request_context()); |
917 downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy); | 935 downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy); |
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1538 } | 1556 } |
1539 | 1557 |
1540 TEST_F(ExtensionUpdaterTest, TestDetermineUpdates) { | 1558 TEST_F(ExtensionUpdaterTest, TestDetermineUpdates) { |
1541 TestDetermineUpdates(); | 1559 TestDetermineUpdates(); |
1542 } | 1560 } |
1543 | 1561 |
1544 TEST_F(ExtensionUpdaterTest, TestDetermineUpdatesPending) { | 1562 TEST_F(ExtensionUpdaterTest, TestDetermineUpdatesPending) { |
1545 TestDetermineUpdatesPending(); | 1563 TestDetermineUpdatesPending(); |
1546 } | 1564 } |
1547 | 1565 |
1548 #if defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) | 1566 TEST_F(ExtensionUpdaterTest, TestMultipleManifestDownloading) { |
1549 // This test fails under ThreadSanitizer and MemorySanitizer, which build with | |
1550 // libc++ instead of libstdc++. | |
1551 #define MAYBE_TestMultipleManifestDownloading \ | |
1552 DISABLED_TestMultipleManifestDownloading | |
1553 #else | |
1554 #define MAYBE_TestMultipleManifestDownloading TestMultipleManifestDownloading | |
1555 #endif | |
1556 TEST_F(ExtensionUpdaterTest, MAYBE_TestMultipleManifestDownloading) { | |
1557 TestMultipleManifestDownloading(); | 1567 TestMultipleManifestDownloading(); |
1558 } | 1568 } |
1559 | 1569 |
1560 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloading) { | 1570 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloading) { |
1561 TestSingleExtensionDownloading(false, false, false); | 1571 TestSingleExtensionDownloading(false, false, false); |
1562 } | 1572 } |
1563 | 1573 |
1564 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPending) { | 1574 TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPending) { |
1565 TestSingleExtensionDownloading(true, false, false); | 1575 TestSingleExtensionDownloading(true, false, false); |
1566 } | 1576 } |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1782 // -prodversionmin (shouldn't update if browser version too old) | 1792 // -prodversionmin (shouldn't update if browser version too old) |
1783 // -manifests & updates arriving out of order / interleaved | 1793 // -manifests & updates arriving out of order / interleaved |
1784 // -malformed update url (empty, file://, has query, has a # fragment, etc.) | 1794 // -malformed update url (empty, file://, has query, has a # fragment, etc.) |
1785 // -An extension gets uninstalled while updates are in progress (so it doesn't | 1795 // -An extension gets uninstalled while updates are in progress (so it doesn't |
1786 // "come back from the dead") | 1796 // "come back from the dead") |
1787 // -An extension gets manually updated to v3 while we're downloading v2 (ie | 1797 // -An extension gets manually updated to v3 while we're downloading v2 (ie |
1788 // you don't get downgraded accidentally) | 1798 // you don't get downgraded accidentally) |
1789 // -An update manifest mentions multiple updates | 1799 // -An update manifest mentions multiple updates |
1790 | 1800 |
1791 } // namespace extensions | 1801 } // namespace extensions |
OLD | NEW |