load_reporter_test.cc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. /*
  2. *
  3. * Copyright 2018 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * 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, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. #include <grpc/impl/codegen/port_platform.h>
  19. #include "src/cpp/server/load_reporter/load_reporter.h"
  20. #include <set>
  21. #include <vector>
  22. #include <gmock/gmock.h>
  23. #include <gtest/gtest.h>
  24. #include "absl/memory/memory.h"
  25. #include "opencensus/stats/testing/test_utils.h"
  26. #include <grpc/grpc.h>
  27. #include "src/core/ext/filters/load_reporting/registered_opencensus_objects.h"
  28. #include "src/core/lib/iomgr/exec_ctx.h"
  29. #include "src/cpp/server/load_reporter/constants.h"
  30. #include "test/core/util/port.h"
  31. #include "test/core/util/test_config.h"
  32. namespace grpc {
  33. namespace testing {
  34. namespace {
  35. using ::grpc::lb::v1::LoadBalancingFeedback;
  36. using ::grpc::load_reporter::CensusViewProvider;
  37. using ::grpc::load_reporter::CpuStatsProvider;
  38. using ::grpc::load_reporter::LoadReporter;
  39. using ::opencensus::stats::ViewDescriptor;
  40. using ::testing::DoubleNear;
  41. using ::testing::Return;
  42. constexpr uint64_t kFeedbackSampleWindowSeconds = 5;
  43. constexpr uint64_t kFetchAndSampleIntervalSeconds = 1;
  44. constexpr uint64_t kNumFeedbackSamplesInWindow =
  45. kFeedbackSampleWindowSeconds / kFetchAndSampleIntervalSeconds;
  46. class MockCensusViewProvider : public CensusViewProvider {
  47. public:
  48. MOCK_METHOD0(FetchViewData, CensusViewProvider::ViewDataMap());
  49. const ::opencensus::stats::ViewDescriptor& FindViewDescriptor(
  50. const std::string& view_name) {
  51. auto it = view_descriptor_map().find(view_name);
  52. GPR_ASSERT(it != view_descriptor_map().end());
  53. return it->second;
  54. }
  55. };
  56. class MockCpuStatsProvider : public CpuStatsProvider {
  57. public:
  58. MOCK_METHOD0(GetCpuStats, CpuStatsProvider::CpuStatsSample());
  59. };
  60. class LoadReporterTest : public ::testing::Test {
  61. public:
  62. LoadReporterTest() {}
  63. MockCensusViewProvider* mock_census_view_provider() {
  64. return static_cast<MockCensusViewProvider*>(
  65. load_reporter_->census_view_provider());
  66. }
  67. void PrepareCpuExpectation(size_t call_num) {
  68. auto mock_cpu_stats_provider = static_cast<MockCpuStatsProvider*>(
  69. load_reporter_->cpu_stats_provider());
  70. ::testing::InSequence s;
  71. for (size_t i = 0; i < call_num; ++i) {
  72. EXPECT_CALL(*mock_cpu_stats_provider, GetCpuStats())
  73. .WillOnce(Return(kCpuStatsSamples[i]))
  74. .RetiresOnSaturation();
  75. }
  76. }
  77. CpuStatsProvider::CpuStatsSample initial_cpu_stats_{2, 20};
  78. const std::vector<CpuStatsProvider::CpuStatsSample> kCpuStatsSamples = {
  79. {13, 53}, {64, 96}, {245, 345}, {314, 785},
  80. {874, 1230}, {1236, 2145}, {1864, 2974}};
  81. std::unique_ptr<LoadReporter> load_reporter_;
  82. const std::string kHostname1 = "kHostname1";
  83. const std::string kHostname2 = "kHostname2";
  84. const std::string kHostname3 = "kHostname3";
  85. // Pad to the length of a valid LB ID.
  86. const std::string kLbId1 = "kLbId111";
  87. const std::string kLbId2 = "kLbId222";
  88. const std::string kLbId3 = "kLbId333";
  89. const std::string kLbId4 = "kLbId444";
  90. const std::string kLoadKey1 = "kLoadKey1";
  91. const std::string kLoadKey2 = "kLoadKey2";
  92. const std::string kLoadKey3 = "kLoadKey3";
  93. const std::string kLbTag1 = "kLbTag1";
  94. const std::string kLbTag2 = "kLbTag2";
  95. const std::string kLbToken1 = "kLbId111kLbTag1";
  96. const std::string kLbToken2 = "kLbId222kLbTag2";
  97. const std::string kUser1 = "kUser1";
  98. const std::string kUser2 = "kUser2";
  99. const std::string kUser3 = "kUser3";
  100. const std::string kClientIp0 = "00";
  101. const std::string kClientIp1 = "0800000001";
  102. const std::string kClientIp2 = "3200000000000000000000000000000002";
  103. const std::string kMetric1 = "kMetric1";
  104. const std::string kMetric2 = "kMetric2";
  105. private:
  106. void SetUp() override {
  107. // Access the measures to make them valid.
  108. grpc::load_reporter::MeasureStartCount();
  109. grpc::load_reporter::MeasureEndCount();
  110. grpc::load_reporter::MeasureEndBytesSent();
  111. grpc::load_reporter::MeasureEndBytesReceived();
  112. grpc::load_reporter::MeasureEndLatencyMs();
  113. grpc::load_reporter::MeasureOtherCallMetric();
  114. // Set up the load reporter.
  115. auto mock_cpu = new MockCpuStatsProvider();
  116. auto mock_census = new MockCensusViewProvider();
  117. // Prepare the initial CPU stats data. Note that the expectation should be
  118. // set up before the load reporter is initialized, because CPU stats is
  119. // sampled at that point.
  120. EXPECT_CALL(*mock_cpu, GetCpuStats())
  121. .WillOnce(Return(initial_cpu_stats_))
  122. .RetiresOnSaturation();
  123. load_reporter_ = absl::make_unique<LoadReporter>(
  124. kFeedbackSampleWindowSeconds,
  125. std::unique_ptr<CensusViewProvider>(mock_census),
  126. std::unique_ptr<CpuStatsProvider>(mock_cpu));
  127. }
  128. };
  129. class LbFeedbackTest : public LoadReporterTest {
  130. public:
  131. // Note that [start, start + count) of the fake samples (maybe plus the
  132. // initial record) are in the window now.
  133. void VerifyLbFeedback(const LoadBalancingFeedback& lb_feedback, size_t start,
  134. size_t count) {
  135. const CpuStatsProvider::CpuStatsSample* base =
  136. start == 0 ? &initial_cpu_stats_ : &kCpuStatsSamples[start - 1];
  137. double expected_cpu_util =
  138. static_cast<double>(kCpuStatsSamples[start + count - 1].first -
  139. base->first) /
  140. static_cast<double>(kCpuStatsSamples[start + count - 1].second -
  141. base->second);
  142. ASSERT_THAT(static_cast<double>(lb_feedback.server_utilization()),
  143. DoubleNear(expected_cpu_util, 0.00001));
  144. double qps_sum = 0, eps_sum = 0;
  145. for (size_t i = 0; i < count; ++i) {
  146. qps_sum += kQpsEpsSamples[start + i].first;
  147. eps_sum += kQpsEpsSamples[start + i].second;
  148. }
  149. double expected_qps = qps_sum / count;
  150. double expected_eps = eps_sum / count;
  151. // TODO(juanlishen): The error is big because we use sleep(). It should be
  152. // much smaller when we use fake clock.
  153. ASSERT_THAT(static_cast<double>(lb_feedback.calls_per_second()),
  154. DoubleNear(expected_qps, expected_qps * 0.3));
  155. ASSERT_THAT(static_cast<double>(lb_feedback.errors_per_second()),
  156. DoubleNear(expected_eps, expected_eps * 0.3));
  157. gpr_log(GPR_INFO,
  158. "Verified LB feedback matches the samples of index [%zu, %zu).",
  159. start, start + count);
  160. }
  161. const std::vector<std::pair<double, double>> kQpsEpsSamples = {
  162. {546.1, 153.1}, {62.1, 54.1}, {578.1, 154.2}, {978.1, 645.1},
  163. {1132.1, 846.4}, {531.5, 315.4}, {874.1, 324.9}};
  164. };
  165. TEST_F(LbFeedbackTest, ZeroDuration) {
  166. PrepareCpuExpectation(kCpuStatsSamples.size());
  167. EXPECT_CALL(*mock_census_view_provider(), FetchViewData())
  168. .WillRepeatedly(
  169. Return(grpc::load_reporter::CensusViewProvider::ViewDataMap()));
  170. // Verify that divide-by-zero exception doesn't happen.
  171. for (size_t i = 0; i < kCpuStatsSamples.size(); ++i) {
  172. load_reporter_->FetchAndSample();
  173. }
  174. load_reporter_->GenerateLoadBalancingFeedback();
  175. }
  176. TEST_F(LbFeedbackTest, Normal) {
  177. // Prepare view data list using the <QPS, EPS> samples.
  178. std::vector<CensusViewProvider::ViewDataMap> view_data_map_list;
  179. for (const auto& p : LbFeedbackTest::kQpsEpsSamples) {
  180. double qps = p.first;
  181. double eps = p.second;
  182. double ok_count = (qps - eps) * kFetchAndSampleIntervalSeconds;
  183. double error_count = eps * kFetchAndSampleIntervalSeconds;
  184. double ok_count_1 = ok_count / 3.0;
  185. double ok_count_2 = ok_count - ok_count_1;
  186. auto end_count_vd = ::opencensus::stats::testing::TestUtils::MakeViewData(
  187. mock_census_view_provider()->FindViewDescriptor(
  188. grpc::load_reporter::kViewEndCount),
  189. {{{kClientIp0 + kLbToken1, kHostname1, kUser1,
  190. grpc::load_reporter::kCallStatusOk},
  191. ok_count_1},
  192. {{kClientIp0 + kLbToken1, kHostname1, kUser2,
  193. grpc::load_reporter::kCallStatusOk},
  194. ok_count_2},
  195. {{kClientIp0 + kLbToken1, kHostname1, kUser1,
  196. grpc::load_reporter::kCallStatusClientError},
  197. error_count}});
  198. // Values for other view data don't matter.
  199. auto end_bytes_sent_vd =
  200. ::opencensus::stats::testing::TestUtils::MakeViewData(
  201. mock_census_view_provider()->FindViewDescriptor(
  202. grpc::load_reporter::kViewEndBytesSent),
  203. {{{kClientIp0 + kLbToken1, kHostname1, kUser1,
  204. grpc::load_reporter::kCallStatusOk},
  205. 0},
  206. {{kClientIp0 + kLbToken1, kHostname1, kUser2,
  207. grpc::load_reporter::kCallStatusOk},
  208. 0},
  209. {{kClientIp0 + kLbToken1, kHostname1, kUser1,
  210. grpc::load_reporter::kCallStatusClientError},
  211. 0}});
  212. auto end_bytes_received_vd =
  213. ::opencensus::stats::testing::TestUtils::MakeViewData(
  214. mock_census_view_provider()->FindViewDescriptor(
  215. grpc::load_reporter::kViewEndBytesReceived),
  216. {{{kClientIp0 + kLbToken1, kHostname1, kUser1,
  217. grpc::load_reporter::kCallStatusOk},
  218. 0},
  219. {{kClientIp0 + kLbToken1, kHostname1, kUser2,
  220. grpc::load_reporter::kCallStatusOk},
  221. 0},
  222. {{kClientIp0 + kLbToken1, kHostname1, kUser1,
  223. grpc::load_reporter::kCallStatusClientError},
  224. 0}});
  225. auto end_latency_vd = ::opencensus::stats::testing::TestUtils::MakeViewData(
  226. mock_census_view_provider()->FindViewDescriptor(
  227. grpc::load_reporter::kViewEndLatencyMs),
  228. {{{kClientIp0 + kLbToken1, kHostname1, kUser1,
  229. grpc::load_reporter::kCallStatusOk},
  230. 0},
  231. {{kClientIp0 + kLbToken1, kHostname1, kUser2,
  232. grpc::load_reporter::kCallStatusOk},
  233. 0},
  234. {{kClientIp0 + kLbToken1, kHostname1, kUser1,
  235. grpc::load_reporter::kCallStatusClientError},
  236. 0}});
  237. view_data_map_list.push_back(
  238. {{::grpc::load_reporter::kViewEndCount, end_count_vd},
  239. {::grpc::load_reporter::kViewEndBytesSent, end_bytes_sent_vd},
  240. {::grpc::load_reporter::kViewEndBytesReceived, end_bytes_received_vd},
  241. {::grpc::load_reporter::kViewEndLatencyMs, end_latency_vd}});
  242. }
  243. {
  244. ::testing::InSequence s;
  245. for (size_t i = 0; i < view_data_map_list.size(); ++i) {
  246. EXPECT_CALL(*mock_census_view_provider(), FetchViewData())
  247. .WillOnce(Return(view_data_map_list[i]))
  248. .RetiresOnSaturation();
  249. }
  250. }
  251. PrepareCpuExpectation(kNumFeedbackSamplesInWindow + 2);
  252. // When the load reporter is created, a trivial LB feedback record is added.
  253. // But that's not enough for generating an LB feedback.
  254. // Fetch some view data so that non-trivial LB feedback can be generated.
  255. for (size_t i = 0; i < kNumFeedbackSamplesInWindow / 2; ++i) {
  256. // TODO(juanlishen): Find some fake clock to speed up testing.
  257. sleep(1);
  258. load_reporter_->FetchAndSample();
  259. }
  260. VerifyLbFeedback(load_reporter_->GenerateLoadBalancingFeedback(), 0,
  261. kNumFeedbackSamplesInWindow / 2);
  262. // Fetch more view data so that the feedback record window is just full (the
  263. // initial record just falls out of the window).
  264. for (size_t i = 0; i < (kNumFeedbackSamplesInWindow + 1) / 2; ++i) {
  265. sleep(1);
  266. load_reporter_->FetchAndSample();
  267. }
  268. VerifyLbFeedback(load_reporter_->GenerateLoadBalancingFeedback(), 0,
  269. kNumFeedbackSamplesInWindow);
  270. // Further fetching will cause the old records to fall out of the window.
  271. for (size_t i = 0; i < 2; ++i) {
  272. sleep(1);
  273. load_reporter_->FetchAndSample();
  274. }
  275. VerifyLbFeedback(load_reporter_->GenerateLoadBalancingFeedback(), 2,
  276. kNumFeedbackSamplesInWindow);
  277. }
  278. using LoadReportTest = LoadReporterTest;
  279. TEST_F(LoadReportTest, BasicReport) {
  280. // Make up the first view data map.
  281. CensusViewProvider::ViewDataMap vdm1;
  282. vdm1.emplace(
  283. grpc::load_reporter::kViewStartCount,
  284. ::opencensus::stats::testing::TestUtils::MakeViewData(
  285. mock_census_view_provider()->FindViewDescriptor(
  286. grpc::load_reporter::kViewStartCount),
  287. {{{kClientIp1 + kLbToken1, kHostname1, kUser1}, 1234},
  288. {{kClientIp2 + kLbToken1, kHostname1, kUser1}, 1225},
  289. {{kClientIp0 + kLbToken1, kHostname1, kUser1}, 10},
  290. {{kClientIp2 + kLbToken1, kHostname1, kUser2}, 464},
  291. {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3}, 101},
  292. {{kClientIp1 + kLbToken2, kHostname2, kUser3}, 17},
  293. {{kClientIp2 + kLbId3 + kLbTag2, kHostname2, kUser3}, 23}}));
  294. vdm1.emplace(grpc::load_reporter::kViewEndCount,
  295. ::opencensus::stats::testing::TestUtils::MakeViewData(
  296. mock_census_view_provider()->FindViewDescriptor(
  297. grpc::load_reporter::kViewEndCount),
  298. {{{kClientIp1 + kLbToken1, kHostname1, kUser1,
  299. grpc::load_reporter::kCallStatusOk},
  300. 641},
  301. {{kClientIp2 + kLbToken1, kHostname1, kUser1,
  302. grpc::load_reporter::kCallStatusClientError},
  303. 272},
  304. {{kClientIp2 + kLbToken1, kHostname1, kUser2,
  305. grpc::load_reporter::kCallStatusOk},
  306. 996},
  307. {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3,
  308. grpc::load_reporter::kCallStatusClientError},
  309. 34},
  310. {{kClientIp1 + kLbToken2, kHostname2, kUser2,
  311. grpc::load_reporter::kCallStatusOk},
  312. 18}}));
  313. vdm1.emplace(grpc::load_reporter::kViewEndBytesSent,
  314. ::opencensus::stats::testing::TestUtils::MakeViewData(
  315. mock_census_view_provider()->FindViewDescriptor(
  316. grpc::load_reporter::kViewEndBytesSent),
  317. {{{kClientIp1 + kLbToken1, kHostname1, kUser1,
  318. grpc::load_reporter::kCallStatusOk},
  319. 8977},
  320. {{kClientIp2 + kLbToken1, kHostname1, kUser1,
  321. grpc::load_reporter::kCallStatusClientError},
  322. 266},
  323. {{kClientIp2 + kLbToken1, kHostname1, kUser2,
  324. grpc::load_reporter::kCallStatusOk},
  325. 1276},
  326. {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3,
  327. grpc::load_reporter::kCallStatusClientError},
  328. 77823},
  329. {{kClientIp1 + kLbToken2, kHostname2, kUser2,
  330. grpc::load_reporter::kCallStatusOk},
  331. 48}}));
  332. vdm1.emplace(grpc::load_reporter::kViewEndBytesReceived,
  333. ::opencensus::stats::testing::TestUtils::MakeViewData(
  334. mock_census_view_provider()->FindViewDescriptor(
  335. grpc::load_reporter::kViewEndBytesReceived),
  336. {{{kClientIp1 + kLbToken1, kHostname1, kUser1,
  337. grpc::load_reporter::kCallStatusOk},
  338. 2341},
  339. {{kClientIp2 + kLbToken1, kHostname1, kUser1,
  340. grpc::load_reporter::kCallStatusClientError},
  341. 466},
  342. {{kClientIp2 + kLbToken1, kHostname1, kUser2,
  343. grpc::load_reporter::kCallStatusOk},
  344. 518},
  345. {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3,
  346. grpc::load_reporter::kCallStatusClientError},
  347. 81},
  348. {{kClientIp1 + kLbToken2, kHostname2, kUser2,
  349. grpc::load_reporter::kCallStatusOk},
  350. 27}}));
  351. vdm1.emplace(grpc::load_reporter::kViewEndLatencyMs,
  352. ::opencensus::stats::testing::TestUtils::MakeViewData(
  353. mock_census_view_provider()->FindViewDescriptor(
  354. grpc::load_reporter::kViewEndLatencyMs),
  355. {{{kClientIp1 + kLbToken1, kHostname1, kUser1,
  356. grpc::load_reporter::kCallStatusOk},
  357. 3.14},
  358. {{kClientIp2 + kLbToken1, kHostname1, kUser1,
  359. grpc::load_reporter::kCallStatusClientError},
  360. 5.26},
  361. {{kClientIp2 + kLbToken1, kHostname1, kUser2,
  362. grpc::load_reporter::kCallStatusOk},
  363. 45.4},
  364. {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3,
  365. grpc::load_reporter::kCallStatusClientError},
  366. 4.4},
  367. {{kClientIp1 + kLbToken2, kHostname2, kUser2,
  368. grpc::load_reporter::kCallStatusOk},
  369. 2348.0}}));
  370. vdm1.emplace(
  371. grpc::load_reporter::kViewOtherCallMetricCount,
  372. ::opencensus::stats::testing::TestUtils::MakeViewData(
  373. mock_census_view_provider()->FindViewDescriptor(
  374. grpc::load_reporter::kViewOtherCallMetricCount),
  375. {{{kClientIp1 + kLbToken1, kHostname1, kUser2, kMetric1}, 1},
  376. {{kClientIp1 + kLbToken1, kHostname1, kUser2, kMetric1}, 1},
  377. {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3, kMetric2},
  378. 1}}));
  379. vdm1.emplace(
  380. grpc::load_reporter::kViewOtherCallMetricValue,
  381. ::opencensus::stats::testing::TestUtils::MakeViewData(
  382. mock_census_view_provider()->FindViewDescriptor(
  383. grpc::load_reporter::kViewOtherCallMetricValue),
  384. {{{kClientIp1 + kLbToken1, kHostname1, kUser2, kMetric1}, 1.2},
  385. {{kClientIp1 + kLbToken1, kHostname1, kUser2, kMetric1}, 1.2},
  386. {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3, kMetric2},
  387. 3.2}}));
  388. // Make up the second view data map.
  389. CensusViewProvider::ViewDataMap vdm2;
  390. vdm2.emplace(
  391. grpc::load_reporter::kViewStartCount,
  392. ::opencensus::stats::testing::TestUtils::MakeViewData(
  393. mock_census_view_provider()->FindViewDescriptor(
  394. grpc::load_reporter::kViewStartCount),
  395. {{{kClientIp2 + kLbToken1, kHostname1, kUser1}, 3},
  396. {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3}, 778}}));
  397. vdm2.emplace(grpc::load_reporter::kViewEndCount,
  398. ::opencensus::stats::testing::TestUtils::MakeViewData(
  399. mock_census_view_provider()->FindViewDescriptor(
  400. grpc::load_reporter::kViewEndCount),
  401. {{{kClientIp1 + kLbToken1, kHostname1, kUser1,
  402. grpc::load_reporter::kCallStatusOk},
  403. 24},
  404. {{kClientIp1 + kLbToken2, kHostname2, kUser3,
  405. grpc::load_reporter::kCallStatusClientError},
  406. 546}}));
  407. vdm2.emplace(grpc::load_reporter::kViewEndBytesSent,
  408. ::opencensus::stats::testing::TestUtils::MakeViewData(
  409. mock_census_view_provider()->FindViewDescriptor(
  410. grpc::load_reporter::kViewEndBytesSent),
  411. {{{kClientIp1 + kLbToken1, kHostname1, kUser1,
  412. grpc::load_reporter::kCallStatusOk},
  413. 747},
  414. {{kClientIp1 + kLbToken2, kHostname2, kUser3,
  415. grpc::load_reporter::kCallStatusClientError},
  416. 229}}));
  417. vdm2.emplace(grpc::load_reporter::kViewEndBytesReceived,
  418. ::opencensus::stats::testing::TestUtils::MakeViewData(
  419. mock_census_view_provider()->FindViewDescriptor(
  420. grpc::load_reporter::kViewEndBytesReceived),
  421. {{{kClientIp1 + kLbToken1, kHostname1, kUser1,
  422. grpc::load_reporter::kCallStatusOk},
  423. 173},
  424. {{kClientIp1 + kLbToken2, kHostname2, kUser3,
  425. grpc::load_reporter::kCallStatusClientError},
  426. 438}}));
  427. vdm2.emplace(grpc::load_reporter::kViewEndLatencyMs,
  428. ::opencensus::stats::testing::TestUtils::MakeViewData(
  429. mock_census_view_provider()->FindViewDescriptor(
  430. grpc::load_reporter::kViewEndLatencyMs),
  431. {{{kClientIp1 + kLbToken1, kHostname1, kUser1,
  432. grpc::load_reporter::kCallStatusOk},
  433. 187},
  434. {{kClientIp1 + kLbToken2, kHostname2, kUser3,
  435. grpc::load_reporter::kCallStatusClientError},
  436. 34}}));
  437. vdm2.emplace(
  438. grpc::load_reporter::kViewOtherCallMetricCount,
  439. ::opencensus::stats::testing::TestUtils::MakeViewData(
  440. mock_census_view_provider()->FindViewDescriptor(
  441. grpc::load_reporter::kViewOtherCallMetricCount),
  442. {{{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3, kMetric1}, 1},
  443. {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3, kMetric2},
  444. 1}}));
  445. vdm2.emplace(
  446. grpc::load_reporter::kViewOtherCallMetricValue,
  447. ::opencensus::stats::testing::TestUtils::MakeViewData(
  448. mock_census_view_provider()->FindViewDescriptor(
  449. grpc::load_reporter::kViewOtherCallMetricValue),
  450. {{{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3, kMetric1}, 9.6},
  451. {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3, kMetric2},
  452. 5.7}}));
  453. // Set up mock expectation.
  454. EXPECT_CALL(*mock_census_view_provider(), FetchViewData())
  455. .WillOnce(Return(vdm1))
  456. .WillOnce(Return(vdm2));
  457. PrepareCpuExpectation(2);
  458. // Start testing.
  459. load_reporter_->ReportStreamCreated(kHostname1, kLbId1, kLoadKey1);
  460. load_reporter_->ReportStreamCreated(kHostname2, kLbId2, kLoadKey2);
  461. load_reporter_->ReportStreamCreated(kHostname2, kLbId3, kLoadKey3);
  462. // First fetch.
  463. load_reporter_->FetchAndSample();
  464. load_reporter_->GenerateLoads(kHostname1, kLbId1);
  465. gpr_log(GPR_INFO, "First load generated.");
  466. // Second fetch.
  467. load_reporter_->FetchAndSample();
  468. load_reporter_->GenerateLoads(kHostname2, kLbId2);
  469. gpr_log(GPR_INFO, "Second load generated.");
  470. // TODO(juanlishen): Verify the data.
  471. }
  472. } // namespace
  473. } // namespace testing
  474. } // namespace grpc
  475. int main(int argc, char** argv) {
  476. grpc::testing::TestEnvironment env(argc, argv);
  477. ::testing::InitGoogleTest(&argc, argv);
  478. return RUN_ALL_TESTS();
  479. }