Downloader.cpp (3802B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #include "pch.h" 4 #include "TestCommon.h" 5 #include "AppInstallerDownloader.h" 6 #include "AppInstallerSHA256.h" 7 #include "HttpStream/HttpLocalCache.h" 8 9 using namespace AppInstaller; 10 using namespace AppInstaller::Utility; 11 using namespace std::string_literals; 12 13 TEST_CASE("DownloadValidFileAndVerifyHash", "[Downloader]") 14 { 15 TestCommon::TempFile tempFile("downloader_test"s, ".test"s); 16 INFO("Using temporary file named: " << tempFile.GetPath()); 17 18 // Todo: point to files from our repo when the repo goes public 19 ProgressCallback callback; 20 auto result = Download("https://raw.githubusercontent.com/microsoft/msix-packaging/master/LICENSE", tempFile.GetPath(), DownloadType::Manifest, callback); 21 22 REQUIRE(!result.Sha256Hash.empty()); 23 auto resultHash = result.Sha256Hash; 24 25 auto expectedHash = SHA256::ConvertToBytes("d2a45116709136462ee7a1c42f0e75f0efa258fe959b1504dc8ea4573451b759"); 26 REQUIRE(std::equal( 27 expectedHash.begin(), 28 expectedHash.end(), 29 resultHash.begin())); 30 31 uint64_t expectedFileSize = 1119; 32 REQUIRE(result.SizeInBytes == expectedFileSize); 33 REQUIRE(std::filesystem::file_size(tempFile.GetPath()) == expectedFileSize); 34 35 REQUIRE(result.ContentType); 36 REQUIRE(!result.ContentType.value().empty()); 37 38 // Verify motw content 39 std::filesystem::path motwFile(tempFile); 40 motwFile += ":Zone.Identifier:$data"; 41 std::ifstream motwStream(motwFile); 42 std::stringstream motwContent; 43 motwContent << motwStream.rdbuf(); 44 std::string motwContentStr = motwContent.str(); 45 REQUIRE(motwContentStr.find("ZoneId=3") != std::string::npos); 46 } 47 48 TEST_CASE("DownloadValidFileAndCancel", "[Downloader]") 49 { 50 TestCommon::TempFile tempFile("downloader_test"s, ".test"s); 51 INFO("Using temporary file named: " << tempFile.GetPath()); 52 53 ProgressCallback callback; 54 55 DownloadResult waitResult; 56 std::thread waitThread([&] 57 { 58 waitResult = Download("https://aka.ms/win32-x64-user-stable", tempFile.GetPath(), DownloadType::Installer, callback); 59 }); 60 61 callback.Cancel(); 62 63 waitThread.join(); 64 65 REQUIRE(waitResult.Sha256Hash.empty()); 66 } 67 68 TEST_CASE("DownloadInvalidUrl", "[Downloader]") 69 { 70 TestCommon::TempFile tempFile("downloader_test"s, ".test"s); 71 INFO("Using temporary file named: " << tempFile.GetPath()); 72 73 ProgressCallback callback; 74 75 REQUIRE_THROWS(Download("blargle-flargle-fluff", tempFile.GetPath(), DownloadType::Installer, callback)); 76 } 77 78 TEST_CASE("HttpStream_ReadLastFullPage", "[HttpStream]") 79 { 80 Microsoft::WRL::ComPtr<IStream> stream; 81 STATSTG stat = { 0 }; 82 83 for (size_t i = 0; i < 10; ++i) 84 { 85 stream = GetReadOnlyStreamFromURI("https://cdn.winget.microsoft.com/cache/source2.msix"); 86 87 stat = { 0 }; 88 REQUIRE(stream->Stat(&stat, STATFLAG_NONAME) == S_OK); 89 90 if (stat.cbSize.QuadPart > 0) 91 { 92 break; 93 } 94 95 Sleep(500); 96 } 97 98 { 99 INFO("https://cdn.winget.microsoft.com/cache/source2.msix gave back a 0 byte file"); 100 REQUIRE(stream); 101 } 102 103 LARGE_INTEGER seek; 104 seek.QuadPart = (stat.cbSize.QuadPart / HttpStream::HttpLocalCache::PAGE_SIZE) * HttpStream::HttpLocalCache::PAGE_SIZE; 105 REQUIRE(stream->Seek(seek, STREAM_SEEK_SET, nullptr) == S_OK); 106 107 std::unique_ptr<BYTE[]> buffer = std::make_unique<BYTE[]>(HttpStream::HttpLocalCache::PAGE_SIZE); 108 ULONG read = 0; 109 REQUIRE(stream->Read(buffer.get(), static_cast<ULONG>(HttpStream::HttpLocalCache::PAGE_SIZE), &read) >= S_OK); 110 REQUIRE(read == (stat.cbSize.QuadPart % HttpStream::HttpLocalCache::PAGE_SIZE)); 111 }