winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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 }