winget-cli

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

main.cpp (4816B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #include "pch.h"
      4 #include <AppInstallerLogging.h>
      5 #include <AppInstallerFileLogger.h>
      6 #include <Public/AppInstallerTelemetry.h>
      7 #include <Telemetry/TraceLogging.h>
      8 #include "TestCommon.h"
      9 #include "TestSettings.h"
     10 
     11 using namespace winrt;
     12 using namespace winrt::Windows::Foundation;
     13 using namespace std::string_literals;
     14 using namespace AppInstaller;
     15 
     16 
     17 // Logs the AppInstaller log target to break up individual tests
     18 struct LoggingBreakListener : public Catch::EventListenerBase
     19 {
     20     using EventListenerBase::EventListenerBase;
     21 
     22     void testCaseStarting(const Catch::TestCaseInfo& info) override
     23     {
     24         Catch::EventListenerBase::testCaseStarting(info);
     25         AICLI_LOG(Test, Info, << "========== Test Case Begins :: " << info.name << " ==========");
     26         TestCommon::TempFile::SetTestFailed(false);
     27     }
     28 
     29     void testCaseEnded(const Catch::TestCaseStats& testCaseStats) override
     30     {
     31         AICLI_LOG(Test, Info, << "========== Test Case Ends ==========");
     32         if (!testCaseStats.totals.delta(lastTotals).testCases.allOk())
     33         {
     34             TestCommon::TempFile::SetTestFailed(true);
     35         }
     36         lastTotals = testCaseStats.totals;
     37         Catch::EventListenerBase::testCaseEnded(testCaseStats);
     38     }
     39 
     40     Catch::Totals lastTotals{};
     41 };
     42 CATCH_REGISTER_LISTENER(LoggingBreakListener);
     43 
     44 // Map CATCH exceptions so that WIL doesn't fail fast the tests
     45 HRESULT __stdcall CatchResultFromCaughtException() WI_PFN_NOEXCEPT
     46 {
     47     try
     48     {
     49         throw;
     50     }
     51     catch (const Catch::TestFailureException&)
     52     {
     53         // REC_E_TEST_FAILURE :: Test failure.
     54         // Not sure what could generate this, but it is unlikely that we use it.
     55         // Since the message is aligned with the issue it should help diagnosis.
     56         return 0x8b051032;
     57     }
     58     catch (...)
     59     {
     60         // Means we couldn't map the exception
     61         return S_OK;
     62     }
     63 }
     64 
     65 int main(int argc, char** argv)
     66 {
     67     init_apartment();
     68 
     69     bool hasSetTestDataBasePath = false;
     70     bool waitBeforeReturn = false;
     71     bool keepSQLLogging = false;
     72 
     73     std::vector<char*> args;
     74     for (int i = 0; i < argc; ++i)
     75     {
     76         if ("-ktf"s == argv[i])
     77         {
     78             TestCommon::TempFile::SetDestructorBehavior(TestCommon::TempFileDestructionBehavior::Keep);
     79         }
     80         else if ("-seof"s == argv[i])
     81         {
     82             TestCommon::TempFile::SetDestructorBehavior(TestCommon::TempFileDestructionBehavior::ShellExecuteOnFailure);
     83         }
     84         else if ("-log"s == argv[i])
     85         {
     86             Logging::FileLogger::Add();
     87         }
     88         else if ("-logto"s == argv[i])
     89         {
     90             ++i;
     91             Logging::FileLogger::Add(std::filesystem::path{ argv[i] });
     92         }
     93         else if ("-tdd"s == argv[i])
     94         {
     95             ++i;
     96             if (i < argc)
     97             {
     98                 TestCommon::TestDataFile::SetTestDataBasePath(argv[i]);
     99                 hasSetTestDataBasePath = true;
    100             }
    101         }
    102         else if ("-wait"s == argv[i])
    103         {
    104             waitBeforeReturn = true;
    105         }
    106         else if ("-logsql"s == argv[i])
    107         {
    108             keepSQLLogging = true;
    109         }
    110         else
    111         {
    112             args.push_back(argv[i]);
    113         }
    114     }
    115 
    116     // If not set, use the current executables path
    117     if (!hasSetTestDataBasePath)
    118     {
    119         wchar_t fullFileName[1024];
    120         DWORD chars = ARRAYSIZE(fullFileName);
    121         if (QueryFullProcessImageNameW(GetCurrentProcess(), 0, fullFileName, &chars))
    122         {
    123             std::filesystem::path filepath{ fullFileName };
    124             filepath.remove_filename();
    125             TestCommon::TestDataFile::SetTestDataBasePath(filepath);
    126         }
    127     }
    128 
    129     // Enable logging, to force log string building to run.
    130     // Disable SQL by default, as it generates 10s of MBs of log file and
    131     // increases the full test run time by 60% or more.
    132     // By not creating a log target, it will all be thrown away.
    133     Logging::Log().SetEnabledChannels(Logging::Channel::All);
    134     if (!keepSQLLogging)
    135     {
    136         Logging::Log().DisableChannel(Logging::Channel::SQL);
    137     }
    138     Logging::Log().SetLevel(Logging::Level::Verbose);
    139     Logging::EnableWilFailureTelemetry();
    140 
    141     wil::SetResultFromCaughtExceptionCallback(CatchResultFromCaughtException);
    142 
    143     // Forcibly enable event writing to catch bugs in that code
    144     g_IsTelemetryProviderEnabled = true;
    145 
    146     TestCommon::SetTestPathOverrides();
    147 
    148     // Remove any existing settings files in the new tests path
    149     TestCommon::UserSettingsFileGuard settingsGuard;
    150 
    151     int result = Catch::Session().run(static_cast<int>(args.size()), args.data());
    152 
    153     if (waitBeforeReturn)
    154     {
    155         // Wait for some input before returning
    156         std::cin.get();
    157     }
    158 
    159     return result;
    160 }