Skip to content

Commit

Permalink
Create WinGetUtil functionality for running installed package correla…
Browse files Browse the repository at this point in the history
…tion (#2221)

The goal of this change is to expose functionality to run the installed package correlation and gather the results.  This will be used to validate and enhance manifests and allows us to use the same correlation code throughout the system.

The biggest changes to existing code are:
1. Moving the JSON utility methods out of Repository and into Common
2. Moving the correlation code to be object oriented, enabling easier reuse (and allowing for more control in the future)

Beyond those changes, the majority of the work is in creating the JSON (de)serialization and handling updating the metadata that has been collected.

More work is still needed to:
1. Collect more information for diagnostic purposes, like the top results for diagnostics when there is no confident match.
2. Leveraging the previous metadata results to improve correlation.
3. Enable more control over weighting the correlation heuristics, enabling a difference between running on an end user system and in a "clean room" of validation.
  • Loading branch information
JohnMcPMS authored Jun 24, 2022
1 parent 331d0ee commit 9f8ceea
Show file tree
Hide file tree
Showing 56 changed files with 2,969 additions and 754 deletions.
3 changes: 2 additions & 1 deletion .github/actions/spelling/allow.txt
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ denelon
depersist
deque
deserialize
Deserialize
deserializer
deserializes
deserializing
dest
devblogs
Expand Down Expand Up @@ -301,6 +301,7 @@ MContext
mday
memset
metadata
metadatas
microsoft
mimetype
Minimatch
Expand Down
3 changes: 3 additions & 0 deletions .github/actions/spelling/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ ashpatil
Ashwini
asm
ASwitch
ASYNCRTIMP
Atest
ATL
AType
Expand Down Expand Up @@ -99,6 +100,7 @@ deleteifnotneeded
desktopappinstaller
dirs
diskfull
dllimport
dnld
Dobbeleer
dsc
Expand All @@ -107,6 +109,7 @@ dvinns
dw
ecfr
ecfrbrowse
efgh
endian
enr
enums
Expand Down
6 changes: 3 additions & 3 deletions src/AppInstallerCLICore/ExecutionContextData.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ namespace AppInstaller::CLI::Execution
PackagesToInstall,
// On import: Sources for the imported packages
Sources,
ARPSnapshot,
ARPCorrelationData,
CorrelatedAppsAndFeaturesEntries,
Dependencies,
DependencySource,
Expand Down Expand Up @@ -188,9 +188,9 @@ namespace AppInstaller::CLI::Execution
};

template <>
struct DataMapping<Data::ARPSnapshot>
struct DataMapping<Data::ARPCorrelationData>
{
using value_t = std::vector<Repository::Correlation::ARPEntrySnapshot>;
using value_t = Repository::Correlation::ARPCorrelationData;
};

template <>
Expand Down
1 change: 1 addition & 0 deletions src/AppInstallerCLICore/ExecutionReporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ namespace AppInstaller::CLI::Execution
std::string response;
if (!std::getline(m_in, response))
{
m_in.get();
THROW_HR(APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR);
}

Expand Down
2 changes: 1 addition & 1 deletion src/AppInstallerCLICore/PackageCollection.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "winget/RepositorySource.h"
#include <winget/Manifest.h>

#include <json.h>
#include <json/json.h>

#include <vector>

Expand Down
44 changes: 7 additions & 37 deletions src/AppInstallerCLICore/Workflows/InstallFlow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -615,55 +615,25 @@ namespace AppInstaller::CLI::Workflow

if (installer && MightWriteToARP(installer->InstallerType))
{
Source arpSource = context.Reporter.ExecuteWithProgress(
[](IProgressCallback& progress)
{
Repository::Source result = Repository::Source(PredefinedSource::ARP);
result.Open(progress);
return result;
}, true);

std::vector<std::tuple<Utility::LocIndString, Utility::LocIndString, Utility::LocIndString>> entries;

for (const auto& entry : arpSource.Search({}).Matches)
{
auto installed = entry.Package->GetInstalledVersion();
if (installed)
{
entries.emplace_back(std::make_tuple(
entry.Package->GetProperty(PackageProperty::Id),
installed->GetProperty(PackageVersionProperty::Version),
installed->GetProperty(PackageVersionProperty::Channel)));
}
}

std::sort(entries.begin(), entries.end());

context.Add<Execution::Data::ARPSnapshot>(std::move(entries));
Repository::Correlation::ARPCorrelationData data;
data.CapturePreInstallSnapshot();
context.Add<Execution::Data::ARPCorrelationData>(std::move(data));
}
}
CATCH_LOG()

