summaryrefslogtreecommitdiffstats
path: root/vespalib/src/tests/state_server/state_server_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'vespalib/src/tests/state_server/state_server_test.cpp')
-rw-r--r--vespalib/src/tests/state_server/state_server_test.cpp76
1 files changed, 57 insertions, 19 deletions
diff --git a/vespalib/src/tests/state_server/state_server_test.cpp b/vespalib/src/tests/state_server/state_server_test.cpp
index 2922a6d5069..6c248b54cc8 100644
--- a/vespalib/src/tests/state_server/state_server_test.cpp
+++ b/vespalib/src/tests/state_server/state_server_test.cpp
@@ -47,7 +47,8 @@ vespalib::string getPage(int port, const vespalib::string &path, const vespalib:
vespalib::string getFull(int port, const vespalib::string &path) { return getPage(port, path, "-D -"); }
-vespalib::string get_json(const JsonGetHandler &handler,
+std::pair<vespalib::string, vespalib::string>
+get_body_and_content_type(const JsonGetHandler &handler,
const vespalib::string &host,
const vespalib::string &path,
const std::map<vespalib::string,vespalib::string> &params)
@@ -55,11 +56,19 @@ vespalib::string get_json(const JsonGetHandler &handler,
net::ConnectionAuthContext dummy_ctx(net::tls::PeerCredentials(), net::tls::CapabilitySet::all());
auto res = handler.get(host, path, params, dummy_ctx);
if (res.ok()) {
- return res.payload();
+ return {res.payload(), res.content_type()};
}
return {};
}
+vespalib::string get_json(const JsonGetHandler &handler,
+ const vespalib::string &host,
+ const vespalib::string &path,
+ const std::map<vespalib::string,vespalib::string> &params)
+{
+ return get_body_and_content_type(handler, host, path, params).first;
+}
+
//-----------------------------------------------------------------------------
struct DummyHandler : JsonGetHandler {
@@ -208,7 +217,7 @@ TEST_FFFF("require that the state server wires the appropriate url prefixes",
SimpleHealthProducer(), SimpleMetricsProducer(), SimpleComponentConfigProducer(),
StateServer(0, f1, f2, f3))
{
- f2.setTotalMetrics("{}"); // avoid empty result
+ f2.setTotalMetrics("{}", MetricsProducer::ExpositionFormat::JSON); // avoid empty result
int port = f4.getListenPort();
EXPECT_TRUE(getFull(port, short_root_path).find("HTTP/1.1 200 OK") == 0);
EXPECT_TRUE(getFull(port, total_metrics_path).find("HTTP/1.1 200 OK") == 0);
@@ -282,7 +291,7 @@ TEST_FFFF("require that state api responds to the expected paths",
SimpleHealthProducer(), SimpleMetricsProducer(), SimpleComponentConfigProducer(),
StateApi(f1, f2, f3))
{
- f2.setTotalMetrics("{}"); // avoid empty result
+ f2.setTotalMetrics("{}", MetricsProducer::ExpositionFormat::JSON); // avoid empty result
EXPECT_TRUE(!get_json(f4, host_tag, short_root_path, empty_params).empty());
EXPECT_TRUE(!get_json(f4, host_tag, root_path, empty_params).empty());
EXPECT_TRUE(!get_json(f4, host_tag, health_path, empty_params).empty());
@@ -340,9 +349,20 @@ TEST_FFFF("require that metrics resource works as expected",
EXPECT_EQUAL("{\"status\":{\"code\":\"down\",\"message\":\"FAIL MSG\"}}",
get_json(f4, host_tag, metrics_path, empty_params));
f1.setOk();
- f2.setMetrics("{\"foo\":\"bar\"}");
- EXPECT_EQUAL("{\"status\":{\"code\":\"up\"},\"metrics\":{\"foo\":\"bar\"}}",
- get_json(f4, host_tag, metrics_path, empty_params));
+ f2.setMetrics(R"({"foo":"bar"})", MetricsProducer::ExpositionFormat::JSON);
+ f2.setMetrics(R"(cool_stuff{hello="world"} 1 23456)", MetricsProducer::ExpositionFormat::Prometheus);
+
+ auto result = get_body_and_content_type(f4, host_tag, metrics_path, empty_params);
+ EXPECT_EQUAL(R"({"status":{"code":"up"},"metrics":{"foo":"bar"}})", result.first);
+ EXPECT_EQUAL("application/json", result.second);
+
+ result = get_body_and_content_type(f4, host_tag, metrics_path, {{"format", "json"}}); // Explicit JSON
+ EXPECT_EQUAL(R"({"status":{"code":"up"},"metrics":{"foo":"bar"}})", result.first);
+ EXPECT_EQUAL("application/json", result.second);
+
+ result = get_body_and_content_type(f4, host_tag, metrics_path, {{"format", "prometheus"}}); // Explicit Prometheus
+ EXPECT_EQUAL(R"(cool_stuff{hello="world"} 1 23456)", result.first);
+ EXPECT_EQUAL("text/plain; version=0.0.4", result.second);
}
TEST_FFFF("require that config resource works as expected",
@@ -367,9 +387,12 @@ TEST_FFFF("require that state api also can return total metric",
SimpleHealthProducer(), SimpleMetricsProducer(), SimpleComponentConfigProducer(),
StateApi(f1, f2, f3))
{
- f2.setTotalMetrics("{\"foo\":\"bar\"}");
- EXPECT_EQUAL("{\"foo\":\"bar\"}",
+ f2.setTotalMetrics(R"({"foo":"bar"})", MetricsProducer::ExpositionFormat::JSON);
+ f2.setTotalMetrics(R"(cool_stuff{hello="world"} 1 23456)", MetricsProducer::ExpositionFormat::Prometheus);
+ EXPECT_EQUAL(R"({"foo":"bar"})",
get_json(f4, host_tag, total_metrics_path, empty_params));
+ EXPECT_EQUAL(R"(cool_stuff{hello="world"} 1 23456)",
+ get_json(f4, host_tag, total_metrics_path, {{"format", "prometheus"}}));
}
TEST_FFFFF("require that custom handlers can be added to the state server",
@@ -384,12 +407,25 @@ TEST_FFFFF("require that custom handlers can be added to the state server",
}
struct EchoConsumer : MetricsProducer {
+ static constexpr const char* to_string(ExpositionFormat format) noexcept {
+ switch (format) {
+ case ExpositionFormat::JSON: return "JSON";
+ case ExpositionFormat::Prometheus: return "Prometheus";
+ }
+ abort();
+ }
+
+ static vespalib::string stringify_params(const vespalib::string &consumer, ExpositionFormat format) {
+ // Not semantically meaningful output if format == Prometheus, but doesn't really matter here.
+ return vespalib::make_string(R"(["%s", "%s"])", to_string(format), consumer.c_str());
+ }
+
~EchoConsumer() override;
- vespalib::string getMetrics(const vespalib::string &consumer) override {
- return "[\"" + consumer + "\"]";
+ vespalib::string getMetrics(const vespalib::string &consumer, ExpositionFormat format) override {
+ return stringify_params(consumer, format);
}
- vespalib::string getTotalMetrics(const vespalib::string &consumer) override {
- return "[\"" + consumer + "\"]";
+ vespalib::string getTotalMetrics(const vespalib::string &consumer, ExpositionFormat format) override {
+ return stringify_params(consumer, format);
}
};
@@ -399,17 +435,17 @@ TEST_FFFF("require that empty v1 metrics consumer defaults to 'statereporter'",
SimpleHealthProducer(), EchoConsumer(), SimpleComponentConfigProducer(),
StateApi(f1, f2, f3))
{
- std::map<vespalib::string,vespalib::string> my_params;
- EXPECT_EQUAL("{\"status\":{\"code\":\"up\"},\"metrics\":[\"statereporter\"]}",
+ EXPECT_EQUAL(R"({"status":{"code":"up"},"metrics":["JSON", "statereporter"]})",
get_json(f4, host_tag, metrics_path, empty_params));
+ EXPECT_EQUAL(R"(["Prometheus", "statereporter"])",
+ get_json(f4, host_tag, metrics_path, {{"format", "prometheus"}}));
}
TEST_FFFF("require that empty total metrics consumer defaults to the empty string",
SimpleHealthProducer(), EchoConsumer(), SimpleComponentConfigProducer(),
StateApi(f1, f2, f3))
{
- std::map<vespalib::string,vespalib::string> my_params;
- EXPECT_EQUAL("[\"\"]", get_json(f4, host_tag, total_metrics_path, empty_params));
+ EXPECT_EQUAL(R"(["JSON", ""])", get_json(f4, host_tag, total_metrics_path, empty_params));
}
TEST_FFFF("require that metrics consumer is passed correctly",
@@ -418,8 +454,10 @@ TEST_FFFF("require that metrics consumer is passed correctly",
{
std::map<vespalib::string,vespalib::string> my_params;
my_params["consumer"] = "ME";
- EXPECT_EQUAL("{\"status\":{\"code\":\"up\"},\"metrics\":[\"ME\"]}", get_json(f4, host_tag, metrics_path, my_params));
- EXPECT_EQUAL("[\"ME\"]", get_json(f4, host_tag, total_metrics_path, my_params));
+ EXPECT_EQUAL(R"({"status":{"code":"up"},"metrics":["JSON", "ME"]})", get_json(f4, host_tag, metrics_path, my_params));
+ EXPECT_EQUAL(R"(["JSON", "ME"])", get_json(f4, host_tag, total_metrics_path, my_params));
+ my_params["format"] = "prometheus";
+ EXPECT_EQUAL(R"(["Prometheus", "ME"])", get_json(f4, host_tag, total_metrics_path, my_params));
}
void check_json(const vespalib::string &expect_json, const vespalib::string &actual_json) {