Vendor pinned T5 and T6 plugin sources under the new plugins layout. Add native HTTP deadlines, status and timing diagnostics, telemetry integration, and build/test tooling.
95 lines
4.6 KiB
C++
95 lines
4.6 KiB
C++
int main()
|
|
{
|
|
using namespace scripting;
|
|
http::http_request_params_t params{};
|
|
array options;
|
|
http::parse_request_options(params, options);
|
|
assert(params.limits.connect_timeout_ms == 5000 && params.limits.timeout_ms == 15000);
|
|
options["connect_timeout_ms"] = 120;
|
|
options["timeout_ms"] = 450;
|
|
options["method"] = "POST";
|
|
options["body"] = "snapshot";
|
|
array headers;
|
|
headers["Authorization"] = "Bearer test-only";
|
|
options["headers"] = headers;
|
|
http::parse_request_options(params, options);
|
|
assert(params.limits.connect_timeout_ms == 120 && params.limits.timeout_ms == 450);
|
|
assert(params.method == "POST" && params.fields == "snapshot" && params.headers.at("Authorization") == "Bearer test-only");
|
|
for (const auto* key : {"connect_timeout_ms", "timeout_ms"})
|
|
{
|
|
for (script_value value : {script_value(0), script_value(-1), script_value(1.5), script_value("150")})
|
|
{
|
|
array bad;
|
|
bad[key] = value;
|
|
bool rejected = false;
|
|
try { http::parse_request_options(params, bad); }
|
|
catch (const std::runtime_error&) { rejected = true; }
|
|
assert(rejected);
|
|
}
|
|
}
|
|
http::parse_request_options(params, options);
|
|
auto send = [&]()
|
|
{
|
|
notifications.clear();
|
|
http::create_request(params);
|
|
http::check_requests();
|
|
assert(notifications.empty()); // Incomplete work never notifies early.
|
|
scheduler::thread_pool.run();
|
|
http::check_requests();
|
|
assert(notifications.size() == 1 && notifications.front().size() == 4);
|
|
assert(utils::http::observed_limits.connect_timeout_ms == 120 && utils::http::observed_limits.timeout_ms == 450);
|
|
auto diagnostics = notifications.front()[3].as<array>();
|
|
assert(diagnostics["worker_queue_ms"].as<double>() >= 0 && diagnostics["notify_ms"].as<double>() >= 0);
|
|
assert(diagnostics["connect_timeout_ms"].as<int>() == 120 && diagnostics["timeout_ms"].as<int>() == 450);
|
|
assert(diagnostics.data->size() == 11);
|
|
http::check_requests();
|
|
assert(notifications.size() == 1); // Exactly one completion.
|
|
return diagnostics;
|
|
};
|
|
utils::http::result successful;
|
|
successful.code = CURLE_OK;
|
|
successful.status = 200;
|
|
successful.buffer = "accepted";
|
|
successful.dns_ms = 1;
|
|
successful.connect_ms = 2;
|
|
successful.tls_ms = 3;
|
|
successful.first_byte_ms = 4;
|
|
successful.total_ms = 5;
|
|
utils::http::next_result = successful;
|
|
auto diagnostics = send();
|
|
assert(notifications.front()[0].as<std::string>() == "accepted" && notifications.front()[1].as<bool>());
|
|
assert(notifications.front()[2].get_raw().type == game::SCRIPT_NONE);
|
|
assert(diagnostics["http_status"].as<int>() == 200 && diagnostics["curl_code"].as<int>() == 0);
|
|
assert(diagnostics["dns_ms"].as<double>() == 1 && diagnostics["connect_ms"].as<double>() == 2);
|
|
assert(diagnostics["tls_ms"].as<double>() == 3 && diagnostics["first_byte_ms"].as<double>() == 4 && diagnostics["total_ms"].as<double>() == 5);
|
|
utils::http::next_result->status = 500;
|
|
assert(send()["http_status"].as<int>() == 500 && notifications.front()[1].as<bool>());
|
|
utils::http::next_result->code = CURLE_OPERATION_TIMEDOUT;
|
|
assert(send()["curl_code"].as<int>() == 28 && !notifications.front()[1].as<bool>());
|
|
assert(notifications.front()[0].get_raw().type == game::SCRIPT_NONE && notifications.front()[2].is<std::string>());
|
|
utils::http::next_result = std::nullopt;
|
|
send();
|
|
assert(!notifications.front()[1].as<bool>());
|
|
utils::http::throw_from_transfer = true;
|
|
send();
|
|
assert(!notifications.front()[1].as<bool>());
|
|
utils::http::throw_from_transfer = false;
|
|
utils::http::next_result = successful;
|
|
utils::http::next_result->buffer = std::string(0x5001, 'x');
|
|
send();
|
|
assert(notifications.front()[0].as<std::string>().size() == 0x5000);
|
|
// A resumed waiter can enqueue enough work to reallocate the pending vector.
|
|
utils::http::next_result = successful;
|
|
notifications.clear();
|
|
http::create_request(params);
|
|
scheduler::thread_pool.run();
|
|
after_notify = [&]() { for (int i = 0; i < 100; ++i) http::create_request(params); };
|
|
http::check_requests();
|
|
after_notify = {};
|
|
assert(http::requests.size() == 100 && notifications.size() == 1);
|
|
scheduler::thread_pool.run();
|
|
http::check_requests();
|
|
assert(http::requests.empty() && notifications.size() == 101);
|
|
puts("\nPASS component: option validation, metadata, compatible argument order, single completion on failures/exceptions, reentrant queue");
|
|
}
|