Skip to content

Commit d08ae97

Browse files
committed
[TEST] One set of fake HTTP classes, and a default body this parser accepts
Main grew its own FakeResponse, FakeRequest, FakeSession and FakeHttpClient in #4071 and #4501, in an unnamed namespace, and this branch already had four of the same names in another unnamed namespace in the same file. Reopening an unnamed namespace names the same namespace, so the rebase merged both without a conflict into four redefinitions that do not compile. Merged rather than renamed. Main's set is used once and answers with one fixed response; this branch's runs a script the case supplies, which is the general case. So the session and the client take a script and default to answering the way main's did, and the existing call site is untouched. The default body had to change too, which is not cosmetic. It read `{"errors": false, "failed" : 0}`, and this pull request stops reading `failed` and starts requiring one `items` result per submitted record, so that body is now rejected: with it, ExportingARecordWithInvalidUtf8DoesNotAbort returns kFailure and fails. The default is now a body a server could send for a one record batch, and the comment that described the old substring search is rewritten. Verified in both configurations, since the guards cut different code: 26 tests, 22 passed and 4 skipped without async export, 20 passed and 6 skipped with it, no failures in either. Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
1 parent 3fc79c5 commit d08ae97

1 file changed

Lines changed: 37 additions & 94 deletions

File tree

‎exporters/elasticsearch/test/es_log_record_exporter_test.cc‎

Lines changed: 37 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,19 @@ namespace
3434
{
3535
namespace http_client = opentelemetry::ext::http::client;
3636

37-
// A response shaped like a successful Elasticsearch bulk reply: the exporter looks for
38-
// `"failed" : 0` in the body (see ElasticsearchLogRecordExporter::Export) in addition to the
39-
// status code before reporting success.
37+
// What the exporter accepts: a 2xx status, "errors" false, and one item result per record the
38+
// request submitted. A case that is not testing the response itself takes the default.
39+
constexpr const char *kOneAcceptedRecord =
40+
R"({"took":30,"errors":false,"items":[{"index":{"_index":"logs","_id":"1",)"
41+
R"("_shards":{"total":2,"successful":1,"failed":0},"status":201}}]})";
42+
4043
class FakeResponse final : public http_client::Response
4144
{
4245
public:
43-
FakeResponse()
44-
{
45-
static const std::string kSuccessBody = R"({"errors": false, "failed" : 0})";
46-
body_.assign(kSuccessBody.begin(), kSuccessBody.end());
47-
}
46+
explicit FakeResponse(http_client::StatusCode status = 200,
47+
const std::string &body = kOneAcceptedRecord)
48+
: status_(status), body_(body.begin(), body.end())
49+
{}
4850

4951
const http_client::Body &GetBody() const noexcept override { return body_; }
5052

@@ -63,9 +65,10 @@ class FakeResponse final : public http_client::Response
6365
return true;
6466
}
6567

66-
http_client::StatusCode GetStatusCode() const noexcept override { return 200; }
68+
http_client::StatusCode GetStatusCode() const noexcept override { return status_; }
6769

6870
private:
71+
http_client::StatusCode status_;
6972
http_client::Body body_;
7073
};
7174

@@ -90,39 +93,59 @@ class FakeRequest final : public http_client::Request
9093
void SetRetryPolicy(const http_client::RetryPolicy &) noexcept override {}
9194
};
9295

93-
// A session whose SendRequest() answers synchronously with a successful FakeResponse, so the
94-
// exporter's own wait for a response returns immediately without needing a real connection.
96+
// What the client does with a request, called from inside SendRequest() so the exporter's own
97+
// wait returns without needing a connection. The default answers once, successfully, which is
98+
// what a case wants when the response is not the thing under test.
99+
using EventScript = std::function<void(http_client::EventHandler &)>;
100+
101+
EventScript AnswerSuccessfully()
102+
{
103+
return [](http_client::EventHandler &handler) {
104+
FakeResponse response;
105+
handler.OnResponse(response);
106+
};
107+
}
108+
95109
class FakeSession final : public http_client::Session
96110
{
97111
public:
112+
explicit FakeSession(EventScript script = AnswerSuccessfully()) : script_(std::move(script)) {}
113+
98114
std::shared_ptr<http_client::Request> CreateRequest() noexcept override
99115
{
100116
return std::make_shared<FakeRequest>();
101117
}
102118

103119
void SendRequest(std::shared_ptr<http_client::EventHandler> handler) noexcept override
104120
{
105-
FakeResponse response;
106-
handler->OnResponse(response);
121+
script_(*handler);
107122
}
108123

109124
bool IsSessionActive() noexcept override { return true; }
110125
bool CancelSession() noexcept override { return true; }
111126
bool FinishSession() noexcept override { return true; }
127+
128+
private:
129+
EventScript script_;
112130
};
113131