void ReportARPChanges(Execution::Context& context) try
{
if (!context.Contains(Execution::Data::ARPSnapshot))
if (!context.Contains(Execution::Data::ARPCorrelationData))
{
return;
}

const auto& manifest = context.Get<Execution::Data::Manifest>();
const auto& arpSnapshot = context.Get<Execution::Data::ARPSnapshot>();

// Open the ARP source again to get the (potentially) changed ARP entries
Source arpSource = context.Reporter.ExecuteWithProgress(
[](IProgressCallback& progress)
{
Repository::Source result = Repository::Source(PredefinedSource::ARP);
result.Open(progress);
return result;
}, true);
auto& arpCorrelationData = context.Get<Execution::Data::ARPCorrelationData>();

auto correlationResult = Correlation::FindARPEntryForNewlyInstalledPackage(manifest, arpSnapshot, arpSource);
arpCorrelationData.CapturePostInstallSnapshot();
auto correlationResult = arpCorrelationData.CorrelateForNewlyInstalled(manifest);

// Store the ARP entry found to match the package to record it in the tracking catalog later
if (correlationResult.Package)
Expand Down
30 changes: 15 additions & 15 deletions src/AppInstallerCLITests/ARPChanges.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ TEST_CASE("ARPChanges_MSIX_Ignored", "[ARPChanges][workflow]")

context << SnapshotARPEntries;

REQUIRE(!context.Contains(Data::ARPSnapshot));
REQUIRE(!context.Contains(Data::ARPCorrelationData));

context << ReportARPChanges;

Expand All @@ -245,9 +245,9 @@ TEST_CASE("ARPChanges_CheckSnapshot", "[ARPChanges][workflow]")

context << SnapshotARPEntries;

REQUIRE(context.Contains(Data::ARPSnapshot));
REQUIRE(context.Contains(Data::ARPCorrelationData));

auto snapshot = context.Get<Data::ARPSnapshot>();
auto snapshot = context.Get<Data::ARPCorrelationData>().GetPreInstallSnapshot();

REQUIRE(context.EverythingResult.Matches.size() == snapshot.size());

Expand Down Expand Up @@ -279,7 +279,7 @@ TEST_CASE("ARPChanges_NoChange_NoMatch", "[ARPChanges][workflow]")
TestContext context;

context << SnapshotARPEntries;
REQUIRE(context.Contains(Data::ARPSnapshot));
REQUIRE(context.Contains(Data::ARPCorrelationData));

context << ReportARPChanges;
context.ExpectEvent(0, 0, 0);
Expand All @@ -291,7 +291,7 @@ TEST_CASE("ARPChanges_NoChange_SingleMatch", "[ARPChanges][workflow]")
TestContext context;

context << SnapshotARPEntries;
REQUIRE(context.Contains(Data::ARPSnapshot));
REQUIRE(context.Contains(Data::ARPCorrelationData));

context.AddMatchResult("MatchId1", "MatchName1", "MatchPublisher1", "MatchVersion1");

Expand All @@ -305,7 +305,7 @@ TEST_CASE("ARPChanges_NoChange_MultiMatch", "[ARPChanges][workflow]")
TestContext context;

context << SnapshotARPEntries;
REQUIRE(context.Contains(Data::ARPSnapshot));
REQUIRE(context.Contains(Data::ARPCorrelationData));

context.AddMatchResult("MatchId1", "MatchName1", "MatchPublisher1", "MatchVersion1");
context.AddMatchResult("MatchId2", "MatchName2", "MatchPublisher2", "MatchVersion2");
Expand All @@ -320,7 +320,7 @@ TEST_CASE("ARPChanges_SingleChange_NoMatch", "[ARPChanges][workflow]")
TestContext context;

context << SnapshotARPEntries;
REQUIRE(context.Contains(Data::ARPSnapshot));
REQUIRE(context.Contains(Data::ARPCorrelationData));

context.AddEverythingResult("EverythingId1", "EverythingName1", "EverythingPublisher1", "EverythingVersion1");

Expand All @@ -334,7 +334,7 @@ TEST_CASE("ARPChanges_SingleChange_SingleMatch", "[ARPChanges][workflow]")
TestContext context;

context << SnapshotARPEntries;
REQUIRE(context.Contains(Data::ARPSnapshot));
REQUIRE(context.Contains(Data::ARPCorrelationData));

context.AddEverythingResult("EverythingId1", "EverythingName1", "EverythingPublisher1", "EverythingVersion1");
context.AddMatchResult("MatchId1", "MatchName1", "MatchPublisher1", "MatchVersion1");
Expand All @@ -349,7 +349,7 @@ TEST_CASE("ARPChanges_SingleChange_MultiMatch", "[ARPChanges][workflow]")
TestContext context;

context << SnapshotARPEntries;
REQUIRE(context.Contains(Data::ARPSnapshot));
REQUIRE(context.Contains(Data::ARPCorrelationData));

context.AddEverythingResult("EverythingId1", "EverythingName1", "EverythingPublisher1", "EverythingVersion1");
context.AddMatchResult("MatchId1", "MatchName1", "MatchPublisher1", "MatchVersion1");
Expand All @@ -365,7 +365,7 @@ TEST_CASE("ARPChanges_MultiChange_NoMatch", "[ARPChanges][workflow]")
TestContext context;

context << SnapshotARPEntries;
REQUIRE(context.Contains(Data::ARPSnapshot));
REQUIRE(context.Contains(Data::ARPCorrelationData));

context.AddEverythingResult("EverythingId1", "EverythingName1", "EverythingPublisher1", "EverythingVersion1");
context.AddEverythingResult("EverythingId2", "EverythingName2", "EverythingPublisher2", "EverythingVersion2");
Expand All @@ -380,7 +380,7 @@ TEST_CASE("ARPChanges_MultiChange_SingleMatch_NoOverlap", "[ARPChanges][workflow
TestContext context;

context << SnapshotARPEntries;
REQUIRE(context.Contains(Data::ARPSnapshot));
REQUIRE(context.Contains(Data::ARPCorrelationData));

context.AddEverythingResult("EverythingId1", "EverythingName1", "EverythingPublisher1", "EverythingVersion1");
context.AddEverythingResult("EverythingId2", "EverythingName2", "EverythingPublisher2", "EverythingVersion2");
Expand All @@ -396,7 +396,7 @@ TEST_CASE("ARPChanges_MultiChange_SingleMatch_Overlap", "[ARPChanges][workflow]"
TestContext context;

context << SnapshotARPEntries;
REQUIRE(context.Contains(Data::ARPSnapshot));
REQUIRE(context.Contains(Data::ARPCorrelationData));

context.AddEverythingResult("EverythingId1", "EverythingName1", "EverythingPublisher1", "EverythingVersion1");
context.AddEverythingResult("EverythingId2", "EverythingName2", "EverythingPublisher2", "EverythingVersion2");
Expand All @@ -412,7 +412,7 @@ TEST_CASE("ARPChanges_MultiChange_MultiMatch_NoOverlap", "[ARPChanges][workflow]
TestContext context;

context << SnapshotARPEntries;
REQUIRE(context.Contains(Data::ARPSnapshot));
REQUIRE(context.Contains(Data::ARPCorrelationData));

context.AddEverythingResult("EverythingId1", "EverythingName1", "EverythingPublisher1", "EverythingVersion1");
context.AddEverythingResult("EverythingId2", "EverythingName2", "EverythingPublisher2", "EverythingVersion2");
Expand All @@ -429,7 +429,7 @@ TEST_CASE("ARPChanges_MultiChange_MultiMatch_SingleOverlap", "[ARPChanges][workf
TestContext context;

context << SnapshotARPEntries;
REQUIRE(context.Contains(Data::ARPSnapshot));
REQUIRE(context.Contains(Data::ARPCorrelationData));

context.AddEverythingResult("EverythingId1", "EverythingName1", "EverythingPublisher1", "EverythingVersion1");
context.AddEverythingResult("EverythingId2", "EverythingName2", "EverythingPublisher2", "EverythingVersion2");
Expand All @@ -446,7 +446,7 @@ TEST_CASE("ARPChanges_MultiChange_MultiMatch_MultiOverlap", "[ARPChanges][workfl
TestContext context;

context << SnapshotARPEntries;
REQUIRE(context.Contains(Data::ARPSnapshot));
REQUIRE(context.Contains(Data::ARPCorrelationData));

context.AddEverythingResult("EverythingId1", "EverythingName1", "EverythingPublisher1", "EverythingVersion1");
context.MatchResult.Matches.emplace_back(context.EverythingResult.Matches.back());
Expand Down
9 changes: 5 additions & 4 deletions src/AppInstallerCLITests/AppInstallerCLITests.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_NO_ASYNCRTIMP;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</TreatWarningAsError>
</ClCompile>
<Link>
Expand All @@ -129,7 +129,7 @@
<ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
<ClCompile>
<PreprocessorDefinitions>_NO_ASYNCRTIMP;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</TreatWarningAsError>
</ClCompile>
<Link>
Expand All @@ -148,8 +148,8 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_NO_ASYNCRTIMP;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</TreatWarningAsError>
<TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</TreatWarningAsError>
</ClCompile>
Expand Down Expand Up @@ -196,6 +196,7 @@
<ClCompile Include="GroupPolicy.cpp" />
<ClCompile Include="HashCommand.cpp" />
<ClCompile Include="HttpClientHelper.cpp" />
<ClCompile Include="InstallerMetadataCollectionContext.cpp" />
<ClCompile Include="ManifestComparator.cpp" />
<ClCompile Include="JsonHelper.cpp" />
<ClCompile Include="MsiExecArguments.cpp" />
Expand Down
3 changes: 3 additions & 0 deletions src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@
<ClCompile Include="Correlation.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="InstallerMetadataCollectionContext.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MsixManifest.cpp">
<Filter>Source Files</Filter>
</ClCompile>
Expand Down
6 changes: 3 additions & 3 deletions src/AppInstallerCLITests/CustomHeader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include "TestSource.h"
#include "TestRestRequestHandler.h"
#include <Rest/Schema/1_1/Interface.h>
#include <Rest/Schema/JsonHelper.h>
#include <winget/JsonUtil.h>
#include <Rest/RestClient.h>
#include <winget/Settings.h>

Expand Down Expand Up @@ -79,7 +79,7 @@ TEST_CASE("RestClient_CustomHeader", "[RestSource][CustomHeader]")
}})delimiter");

std::optional<std::string> customHeader = "Testing custom header";
auto header = std::make_pair<>(CustomHeaderName, JsonHelper::GetUtilityString(customHeader.value()));
auto header = std::make_pair<>(CustomHeaderName, JSON::GetUtilityString(customHeader.value()));
HttpClientHelper helper{ GetCustomHeaderVerificationHandler(web::http::status_codes::OK, sample, header) };
RestClient client = RestClient::Create(utility::conversions::to_utf8string("https://restsource.com/api"), customHeader, std::move(helper));
REQUIRE(client.GetSourceIdentifier() == "Source123");
Expand Down Expand Up @@ -127,7 +127,7 @@ TEST_CASE("RestSourceSearch_NoCustomHeader", "[RestSource][CustomHeader]")
TEST_CASE("RestSourceSearch_CustomHeaderExceedingSize", "[RestSource][CustomHeader]")
{
std::string customHeader = "This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. ";
auto header = std::make_pair<>(CustomHeaderName, JsonHelper::GetUtilityString(customHeader));
auto header = std::make_pair<>(CustomHeaderName, JSON::GetUtilityString(customHeader));
HttpClientHelper helper{ GetCustomHeaderVerificationHandler(web::http::status_codes::OK, sampleSearchResponse, header) };

REQUIRE_THROWS_HR(RestClient::Create(utility::conversions::to_utf8string("https://restsource.com/api"), customHeader, std::move(helper)),
Expand Down
Loading

0 comments on commit 9f8ceea

Please sign in to comment.