brpc_prometheus_metrics_unittest.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Licensed to the Apache Software Foundation (ASF) under one
  2. // or more contributor license agreements. See the NOTICE file
  3. // distributed with this work for additional information
  4. // regarding copyright ownership. The ASF licenses this file
  5. // to you under the Apache License, Version 2.0 (the
  6. // "License"); you may not use this file except in compliance
  7. // with the License. You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing,
  12. // software distributed under the License is distributed on an
  13. // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  14. // KIND, either express or implied. See the License for the
  15. // specific language governing permissions and limitations
  16. // under the License.
  17. // brpc - A framework to host and access services throughout Baidu.
  18. #include <gtest/gtest.h>
  19. #include "brpc/server.h"
  20. #include "brpc/channel.h"
  21. #include "brpc/controller.h"
  22. #include "butil/strings/string_piece.h"
  23. #include "echo.pb.h"
  24. int main(int argc, char* argv[]) {
  25. testing::InitGoogleTest(&argc, argv);
  26. return RUN_ALL_TESTS();
  27. }
  28. class DummyEchoServiceImpl : public test::EchoService {
  29. public:
  30. virtual ~DummyEchoServiceImpl() {}
  31. virtual void Echo(google::protobuf::RpcController* cntl_base,
  32. const test::EchoRequest* request,
  33. test::EchoResponse* response,
  34. google::protobuf::Closure* done) {
  35. brpc::ClosureGuard done_guard(done);
  36. return;
  37. }
  38. };
  39. enum STATE {
  40. HELP = 0,
  41. TYPE,
  42. GAUGE,
  43. SUMMARY
  44. };
  45. TEST(PrometheusMetrics, sanity) {
  46. brpc::Server server;
  47. DummyEchoServiceImpl echo_svc;
  48. ASSERT_EQ(0, server.AddService(&echo_svc, brpc::SERVER_DOESNT_OWN_SERVICE));
  49. ASSERT_EQ(0, server.Start("127.0.0.1:8614", NULL));
  50. brpc::Server server2;
  51. DummyEchoServiceImpl echo_svc2;
  52. ASSERT_EQ(0, server2.AddService(&echo_svc2, brpc::SERVER_DOESNT_OWN_SERVICE));
  53. ASSERT_EQ(0, server2.Start("127.0.0.1:8615", NULL));
  54. brpc::Channel channel;
  55. brpc::ChannelOptions channel_opts;
  56. channel_opts.protocol = "http";
  57. ASSERT_EQ(0, channel.Init("127.0.0.1:8614", &channel_opts));
  58. brpc::Controller cntl;
  59. cntl.http_request().uri() = "/brpc_metrics";
  60. channel.CallMethod(NULL, &cntl, NULL, NULL, NULL);
  61. ASSERT_FALSE(cntl.Failed());
  62. std::string res = cntl.response_attachment().to_string();
  63. size_t start_pos = 0;
  64. size_t end_pos = 0;
  65. STATE state = HELP;
  66. char name_help[128];
  67. char name_type[128];
  68. char type[16];
  69. int matched = 0;
  70. int gauge_num = 0;
  71. bool summary_sum_gathered = false;
  72. bool summary_count_gathered = false;
  73. bool has_ever_summary = false;
  74. bool has_ever_gauge = false;
  75. while ((end_pos = res.find('\n', start_pos)) != butil::StringPiece::npos) {
  76. res[end_pos] = '\0'; // safe;
  77. switch (state) {
  78. case HELP:
  79. matched = sscanf(res.data() + start_pos, "# HELP %s", name_help);
  80. ASSERT_EQ(1, matched);
  81. state = TYPE;
  82. break;
  83. case TYPE:
  84. matched = sscanf(res.data() + start_pos, "# TYPE %s %s", name_type, type);
  85. ASSERT_EQ(2, matched);
  86. ASSERT_STREQ(name_type, name_help);
  87. if (strcmp(type, "gauge") == 0) {
  88. state = GAUGE;
  89. } else if (strcmp(type, "summary") == 0) {
  90. state = SUMMARY;
  91. } else {
  92. ASSERT_TRUE(false);
  93. }
  94. break;
  95. case GAUGE:
  96. matched = sscanf(res.data() + start_pos, "%s %d", name_type, &gauge_num);
  97. ASSERT_EQ(2, matched);
  98. ASSERT_STREQ(name_type, name_help);
  99. state = HELP;
  100. has_ever_gauge = true;
  101. break;
  102. case SUMMARY:
  103. if (butil::StringPiece(res.data() + start_pos, end_pos - start_pos).find("quantile=")
  104. == butil::StringPiece::npos) {
  105. matched = sscanf(res.data() + start_pos, "%s %d", name_type, &gauge_num);
  106. ASSERT_EQ(2, matched);
  107. ASSERT_TRUE(strncmp(name_type, name_help, strlen(name_help)) == 0);
  108. if (butil::StringPiece(name_type).ends_with("_sum")) {
  109. ASSERT_FALSE(summary_sum_gathered);
  110. summary_sum_gathered = true;
  111. } else if (butil::StringPiece(name_type).ends_with("_count")) {
  112. ASSERT_FALSE(summary_count_gathered);
  113. summary_count_gathered = true;
  114. } else {
  115. ASSERT_TRUE(false);
  116. }
  117. if (summary_sum_gathered && summary_count_gathered) {
  118. state = HELP;
  119. summary_sum_gathered = false;
  120. summary_count_gathered = false;
  121. has_ever_summary = true;
  122. }
  123. } // else find "quantile=", just break to next line
  124. break;
  125. default:
  126. ASSERT_TRUE(false);
  127. break;
  128. }
  129. start_pos = end_pos + 1;
  130. }
  131. ASSERT_TRUE(has_ever_gauge && has_ever_summary);
  132. ASSERT_EQ(0, server.Stop(0));
  133. ASSERT_EQ(0, server.Join());
  134. }