| OLD | NEW | 
|    1 // Copyright 2015 The Chromium Authors. All rights reserved. |    1 // Copyright 2015 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "components/metrics/call_stack_profile_metrics_provider.h" |    5 #include "components/metrics/call_stack_profile_metrics_provider.h" | 
|    6  |    6  | 
|    7 #include <stddef.h> |    7 #include <stddef.h> | 
|    8 #include <stdint.h> |    8 #include <stdint.h> | 
|    9  |    9  | 
|   10 #include <utility> |   10 #include <utility> | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
|   34   uint64_t name_md5; |   34   uint64_t name_md5; | 
|   35   uint64_t base_address; |   35   uint64_t base_address; | 
|   36 }; |   36 }; | 
|   37  |   37  | 
|   38 struct ExpectedProtoEntry { |   38 struct ExpectedProtoEntry { | 
|   39   int32_t module_index; |   39   int32_t module_index; | 
|   40   uint64_t address; |   40   uint64_t address; | 
|   41 }; |   41 }; | 
|   42  |   42  | 
|   43 struct ExpectedProtoSample { |   43 struct ExpectedProtoSample { | 
|   44   uint32_t process_phases;  // Bit-field of expected phases. |   44   uint32_t process_milestones;  // Bit-field of expected milestones. | 
|   45   const ExpectedProtoEntry* entries; |   45   const ExpectedProtoEntry* entries; | 
|   46   int entry_count; |   46   int entry_count; | 
|   47   int64_t entry_repeats; |   47   int64_t entry_repeats; | 
|   48 }; |   48 }; | 
|   49  |   49  | 
|   50 struct ExpectedProtoProfile { |   50 struct ExpectedProtoProfile { | 
|   51   int32_t duration_ms; |   51   int32_t duration_ms; | 
|   52   int32_t period_ms; |   52   int32_t period_ms; | 
|   53   const ExpectedProtoModule* modules; |   53   const ExpectedProtoModule* modules; | 
|   54   int module_count; |   54   int module_count; | 
|   55   const ExpectedProtoSample* samples; |   55   const ExpectedProtoSample* samples; | 
|   56   int sample_count; |   56   int sample_count; | 
|   57 }; |   57 }; | 
|   58  |   58  | 
|   59 class ProfilesFactory { |   59 class ProfilesFactory { | 
|   60  public: |   60  public: | 
|   61   ProfilesFactory(){}; |   61   ProfilesFactory(){}; | 
|   62   ~ProfilesFactory(){}; |   62   ~ProfilesFactory(){}; | 
|   63  |   63  | 
|   64   ProfilesFactory& AddPhase(int phase); |   64   ProfilesFactory& AddMilestone(int milestone); | 
|   65   ProfilesFactory& NewProfile(int duration_ms, int interval_ms); |   65   ProfilesFactory& NewProfile(int duration_ms, int interval_ms); | 
|   66   ProfilesFactory& NewSample(); |   66   ProfilesFactory& NewSample(); | 
|   67   ProfilesFactory& AddFrame(size_t module, uintptr_t offset); |   67   ProfilesFactory& AddFrame(size_t module, uintptr_t offset); | 
|   68   ProfilesFactory& DefineModule(const char* name, |   68   ProfilesFactory& DefineModule(const char* name, | 
|   69                                 const base::FilePath& path, |   69                                 const base::FilePath& path, | 
|   70                                 uintptr_t base); |   70                                 uintptr_t base); | 
|   71  |   71  | 
|   72   Profiles Build(); |   72   Profiles Build(); | 
|   73  |   73  | 
|   74  private: |   74  private: | 
|   75   Profiles profiles_; |   75   Profiles profiles_; | 
|   76   uint32_t process_phases_ = 0; |   76   uint32_t process_milestones_ = 0; | 
|   77  |   77  | 
|   78   DISALLOW_COPY_AND_ASSIGN(ProfilesFactory); |   78   DISALLOW_COPY_AND_ASSIGN(ProfilesFactory); | 
|   79 }; |   79 }; | 
|   80  |   80  | 
|   81 ProfilesFactory& ProfilesFactory::AddPhase(int phase) { |   81 ProfilesFactory& ProfilesFactory::AddMilestone(int milestone) { | 
|   82   process_phases_ |= 1 << phase; |   82   process_milestones_ |= 1 << milestone; | 
|   83   return *this; |   83   return *this; | 
|   84 } |   84 } | 
|   85  |   85  | 
|   86 ProfilesFactory& ProfilesFactory::NewProfile(int duration_ms, int interval_ms) { |   86 ProfilesFactory& ProfilesFactory::NewProfile(int duration_ms, int interval_ms) { | 
|   87   profiles_.push_back(Profile()); |   87   profiles_.push_back(Profile()); | 
|   88   Profile* profile = &profiles_.back(); |   88   Profile* profile = &profiles_.back(); | 
|   89   profile->profile_duration = base::TimeDelta::FromMilliseconds(duration_ms); |   89   profile->profile_duration = base::TimeDelta::FromMilliseconds(duration_ms); | 
|   90   profile->sampling_period = base::TimeDelta::FromMilliseconds(interval_ms); |   90   profile->sampling_period = base::TimeDelta::FromMilliseconds(interval_ms); | 
|   91   return *this; |   91   return *this; | 
|   92 } |   92 } | 
|   93  |   93  | 
|   94 ProfilesFactory& ProfilesFactory::NewSample() { |   94 ProfilesFactory& ProfilesFactory::NewSample() { | 
|   95   profiles_.back().samples.push_back(Sample()); |   95   profiles_.back().samples.push_back(Sample()); | 
|   96   profiles_.back().samples.back().process_phases = process_phases_; |   96   profiles_.back().samples.back().process_milestones = process_milestones_; | 
|   97   return *this; |   97   return *this; | 
|   98 } |   98 } | 
|   99  |   99  | 
|  100 ProfilesFactory& ProfilesFactory::AddFrame(size_t module, uintptr_t offset) { |  100 ProfilesFactory& ProfilesFactory::AddFrame(size_t module, uintptr_t offset) { | 
|  101   profiles_.back().samples.back().frames.push_back(Frame(offset, module)); |  101   profiles_.back().samples.back().frames.push_back(Frame(offset, module)); | 
|  102   return *this; |  102   return *this; | 
|  103 } |  103 } | 
|  104  |  104  | 
|  105 ProfilesFactory& ProfilesFactory::DefineModule(const char* name, |  105 ProfilesFactory& ProfilesFactory::DefineModule(const char* name, | 
|  106                                                const base::FilePath& path, |  106                                                const base::FilePath& path, | 
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  174     EXPECT_EQ(expected.modules[m].build_id, module_id.build_id()); |  174     EXPECT_EQ(expected.modules[m].build_id, module_id.build_id()); | 
|  175     ASSERT_TRUE(module_id.has_name_md5_prefix()); |  175     ASSERT_TRUE(module_id.has_name_md5_prefix()); | 
|  176     EXPECT_EQ(expected.modules[m].name_md5, module_id.name_md5_prefix()); |  176     EXPECT_EQ(expected.modules[m].name_md5, module_id.name_md5_prefix()); | 
|  177   } |  177   } | 
|  178  |  178  | 
|  179   ASSERT_EQ(expected.sample_count, stack.sample().size()); |  179   ASSERT_EQ(expected.sample_count, stack.sample().size()); | 
|  180   for (int s = 0; s < expected.sample_count; ++s) { |  180   for (int s = 0; s < expected.sample_count; ++s) { | 
|  181     SCOPED_TRACE("sample " + base::IntToString(s)); |  181     SCOPED_TRACE("sample " + base::IntToString(s)); | 
|  182     const CallStackProfile::Sample& proto_sample = stack.sample().Get(s); |  182     const CallStackProfile::Sample& proto_sample = stack.sample().Get(s); | 
|  183  |  183  | 
|  184     uint32_t process_phases = 0; |  184     uint32_t process_milestones = 0; | 
|  185     for (int i = 0; i < proto_sample.process_phase().size(); ++i) |  185     for (int i = 0; i < proto_sample.process_phase().size(); ++i) | 
|  186       process_phases |= 1U << proto_sample.process_phase().Get(i); |  186       process_milestones |= 1U << proto_sample.process_phase().Get(i); | 
|  187     EXPECT_EQ(expected.samples[s].process_phases, process_phases); |  187     EXPECT_EQ(expected.samples[s].process_milestones, process_milestones); | 
|  188  |  188  | 
|  189     ASSERT_EQ(expected.samples[s].entry_count, proto_sample.entry().size()); |  189     ASSERT_EQ(expected.samples[s].entry_count, proto_sample.entry().size()); | 
|  190     ASSERT_TRUE(proto_sample.has_count()); |  190     ASSERT_TRUE(proto_sample.has_count()); | 
|  191     EXPECT_EQ(expected.samples[s].entry_repeats, proto_sample.count()); |  191     EXPECT_EQ(expected.samples[s].entry_repeats, proto_sample.count()); | 
|  192     for (int e = 0; e < expected.samples[s].entry_count; ++e) { |  192     for (int e = 0; e < expected.samples[s].entry_count; ++e) { | 
|  193       SCOPED_TRACE("entry " + base::SizeTToString(e)); |  193       SCOPED_TRACE("entry " + base::SizeTToString(e)); | 
|  194       const CallStackProfile::Entry& entry = proto_sample.entry().Get(e); |  194       const CallStackProfile::Entry& entry = proto_sample.entry().Get(e); | 
|  195       if (expected.samples[s].entries[e].module_index >= 0) { |  195       if (expected.samples[s].entries[e].module_index >= 0) { | 
|  196         ASSERT_TRUE(entry.has_module_id_index()); |  196         ASSERT_TRUE(entry.has_module_id_index()); | 
|  197         EXPECT_EQ(expected.samples[s].entries[e].module_index, |  197         EXPECT_EQ(expected.samples[s].entries[e].module_index, | 
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  372   base::FilePath module_path(L"c:\\some\\path\\to\\chrome.exe"); |  372   base::FilePath module_path(L"c:\\some\\path\\to\\chrome.exe"); | 
|  373 #else |  373 #else | 
|  374   uint64_t module_md5 = 0x554838A8451AC36CULL; |  374   uint64_t module_md5 = 0x554838A8451AC36CULL; | 
|  375   base::FilePath module_path("/some/path/to/chrome"); |  375   base::FilePath module_path("/some/path/to/chrome"); | 
|  376 #endif |  376 #endif | 
|  377  |  377  | 
|  378   Profiles profiles = ProfilesFactory() |  378   Profiles profiles = ProfilesFactory() | 
|  379       .NewProfile(100, 10) |  379       .NewProfile(100, 10) | 
|  380       .DefineModule(module_name, module_path, module_base_address) |  380       .DefineModule(module_name, module_path, module_base_address) | 
|  381  |  381  | 
|  382       .AddPhase(0) |  382       .AddMilestone(0) | 
|  383       .NewSample() |  383       .NewSample() | 
|  384       .AddFrame(0, module_base_address + 0x10) |  384       .AddFrame(0, module_base_address + 0x10) | 
|  385       .NewSample() |  385       .NewSample() | 
|  386       .AddFrame(0, module_base_address + 0x20) |  386       .AddFrame(0, module_base_address + 0x20) | 
|  387       .NewSample() |  387       .NewSample() | 
|  388       .AddFrame(0, module_base_address + 0x10) |  388       .AddFrame(0, module_base_address + 0x10) | 
|  389       .NewSample() |  389       .NewSample() | 
|  390       .AddFrame(0, module_base_address + 0x10) |  390       .AddFrame(0, module_base_address + 0x10) | 
|  391  |  391  | 
|  392       .AddPhase(1) |  392       .AddMilestone(1) | 
|  393       .NewSample() |  393       .NewSample() | 
|  394       .AddFrame(0, module_base_address + 0x10) |  394       .AddFrame(0, module_base_address + 0x10) | 
|  395       .NewSample() |  395       .NewSample() | 
|  396       .AddFrame(0, module_base_address + 0x20) |  396       .AddFrame(0, module_base_address + 0x20) | 
|  397       .NewSample() |  397       .NewSample() | 
|  398       .AddFrame(0, module_base_address + 0x10) |  398       .AddFrame(0, module_base_address + 0x10) | 
|  399       .NewSample() |  399       .NewSample() | 
|  400       .AddFrame(0, module_base_address + 0x10) |  400       .AddFrame(0, module_base_address + 0x10) | 
|  401  |  401  | 
|  402       .Build(); |  402       .Build(); | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  457   base::FilePath module_path(L"c:\\some\\path\\to\\chrome.exe"); |  457   base::FilePath module_path(L"c:\\some\\path\\to\\chrome.exe"); | 
|  458 #else |  458 #else | 
|  459   uint64_t module_md5 = 0x554838A8451AC36CULL; |  459   uint64_t module_md5 = 0x554838A8451AC36CULL; | 
|  460   base::FilePath module_path("/some/path/to/chrome"); |  460   base::FilePath module_path("/some/path/to/chrome"); | 
|  461 #endif |  461 #endif | 
|  462  |  462  | 
|  463   Profiles profiles = ProfilesFactory() |  463   Profiles profiles = ProfilesFactory() | 
|  464       .NewProfile(100, 10) |  464       .NewProfile(100, 10) | 
|  465       .DefineModule(module_name, module_path, module_base_address) |  465       .DefineModule(module_name, module_path, module_base_address) | 
|  466  |  466  | 
|  467       .AddPhase(0) |  467       .AddMilestone(0) | 
|  468       .NewSample() |  468       .NewSample() | 
|  469       .AddFrame(0, module_base_address + 0x10) |  469       .AddFrame(0, module_base_address + 0x10) | 
|  470       .NewSample() |  470       .NewSample() | 
|  471       .AddFrame(0, module_base_address + 0x20) |  471       .AddFrame(0, module_base_address + 0x20) | 
|  472       .NewSample() |  472       .NewSample() | 
|  473       .AddFrame(0, module_base_address + 0x10) |  473       .AddFrame(0, module_base_address + 0x10) | 
|  474       .NewSample() |  474       .NewSample() | 
|  475       .AddFrame(0, module_base_address + 0x10) |  475       .AddFrame(0, module_base_address + 0x10) | 
|  476  |  476  | 
|  477       .AddPhase(1) |  477       .AddMilestone(1) | 
|  478       .NewSample() |  478       .NewSample() | 
|  479       .AddFrame(0, module_base_address + 0x10) |  479       .AddFrame(0, module_base_address + 0x10) | 
|  480       .NewSample() |  480       .NewSample() | 
|  481       .AddFrame(0, module_base_address + 0x20) |  481       .AddFrame(0, module_base_address + 0x20) | 
|  482       .NewSample() |  482       .NewSample() | 
|  483       .AddFrame(0, module_base_address + 0x10) |  483       .AddFrame(0, module_base_address + 0x10) | 
|  484       .NewSample() |  484       .NewSample() | 
|  485       .AddFrame(0, module_base_address + 0x10) |  485       .AddFrame(0, module_base_address + 0x10) | 
|  486  |  486  | 
|  487       .Build(); |  487       .Build(); | 
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  737       .AddFrame(Frame::kUnknownModuleIndex, 0x1234) |  737       .AddFrame(Frame::kUnknownModuleIndex, 0x1234) | 
|  738       .Build(); |  738       .Build(); | 
|  739   callback.Run(std::move(profiles)); |  739   callback.Run(std::move(profiles)); | 
|  740   ChromeUserMetricsExtension uma_proto; |  740   ChromeUserMetricsExtension uma_proto; | 
|  741   provider.ProvideGeneralMetrics(&uma_proto); |  741   provider.ProvideGeneralMetrics(&uma_proto); | 
|  742  |  742  | 
|  743   EXPECT_EQ(0, uma_proto.sampled_profile_size()); |  743   EXPECT_EQ(0, uma_proto.sampled_profile_size()); | 
|  744 } |  744 } | 
|  745  |  745  | 
|  746 }  // namespace metrics |  746 }  // namespace metrics | 
| OLD | NEW |