18 #include <gtest/gtest.h>
19 #include <boost/bind.hpp>
20 #include <boost/foreach.hpp>
32 TEST(CountersTest, Basic) {
38 TRuntimeProfileTree thrift_profile;
44 profile_a.
ToThrift(&thrift_profile.nodes);
45 EXPECT_EQ(thrift_profile.nodes.size(), 3);
46 thrift_profile.nodes.clear();
53 counter_a = profile_a.
AddCounter(
"A", TUnit::UNIT);
54 EXPECT_TRUE(counter_a != NULL);
57 EXPECT_EQ(counter_a->
value(), 5);
59 EXPECT_EQ(counter_a->
value(), 1);
61 counter_b = profile_a2.
AddCounter(
"B", TUnit::BYTES);
62 EXPECT_TRUE(counter_b != NULL);
65 profile_a.
ToThrift(&thrift_profile.nodes);
68 EXPECT_EQ(counter_merged->
value(), 1);
69 EXPECT_TRUE(from_thrift->
GetCounter(
"Not there") == NULL);
73 averaged_profile.UpdateAverage(from_thrift);
74 counter_merged = averaged_profile.GetCounter(
"A");
75 EXPECT_EQ(counter_merged->
value(), 1);
78 averaged_profile.UpdateAverage(from_thrift);
79 EXPECT_EQ(counter_merged->
value(), 1);
81 counter_a = profile_a2.
AddCounter(
"A", TUnit::UNIT);
83 averaged_profile.UpdateAverage(&profile_a2);
84 EXPECT_EQ(counter_merged->
value(), 2);
88 updated_profile.Update(thrift_profile);
90 EXPECT_EQ(counter_updated->
value(), 1);
93 updated_profile.Update(thrift_profile);
94 updated_profile.Update(thrift_profile);
95 EXPECT_EQ(counter_updated->
value(), 1);
100 EXPECT_TRUE(counter != NULL);
101 EXPECT_EQ(counter->
value(), value);
104 TEST(CountersTest, MergeAndUpdate) {
124 profile1.
AddCounter(
"Parent Shared", TUnit::UNIT);
126 profile2.
AddCounter(
"Parent Shared", TUnit::UNIT);
128 profile1.
AddCounter(
"Parent 1 Only", TUnit::UNIT);
130 profile2.
AddCounter(
"Parent 2 Only", TUnit::UNIT);
131 parent1_shared->
Add(1);
132 parent2_shared->
Add(3);
133 parent1_only->
Add(2);
134 parent2_only->
Add(5);
138 p1_child1.
AddCounter(
"Child1 Shared", TUnit::UNIT);
140 p1_child1.
AddCounter(
"Child1 Parent 1 Only", TUnit::UNIT);
144 p2_child1.
AddCounter(
"Child1 Shared", TUnit::UNIT);
146 p1_child1.
AddCounter(
"Child1 Parent 2 Only", TUnit::UNIT);
149 p1_c1_shared->
Add(10);
151 p2_c1_shared->
Add(20);
152 p2_c1_only->
Add(100);
157 TRuntimeProfileTree tprofile1;
167 vector<RuntimeProfile*> children;
169 EXPECT_EQ(children.size(), 3);
171 for (
int i = 0; i < 3; ++i) {
173 if (profile->
name().compare(
"Child1") == 0) {
178 }
else if (profile->
name().compare(
"Child2") == 0) {
181 }
else if (profile->
name().compare(
"Child3") == 0) {
194 profile2.
Update(tprofile1);
201 EXPECT_EQ(children.size(), 3);
203 for (
int i = 0; i < 3; ++i) {
205 if (profile->
name().compare(
"Child1") == 0) {
210 }
else if (profile->
name().compare(
"Child2") == 0) {
213 }
else if (profile->
name().compare(
"Child3") == 0) {
225 TEST(CountersTest, DerivedCounters) {
233 ticks_counter->
Set(1000L * 1000L * 1000L);
239 bytes_counter->
Set(10L);
240 EXPECT_EQ(throughput_counter->
value(), 10);
241 bytes_counter->
Set(20L);
242 EXPECT_EQ(throughput_counter->
value(), 20);
243 ticks_counter->
Set(ticks_counter->
value() / 2);
244 EXPECT_EQ(throughput_counter->
value(), 40);
247 TEST(CountersTest, AverageSetCounters) {
255 bytes_1_counter->
Set(10L);
259 EXPECT_EQ(bytes_avg.
value(), 10L);
260 bytes_1_counter->
Set(20L);
263 EXPECT_EQ(bytes_avg.
value(), 20L);
264 bytes_2_counter->
Set(40L);
267 EXPECT_EQ(bytes_avg.
value(), 30L);
268 bytes_2_counter->
Set(30L);
271 EXPECT_EQ(bytes_avg.
value(), 25L);
274 profile.
AddCounter(
"double 1", TUnit::DOUBLE_VALUE);
276 profile.
AddCounter(
"double 2", TUnit::DOUBLE_VALUE);
277 double_1_counter->
Set(1.0f);
282 double_1_counter->Set(2.0f);
286 double_2_counter->
Set(4.0f);
290 double_2_counter->
Set(3.0f);
296 TEST(CountersTest, InfoStringTest) {
303 EXPECT_TRUE(value != NULL);
304 EXPECT_EQ(*value,
"Value");
307 TRuntimeProfileTree tprofile;
314 EXPECT_TRUE(value != NULL);
315 EXPECT_EQ(*value,
"Value");
319 update_dst_profile.
Update(tprofile);
321 EXPECT_TRUE(value != NULL);
322 EXPECT_EQ(*value,
"Value");
332 update_dst_profile.
Update(tprofile);
333 EXPECT_EQ(*update_dst_profile.
GetInfoString(
"Key"),
"NewValue");
337 TEST(CountersTest, RateCounters) {
346 EXPECT_TRUE(rate_counter->
unit() == TUnit::BYTES_PER_SECOND);
348 EXPECT_EQ(rate_counter->
value(), 0);
350 bytes_counter->
Set(100L * 1024L * 1024L);
355 int64_t rate = rate_counter->
value();
362 EXPECT_GT(rate, 66 * 1024 * 1024);
363 EXPECT_LE(rate, 200 * 1024 * 1024);
369 rate = rate_counter->
value();
370 EXPECT_GT(rate, 66 * 1024 * 1024);
371 EXPECT_LE(rate, 200 * 1024 * 1024);
374 TEST(CountersTest, BucketCounters) {
382 unit_counter->
Set(1L);
385 vector<RuntimeProfile::Counter*> buckets;
398 double val0 = buckets[0]->double_value();
399 double val1 = buckets[1]->double_value();
401 EXPECT_EQ(100, val1);
406 EXPECT_EQ(val0, buckets[0]->double_value());
407 EXPECT_EQ(val1, buckets[1]->double_value());
410 TEST(CountersTest, EventSequences) {
418 vector<RuntimeProfile::EventSequence::Event>
events;
420 EXPECT_EQ(3, events.size());
423 string last_string =
"";
425 EXPECT_TRUE(ev.second >= last_timestamp);
426 last_timestamp = ev.second;
427 EXPECT_TRUE(ev.first > last_string);
428 last_string = ev.first;
431 TRuntimeProfileTree thrift_profile;
433 EXPECT_TRUE(thrift_profile.nodes[0].__isset.event_sequences);
434 EXPECT_EQ(1, thrift_profile.nodes[0].event_sequences.size());
441 EXPECT_EQ(NULL, reconstructed_profile->GetEventSequence(
"doesn't exist"));
442 seq = reconstructed_profile->GetEventSequence(
"event sequence");
443 EXPECT_TRUE(seq != NULL);
444 seq->GetEvents(&events);
445 EXPECT_EQ(3, events.size());
447 EXPECT_TRUE(ev.second >= last_timestamp);
448 last_timestamp = ev.second;
449 EXPECT_TRUE(ev.first > last_string);
450 last_string = ev.first;
455 int expected_period,
int expected_delta) {
456 const int* samples = NULL;
460 samples = sampler.
GetSamples(&num_samples, &period);
461 EXPECT_TRUE(samples != NULL);
462 EXPECT_EQ(num_samples, expected_num);
463 EXPECT_EQ(period, expected_period);
465 for (
int i = 0; i < expected_num - 1; ++i) {
466 EXPECT_EQ(samples[i] + expected_delta, samples[i + 1]) << i;
474 for (
int i = 0; i < 3; ++i) {
479 for (
int i = 0; i < 3; ++i) {
484 for (
int i = 0; i < 3; ++i) {
490 for (
int i = 0; i < 3; ++i) {
496 for (
int i = 0; i < 3; ++i) {
504 int main(
int argc,
char **argv) {
505 ::testing::InitGoogleTest(&argc, argv);
508 return RUN_ALL_TESTS();
Counter * AddCounter(const std::string &name, TUnit::type unit, const std::string &parent_counter_name="")
virtual int64_t value() const
void GetEvents(std::vector< Event > *events)
DerivedCounter * AddDerivedCounter(const std::string &name, TUnit::type unit, const DerivedCounterFunction &counter_fn, const std::string &parent_counter_name="")
EventSequence * AddEventSequence(const std::string &key)
virtual double double_value() const
void AddInfoString(const std::string &key, const std::string &value)
client RuntimeProfile::EventSequence * events
static RuntimeProfile * CreateFromThrift(ObjectPool *pool, const TRuntimeProfileTree &profiles)
Deserialize from thrift. Runtime profiles are allocated from the pool.
std::pair< std::string, int64_t > Event
An Event is a <label, timestamp> pair.
void RegisterBucketingCounters(Counter *src_counter, std::vector< Counter * > *buckets)
Counter * AddRateCounter(const std::string &name, Counter *src_counter)
static int64_t UnitsPerSecond(const Counter *total_counter, const Counter *timer)
Derived counter function: return measured throughput as input_value/second.
int num_counters() const
Returns the number of counters in this profile.
void ValidateCounter(RuntimeProfile *profile, const string &name, int64_t value)
void UpdateCounter(Counter *new_counter)
virtual void Set(int64_t value)
void UpdateAverage(RuntimeProfile *src)
void MarkEvent(const std::string &label)
static void StopBucketingCounters(std::vector< RuntimeProfile::Counter * > *buckets, bool convert)
int main(int argc, char **argv)
void InitThreading()
Initialises the threading subsystem. Must be called before a Thread is created.
virtual int64_t value() const
static void StopRateCounter(RuntimeProfile::Counter *counter)
Stops updating the value of 'counter'.
const T * GetSamples(int *num_samples, int *period, SpinLock **lock=NULL) const
void Update(const TRuntimeProfileTree &thrift_profile)
Counter * GetCounter(const std::string &name)
void PrettyPrint(std::ostream *s, const std::string &prefix="") const
static void Init()
Initialize CpuInfo.
void AddSample(T sample, int ms)
virtual void Add(int64_t delta)
void AddChild(RuntimeProfile *child, bool indent=true, RuntimeProfile *location=NULL)
const std::string & name() const
Returns name of this profile.
const std::string * GetInfoString(const std::string &key) const
void GetChildren(std::vector< RuntimeProfile * > *children)
void ToThrift(TRuntimeProfileTree *tree) const
void ValidateSampler(const StreamingSampler< int, 10 > &sampler, int expected_num, int expected_period, int expected_delta)