114132
class FakeHttpClient final : public http_client::HttpClient
115133
{
116134
public:
135+
explicit FakeHttpClient(EventScript script = AnswerSuccessfully()) : script_(std::move(script)) {}
136+
117137
std::shared_ptr<http_client::Session> CreateSession(
118138
opentelemetry::nostd::string_view) noexcept override
119139
{
120-
return std::make_shared<FakeSession>();
140+
return std::make_shared<FakeSession>(script_);
121141
}
122142

123143
bool CancelAllSessions() noexcept override { return true; }
124144
bool FinishAllSessions() noexcept override { return true; }
125145
void SetMaxSessionsPerConnection(std::size_t) noexcept override {}
146+
147+
private:
148+
EventScript script_;
126149
};
127150

128151
} // namespace
@@ -554,86 +577,6 @@ TEST(ElasticsearchBulkResponseTests, RejectsAnItemErrorUnderErrorsFalse)
554577
// ---------------------------------------------------------------------------
555578
namespace
556579
{
557-
namespace http_client = opentelemetry::ext::http::client;
558-
559-
class FakeResponse : public http_client::Response
560-
{
561-
public:
562-
FakeResponse(http_client::StatusCode status, const std::string &body)
563-
: status_(status), body_(body.begin(), body.end())
564-
{}
565-
const http_client::Body &GetBody() const noexcept override { return body_; }
566-
bool ForEachHeader(
567-
nostd::function_ref<bool(nostd::string_view, nostd::string_view)>) const noexcept override
568-
{
569-
return true;
570-
}
571-
bool ForEachHeader(
572-
const nostd::string_view &,
573-
nostd::function_ref<bool(nostd::string_view, nostd::string_view)>) const noexcept override
574-
{
575-
return true;
576-
}
577-
http_client::StatusCode GetStatusCode() const noexcept override { return status_; }
578-
579-
private:
580-
http_client::StatusCode status_;
581-
http_client::Body body_;
582-
};
583-
584-
class FakeRequest : public http_client::Request
585-
{
586-
public:
587-
void SetMethod(http_client::Method) noexcept override {}
588-
void SetUri(nostd::string_view) noexcept override {}
589-
void SetSslOptions(const http_client::HttpSslOptions &) noexcept override {}
590-
void SetBody(http_client::Body &) noexcept override {}
591-
void AddHeader(nostd::string_view, nostd::string_view) noexcept override {}
592-
void ReplaceHeader(nostd::string_view, nostd::string_view) noexcept override {}
593-
void SetTimeoutMs(std::chrono::milliseconds) noexcept override {}
594-
void SetCompression(const http_client::Compression &) noexcept override {}
595-
void EnableLogging(bool) noexcept override {}
596-
void SetRetryPolicy(const http_client::RetryPolicy &) noexcept override {}
597-
};
598-
599-
using EventScript = std::function<void(http_client::EventHandler &)>;
600-
601-
class FakeSession : public http_client::Session
602-
{
603-
public:
604-
explicit FakeSession(EventScript script) : script_(std::move(script)) {}
605-
std::shared_ptr<http_client::Request> CreateRequest() noexcept override
606-
{
607-
return std::make_shared<FakeRequest>();
608-
}
609-
void SendRequest(std::shared_ptr<http_client::EventHandler> handler) noexcept override
610-
{
611-
script_(*handler);
612-
}
613-
bool IsSessionActive() noexcept override { return false; }
614-
bool CancelSession() noexcept override { return true; }
615-
bool FinishSession() noexcept override { return true; }
616-
617-
private:
618-
EventScript script_;
619-
};
620-
621-
class FakeHttpClient : public http_client::HttpClient
622-
{
623-
public:
624-
explicit FakeHttpClient(EventScript script) : script_(std::move(script)) {}
625-
std::shared_ptr<http_client::Session> CreateSession(nostd::string_view) noexcept override
626-
{
627-
return std::make_shared<FakeSession>(script_);
628-
}
629-
bool CancelAllSessions() noexcept override { return true; }
630-
bool FinishAllSessions() noexcept override { return true; }
631-
void SetMaxSessionsPerConnection(std::size_t) noexcept override {}
632-
633-
private:
634-
EventScript script_;
635-
};
636-
637580
// The response has to answer one operation per record, so a case using a body with N items has to
638581
// export N records or it would be rejected on the count before reaching what it means to test.
639582
opentelemetry::sdk::common::ExportResult ExportWith(EventScript script,

0 commit comments

Comments
 (0)