diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/messagebus/rain_check/http/client_ut.cpp | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/messagebus/rain_check/http/client_ut.cpp')
-rw-r--r-- | library/cpp/messagebus/rain_check/http/client_ut.cpp | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/library/cpp/messagebus/rain_check/http/client_ut.cpp b/library/cpp/messagebus/rain_check/http/client_ut.cpp new file mode 100644 index 0000000000..1628114391 --- /dev/null +++ b/library/cpp/messagebus/rain_check/http/client_ut.cpp @@ -0,0 +1,205 @@ +#include <library/cpp/testing/unittest/registar.h> + +#include "client.h" +#include "http_code_extractor.h" + +#include <library/cpp/messagebus/rain_check/test/ut/test.h> + +#include <library/cpp/messagebus/test/helper/fixed_port.h> + +#include <library/cpp/http/io/stream.h> +#include <library/cpp/neh/rpc.h> + +#include <util/generic/cast.h> +#include <util/generic/ptr.h> +#include <util/generic/strbuf.h> +#include <util/generic/string.h> +#include <util/generic/vector.h> +#include <util/network/ip.h> +#include <util/stream/str.h> +#include <util/string/printf.h> +#include <util/system/defaults.h> +#include <util/system/yassert.h> + +#include <cstdlib> +#include <utility> + +using namespace NRainCheck; +using namespace NBus::NTest; + +namespace { + class THttpClientEnv: public TTestEnvTemplate<THttpClientEnv> { + public: + THttpClientService HttpClientService; + }; + + const TString TEST_SERVICE = "test-service"; + const TString TEST_GET_PARAMS = "p=GET"; + const TString TEST_POST_PARAMS = "p=POST"; + const TString TEST_POST_HEADERS = "Content-Type: application/json\r\n"; + const TString TEST_GET_RECV = "GET was ok."; + const TString TEST_POST_RECV = "POST was ok."; + + TString BuildServiceLocation(ui32 port) { + return Sprintf("http://*:%" PRIu32 "/%s", port, TEST_SERVICE.data()); + } + + TString BuildPostServiceLocation(ui32 port) { + return Sprintf("post://*:%" PRIu32 "/%s", port + 1, TEST_SERVICE.data()); + } + + TString BuildGetTestRequest(ui32 port) { + return BuildServiceLocation(port) + "?" + TEST_GET_PARAMS; + } + + class TSimpleServer { + public: + inline void ServeRequest(const NNeh::IRequestRef& req) { + NNeh::TData response; + if (req->Data() == TEST_GET_PARAMS) { + response.assign(TEST_GET_RECV.begin(), TEST_GET_RECV.end()); + } else { + response.assign(TEST_POST_RECV.begin(), TEST_POST_RECV.end()); + } + req->SendReply(response); + } + }; + + NNeh::IServicesRef RunServer(ui32 port, TSimpleServer& server) { + NNeh::IServicesRef runner = NNeh::CreateLoop(); + runner->Add(BuildServiceLocation(port), server); + runner->Add(BuildPostServiceLocation(port), server); + + try { + const int THR_POOL_SIZE = 2; + runner->ForkLoop(THR_POOL_SIZE); + } catch (...) { + Y_FAIL("Can't run server: %s", CurrentExceptionMessage().data()); + } + + return runner; + } + enum ERequestType { + RT_HTTP_GET = 0, + RT_HTTP_POST = 1 + }; + + using TTaskParam = std::pair<TIpPort, ERequestType>; + + class THttpClientTask: public ISimpleTask { + public: + THttpClientTask(THttpClientEnv* env, TTaskParam param) + : Env(env) + , ServerPort(param.first) + , ReqType(param.second) + { + } + + TContinueFunc Start() override { + switch (ReqType) { + case RT_HTTP_GET: { + TString getRequest = BuildGetTestRequest(ServerPort); + for (size_t i = 0; i < 3; ++i) { + Requests.push_back(new THttpFuture()); + Env->HttpClientService.Send(getRequest, Requests[i].Get()); + } + break; + } + case RT_HTTP_POST: { + TString servicePath = BuildPostServiceLocation(ServerPort); + TStringInput headersText(TEST_POST_HEADERS); + THttpHeaders headers(&headersText); + for (size_t i = 0; i < 3; ++i) { + Requests.push_back(new THttpFuture()); + Env->HttpClientService.SendPost(servicePath, TEST_POST_PARAMS, headers, Requests[i].Get()); + } + break; + } + } + + return &THttpClientTask::GotReplies; + } + + TContinueFunc GotReplies() { + const TString& TEST_OK_RECV = (ReqType == RT_HTTP_GET) ? TEST_GET_RECV : TEST_POST_RECV; + for (size_t i = 0; i < Requests.size(); ++i) { + UNIT_ASSERT_EQUAL(Requests[i]->GetHttpCode(), 200); + UNIT_ASSERT_EQUAL(Requests[i]->GetResponseBody(), TEST_OK_RECV); + } + + Env->TestSync.CheckAndIncrement(0); + + return nullptr; + } + + THttpClientEnv* const Env; + const TIpPort ServerPort; + const ERequestType ReqType; + + TVector<TSimpleSharedPtr<THttpFuture>> Requests; + }; + +} // anonymous namespace + +Y_UNIT_TEST_SUITE(RainCheckHttpClient) { + static const TIpPort SERVER_PORT = 4000; + + Y_UNIT_TEST(Simple) { + // TODO: randomize port + if (!IsFixedPortTestAllowed()) { + return; + } + + TSimpleServer server; + NNeh::IServicesRef runner = RunServer(SERVER_PORT, server); + + THttpClientEnv env; + TIntrusivePtr<TSimpleTaskRunner> task = env.SpawnTask<THttpClientTask>(TTaskParam(SERVER_PORT, RT_HTTP_GET)); + + env.TestSync.WaitForAndIncrement(1); + } + + Y_UNIT_TEST(SimplePost) { + // TODO: randomize port + if (!IsFixedPortTestAllowed()) { + return; + } + + TSimpleServer server; + NNeh::IServicesRef runner = RunServer(SERVER_PORT, server); + + THttpClientEnv env; + TIntrusivePtr<TSimpleTaskRunner> task = env.SpawnTask<THttpClientTask>(TTaskParam(SERVER_PORT, RT_HTTP_POST)); + + env.TestSync.WaitForAndIncrement(1); + } + + Y_UNIT_TEST(HttpCodeExtraction) { + // Find "request failed(" string, then copy len("HTTP/1.X NNN") chars and try to convert NNN to HTTP code. + +#define CHECK_VALID_LINE(line, code) \ + UNIT_ASSERT_NO_EXCEPTION(TryGetHttpCodeFromErrorDescription(line)); \ + UNIT_ASSERT(!!TryGetHttpCodeFromErrorDescription(line)); \ + UNIT_ASSERT_EQUAL(*TryGetHttpCodeFromErrorDescription(line), code) + + CHECK_VALID_LINE(TStringBuf("library/cpp/neh/http.cpp:<LINE>: request failed(HTTP/1.0 200 Some random message"), 200); + CHECK_VALID_LINE(TStringBuf("library/cpp/neh/http.cpp:<LINE>: request failed(HTTP/1.0 404 Some random message"), 404); + CHECK_VALID_LINE(TStringBuf("request failed(HTTP/1.0 100 Some random message"), 100); + CHECK_VALID_LINE(TStringBuf("request failed(HTTP/1.0 105)"), 105); + CHECK_VALID_LINE(TStringBuf("request failed(HTTP/1.1 2004 Some random message"), 200); +#undef CHECK_VALID_LINE + +#define CHECK_INVALID_LINE(line) \ + UNIT_ASSERT_NO_EXCEPTION(TryGetHttpCodeFromErrorDescription(line)); \ + UNIT_ASSERT(!TryGetHttpCodeFromErrorDescription(line)) + + CHECK_INVALID_LINE(TStringBuf("library/cpp/neh/http.cpp:<LINE>: request failed(HTTP/1.1 1 Some random message")); + CHECK_INVALID_LINE(TStringBuf("request failed(HTTP/1.0 asdf Some random message")); + CHECK_INVALID_LINE(TStringBuf("HTTP/1.0 200 Some random message")); + CHECK_INVALID_LINE(TStringBuf("request failed(HTTP/1.0 2x00 Some random message")); + CHECK_INVALID_LINE(TStringBuf("HTTP/1.0 200 Some random message")); + CHECK_INVALID_LINE(TStringBuf("HTTP/1.0 200")); + CHECK_INVALID_LINE(TStringBuf("request failed(HTTP/1.1 3334 Some random message")); +#undef CHECK_INVALID_LINE + } +} |