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