|
7 | 7 | #include "DefineTestMacros.h" |
8 | 8 | #include "Utils.h" |
9 | 9 | #include "../global/global.h" |
| 10 | +#include "Platform/ExternalHttpProvider.h" |
10 | 11 | #include <httpClient/httpProvider.h> |
11 | 12 |
|
12 | 13 | #if HC_PLATFORM == HC_PLATFORM_GDK |
@@ -70,6 +71,30 @@ static void CALLBACK PerformCallback( |
70 | 71 | XAsyncComplete(asyncBlock, S_OK, 0); |
71 | 72 | } |
72 | 73 |
|
| 74 | +static HCCallPerformFunction g_defaultPerform = nullptr; |
| 75 | +static void* g_defaultPerformContext = nullptr; |
| 76 | +static std::atomic<int> g_chainingFilterCalls{ 0 }; |
| 77 | + |
| 78 | +// Models the filter documented on HCGetHttpCallPerformFunction: chain to the default |
| 79 | +// implementation after inspecting the call. |
| 80 | +static void CALLBACK ChainingPerformCallback( |
| 81 | + _In_ HCCallHandle call, |
| 82 | + _Inout_ XAsyncBlock* asyncBlock, |
| 83 | + _In_opt_ void* ctx, |
| 84 | + _In_opt_ HCPerformEnv env |
| 85 | + ) |
| 86 | +{ |
| 87 | + UNREFERENCED_PARAMETER(ctx); |
| 88 | + |
| 89 | + if (++g_chainingFilterCalls > 1) |
| 90 | + { |
| 91 | + // Re-entered |
| 92 | + XAsyncComplete(asyncBlock, E_UNEXPECTED, 0); |
| 93 | + return; |
| 94 | + } |
| 95 | + |
| 96 | + g_defaultPerform(call, asyncBlock, g_defaultPerformContext, env); |
| 97 | +} |
73 | 98 |
|
74 | 99 | DEFINE_TEST_CLASS(HttpTests) |
75 | 100 | { |
@@ -128,6 +153,44 @@ DEFINE_TEST_CLASS(HttpTests) |
128 | 153 | VERIFY_IS_NULL(get_http_singleton()); |
129 | 154 | } |
130 | 155 |
|
| 156 | + DEFINE_TEST_CASE(TestPerformCallbackChainsToDefaultProvider) |
| 157 | + { |
| 158 | + DEFINE_TEST_CASE_PROPERTIES(TestPerformCallbackChainsToDefaultProvider); |
| 159 | + |
| 160 | + // This test only works while no client callback is installed. |
| 161 | + VERIFY_IS_FALSE(ExternalHttpProvider::Get().HasCallback()); |
| 162 | + |
| 163 | + g_chainingFilterCalls = 0; |
| 164 | + VERIFY_ARE_EQUAL(S_OK, HCGetHttpCallPerformFunction(&g_defaultPerform, &g_defaultPerformContext)); |
| 165 | + VERIFY_IS_NOT_NULL(g_defaultPerform); |
| 166 | + |
| 167 | + VERIFY_ARE_EQUAL(S_OK, HCSetHttpCallPerformFunction(&ChainingPerformCallback, nullptr)); |
| 168 | + VERIFY_ARE_EQUAL(S_OK, HCInitialize(nullptr)); |
| 169 | + |
| 170 | + HCCallHandle call{ nullptr }; |
| 171 | + VERIFY_ARE_EQUAL(S_OK, HCHttpCallCreate(&call)); |
| 172 | + VERIFY_ARE_EQUAL(S_OK, HCHttpCallRequestSetUrl(call, "GET", "http://127.0.0.1:1/")); |
| 173 | + VERIFY_ARE_EQUAL(S_OK, HCHttpCallRequestSetRetryAllowed(call, false)); |
| 174 | + |
| 175 | + XTaskQueueHandle queue{ nullptr }; |
| 176 | + VERIFY_ARE_EQUAL(S_OK, XTaskQueueCreate( |
| 177 | + XTaskQueueDispatchMode::ThreadPool, |
| 178 | + XTaskQueueDispatchMode::ThreadPool, |
| 179 | + &queue)); |
| 180 | + |
| 181 | + XAsyncBlock asyncBlock{}; |
| 182 | + asyncBlock.queue = queue; |
| 183 | + VERIFY_ARE_EQUAL(S_OK, HCHttpCallPerformAsync(call, &asyncBlock)); |
| 184 | + XAsyncGetStatus(&asyncBlock, true); |
| 185 | + |
| 186 | + VERIFY_ARE_EQUAL(S_OK, HCHttpCallCloseHandle(call)); |
| 187 | + XTaskQueueCloseHandle(queue); |
| 188 | + HCCleanup(); |
| 189 | + |
| 190 | + // Has to happen after HCCleanup() or else other tests break. |
| 191 | + VERIFY_ARE_EQUAL(1, g_chainingFilterCalls.load()); |
| 192 | + } |
| 193 | + |
131 | 194 | DEFINE_TEST_CASE(TestPerformCallback) |
132 | 195 | { |
133 | 196 | DEFINE_TEST_CASE_PROPERTIES_FOCUS(TestPerformCallback); |
|
0 commit comments