| 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 |