aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/messagebus/rain_check/http/client_ut.cpp
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/messagebus/rain_check/http/client_ut.cpp
downloadydb-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.cpp205
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
+ }
+}