OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 // CpuInfoProvider unit tests | 5 // CpuInfoProvider unit tests |
6 | 6 |
7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
9 #include "chrome/browser/extensions/api/system_info_cpu/cpu_info_provider.h" | 9 #include "chrome/browser/extensions/api/system_info_cpu/cpu_info_provider.h" |
10 #include "content/public/test/test_browser_thread.h" | 10 #include "content/public/test/test_browser_thread.h" |
11 #include "content/public/test/test_utils.h" | 11 #include "content/public/test/test_utils.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
13 | 13 |
14 namespace extensions { | 14 namespace extensions { |
15 | 15 |
16 using api::system_info_cpu::CpuInfo; | 16 using api::system_info_cpu::CpuInfo; |
17 using api::system_info_cpu::CpuUpdateInfo; | |
18 using content::BrowserThread; | |
19 | 17 |
20 struct TestCpuInfo { | 18 struct TestCpuInfo { |
21 std::string arch_name; | 19 std::string arch_name; |
22 std::string model_name; | 20 std::string model_name; |
23 int num_of_processors; | 21 int num_of_processors; |
24 }; | 22 }; |
25 | 23 |
26 struct TestCpuTimeInfo { | |
27 int64 user; | |
28 int64 kernel; | |
29 int64 idle; | |
30 }; | |
31 | |
32 struct TestCpuUpdateInfo { | |
33 double average_usage; | |
34 std::vector<double> usage_per_processor; | |
35 }; | |
36 | |
37 const struct TestCpuInfo kTestingCpuInfoData = { | 24 const struct TestCpuInfo kTestingCpuInfoData = { |
38 "x86", "Intel Core", 2 | 25 "x86", "Intel Core", 2 |
39 }; | 26 }; |
40 | 27 |
41 const struct TestCpuTimeInfo kTestingCpuTimeDataForOneProcessor[][3] = { | |
42 {{2, 4, 5}, {5, 7, 9}, {5, 7, 9}} | |
43 }; | |
44 | |
45 const struct TestCpuTimeInfo kTestingCpuTimeDataForTwoProcessors[][3] = { | |
46 {{2, 4, 5}, {2, 4, 5}, {3, 5, 6}}, // Processor1 cpu time data | |
47 {{5, 7, 9}, {5, 7, 9}, {6, 8, 10}} // Processor2 cpu time data | |
48 }; | |
49 | |
50 // The cpu sampling interval in unittest is 1ms. | |
51 const int kWatchingIntervalMs = 1; | |
52 // The times of doing cpu sampling. | |
53 const int kSamplingTimes = 2; | |
54 // The size of cpu time data. | |
55 const int kCpuTimeDataSize = 3; | |
56 | |
57 class TestCpuInfoProvider : public CpuInfoProvider { | 28 class TestCpuInfoProvider : public CpuInfoProvider { |
58 public: | 29 public: |
59 typedef const struct TestCpuTimeInfo (* TestingCpuTimeDataPointer)[3]; | |
60 | |
61 TestCpuInfoProvider(); | 30 TestCpuInfoProvider(); |
62 TestCpuInfoProvider(int num_of_processors, | |
63 TestingCpuTimeDataPointer cpu_time_data, | |
64 size_t sampling_interval); | |
65 virtual bool QueryInfo(CpuInfo* info) OVERRIDE; | 31 virtual bool QueryInfo(CpuInfo* info) OVERRIDE; |
66 virtual bool QueryCpuTimePerProcessor(std::vector<CpuTime>* times) OVERRIDE; | |
67 | |
68 // Check whether finishing cpu sampling. | |
69 bool is_complete_sampling() { | |
70 return query_times_ >= kCpuTimeDataSize; | |
71 } | |
72 | |
73 int num_of_processors() const { | |
74 return num_of_processors_; | |
75 } | |
76 | |
77 TestingCpuTimeDataPointer cpu_time_data() const { | |
78 return cpu_time_data_; | |
79 } | |
80 | 32 |
81 private: | 33 private: |
82 virtual ~TestCpuInfoProvider(); | 34 virtual ~TestCpuInfoProvider(); |
83 | |
84 // Record the query times of cpu_time_data_. | |
85 int query_times_; | |
86 int num_of_processors_; | |
87 | |
88 // A Pointer to kTestingCpuTimeDataFor*Processors array. | |
89 TestingCpuTimeDataPointer cpu_time_data_; | |
90 }; | 35 }; |
91 | 36 |
92 TestCpuInfoProvider::TestCpuInfoProvider() | 37 TestCpuInfoProvider::TestCpuInfoProvider() {} |
93 : query_times_(0), | |
94 num_of_processors_(1), | |
95 cpu_time_data_(NULL) { | |
96 } | |
97 | |
98 TestCpuInfoProvider::TestCpuInfoProvider(int num_of_processors, | |
99 TestingCpuTimeDataPointer cpu_time_data, | |
100 size_t sampling_interval) | |
101 : query_times_(0), | |
102 num_of_processors_(num_of_processors), | |
103 cpu_time_data_(cpu_time_data) { | |
104 sampling_interval_ = sampling_interval; | |
105 } | |
106 | 38 |
107 TestCpuInfoProvider::~TestCpuInfoProvider() {} | 39 TestCpuInfoProvider::~TestCpuInfoProvider() {} |
108 | 40 |
109 bool TestCpuInfoProvider::QueryInfo(CpuInfo* info) { | 41 bool TestCpuInfoProvider::QueryInfo(CpuInfo* info) { |
110 if (info == NULL) | 42 if (info == NULL) |
111 return false; | 43 return false; |
112 info->arch_name = kTestingCpuInfoData.arch_name; | 44 info->arch_name = kTestingCpuInfoData.arch_name; |
113 info->model_name = kTestingCpuInfoData.model_name; | 45 info->model_name = kTestingCpuInfoData.model_name; |
114 info->num_of_processors = kTestingCpuInfoData.num_of_processors; | 46 info->num_of_processors = kTestingCpuInfoData.num_of_processors; |
115 return true; | 47 return true; |
116 } | 48 } |
117 | 49 |
118 bool TestCpuInfoProvider::QueryCpuTimePerProcessor( | |
119 std::vector<CpuTime>* times) { | |
120 if (is_complete_sampling()) | |
121 return false; | |
122 | |
123 std::vector<CpuTime> results; | |
124 for (int i = 0; i < num_of_processors_; ++i) { | |
125 CpuTime cpu_time; | |
126 cpu_time.user = cpu_time_data_[i][query_times_].user; | |
127 cpu_time.kernel = cpu_time_data_[i][query_times_].kernel; | |
128 cpu_time.idle = cpu_time_data_[i][query_times_].idle; | |
129 results.push_back(cpu_time); | |
130 } | |
131 ++query_times_; | |
132 times->swap(results); | |
133 | |
134 return true; | |
135 } | |
136 | |
137 class CpuInfoProviderTest : public testing::Test { | 50 class CpuInfoProviderTest : public testing::Test { |
138 public: | 51 public: |
139 CpuInfoProviderTest(); | 52 CpuInfoProviderTest(); |
140 | 53 |
141 // A callback function to be called when CpuInfoProvider completes to sample. | |
142 // Called on FILE thread. | |
143 void OnCheckCpuSamplingFinishedForTesting(scoped_ptr<CpuUpdateInfo> info); | |
144 void CalculateExpectedResult(); | |
145 void VerifyResult(); | |
146 | |
147 protected: | 54 protected: |
148 base::MessageLoop message_loop_; | |
149 content::TestBrowserThread ui_thread_; | |
150 content::TestBrowserThread file_thread_; | |
151 scoped_refptr<TestCpuInfoProvider> cpu_info_provider_; | 55 scoped_refptr<TestCpuInfoProvider> cpu_info_provider_; |
152 | |
153 // Maintain the CpuUpdateInfo results returned by DoSample function. | |
154 std::vector<TestCpuUpdateInfo> cpu_update_result_; | |
155 | |
156 // Maintain the expected CpuUpdateInfo. | |
157 std::vector<TestCpuUpdateInfo> expected_cpu_update_result_; | |
158 }; | 56 }; |
159 | 57 |
160 CpuInfoProviderTest::CpuInfoProviderTest() | 58 CpuInfoProviderTest::CpuInfoProviderTest() {} |
161 : message_loop_(base::MessageLoop::TYPE_UI), | |
162 ui_thread_(BrowserThread::UI, &message_loop_), | |
163 file_thread_(BrowserThread::FILE, &message_loop_) { | |
164 } | |
165 | |
166 void CpuInfoProviderTest::OnCheckCpuSamplingFinishedForTesting( | |
167 scoped_ptr<CpuUpdateInfo> info) { | |
168 // The cpu sampling is doing in FILE thread, so the callback function | |
169 // should be also called in FILE thread. | |
170 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
171 | |
172 // Once the sampling completed, we need to quit the FILE thread to given | |
173 // UI thread a chance to verify results. | |
174 if (cpu_info_provider_->is_complete_sampling()) { | |
175 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
176 base::MessageLoop::QuitClosure()); | |
177 } | |
178 | |
179 TestCpuUpdateInfo result; | |
180 result.average_usage = info->average_usage; | |
181 result.usage_per_processor = info->usage_per_processor; | |
182 cpu_update_result_.push_back(result); | |
183 } | |
184 | |
185 void CpuInfoProviderTest::CalculateExpectedResult() { | |
186 TestCpuInfoProvider::TestingCpuTimeDataPointer cpu_time_testing_data = | |
187 cpu_info_provider_->cpu_time_data(); | |
188 DCHECK(cpu_time_testing_data != NULL); | |
189 | |
190 int test_data_index = 0; | |
191 std::vector<TestCpuTimeInfo> baseline_cpu_time; | |
192 | |
193 for (int i = 0; i < cpu_info_provider_->num_of_processors(); ++i) | |
194 baseline_cpu_time.push_back(cpu_time_testing_data[i][0]); | |
195 ++test_data_index; | |
196 | |
197 for (int i = 0; i < kSamplingTimes; ++i) { | |
198 TestCpuUpdateInfo info; | |
199 double total_usage = 0; | |
200 std::vector<TestCpuTimeInfo> next_cpu_time; | |
201 for (int j = 0; j < cpu_info_provider_->num_of_processors(); ++j) | |
202 next_cpu_time.push_back(cpu_time_testing_data[j][test_data_index]); | |
203 | |
204 for (int j = 0; j < cpu_info_provider_->num_of_processors(); ++j) { | |
205 double toal_time = | |
206 (next_cpu_time[j].user - baseline_cpu_time[j].user) + | |
207 (next_cpu_time[j].idle - baseline_cpu_time[j].idle) + | |
208 (next_cpu_time[j].kernel - baseline_cpu_time[j].kernel); | |
209 double idle_time = next_cpu_time[j].idle - baseline_cpu_time[j].idle; | |
210 double usage = 0; | |
211 if (toal_time != 0) | |
212 usage = 100 - idle_time * 100 / toal_time; | |
213 info.usage_per_processor.push_back(usage); | |
214 total_usage += usage; | |
215 } | |
216 info.average_usage = | |
217 total_usage / cpu_info_provider_->num_of_processors(); | |
218 expected_cpu_update_result_.push_back(info); | |
219 | |
220 ++test_data_index; | |
221 baseline_cpu_time.swap(next_cpu_time); | |
222 } | |
223 } | |
224 | |
225 void CpuInfoProviderTest::VerifyResult() { | |
226 EXPECT_EQ(expected_cpu_update_result_.size(), cpu_update_result_.size()); | |
227 for (size_t i = 0; i < expected_cpu_update_result_.size(); ++i) { | |
228 EXPECT_DOUBLE_EQ(expected_cpu_update_result_[i].average_usage, | |
229 cpu_update_result_[i].average_usage); | |
230 EXPECT_EQ(expected_cpu_update_result_[i].usage_per_processor.size(), | |
231 cpu_update_result_[i].usage_per_processor.size()); | |
232 for (size_t j = 0; | |
233 j < expected_cpu_update_result_[i].usage_per_processor.size(); ++j) { | |
234 EXPECT_DOUBLE_EQ(expected_cpu_update_result_[i].usage_per_processor[j], | |
235 cpu_update_result_[i].usage_per_processor[j]); | |
236 } | |
237 } | |
238 } | |
239 | 59 |
240 TEST_F(CpuInfoProviderTest, QueryCpuInfo) { | 60 TEST_F(CpuInfoProviderTest, QueryCpuInfo) { |
241 cpu_info_provider_ = new TestCpuInfoProvider(); | 61 cpu_info_provider_ = new TestCpuInfoProvider(); |
242 scoped_ptr<CpuInfo> cpu_info(new CpuInfo()); | 62 scoped_ptr<CpuInfo> cpu_info(new CpuInfo()); |
243 EXPECT_TRUE(cpu_info_provider_->QueryInfo(cpu_info.get())); | 63 EXPECT_TRUE(cpu_info_provider_->QueryInfo(cpu_info.get())); |
244 EXPECT_EQ(kTestingCpuInfoData.arch_name, cpu_info->arch_name); | 64 EXPECT_EQ(kTestingCpuInfoData.arch_name, cpu_info->arch_name); |
245 EXPECT_EQ(kTestingCpuInfoData.model_name, cpu_info->model_name); | 65 EXPECT_EQ(kTestingCpuInfoData.model_name, cpu_info->model_name); |
246 EXPECT_EQ(kTestingCpuInfoData.num_of_processors, cpu_info->num_of_processors); | 66 EXPECT_EQ(kTestingCpuInfoData.num_of_processors, cpu_info->num_of_processors); |
247 } | 67 } |
248 | 68 |
249 TEST_F(CpuInfoProviderTest, DoOnlyOneProcessorCpuSampling) { | |
250 cpu_info_provider_ = | |
251 new TestCpuInfoProvider(1, // number of processors | |
252 kTestingCpuTimeDataForOneProcessor, | |
253 kWatchingIntervalMs); | |
254 CalculateExpectedResult(); | |
255 cpu_info_provider_->StartSampling( | |
256 base::Bind(&CpuInfoProviderTest::OnCheckCpuSamplingFinishedForTesting, | |
257 base::Unretained(this))); | |
258 content::RunAllPendingInMessageLoop(content::BrowserThread::FILE); | |
259 content::RunMessageLoop(); | |
260 cpu_info_provider_->StopSampling(); | |
261 content::RunAllPendingInMessageLoop(content::BrowserThread::FILE); | |
262 VerifyResult(); | |
263 } | 69 } |
264 | |
265 TEST_F(CpuInfoProviderTest, DoTwoProcessorsCpuSampling) { | |
266 cpu_info_provider_ = | |
267 new TestCpuInfoProvider(2, // number of processors | |
268 kTestingCpuTimeDataForTwoProcessors, | |
269 kWatchingIntervalMs); | |
270 CalculateExpectedResult(); | |
271 | |
272 cpu_info_provider_->StartSampling( | |
273 base::Bind(&CpuInfoProviderTest::OnCheckCpuSamplingFinishedForTesting, | |
274 base::Unretained(this))); | |
275 content::RunAllPendingInMessageLoop(content::BrowserThread::FILE); | |
276 content::RunMessageLoop(); | |
277 cpu_info_provider_->StopSampling(); | |
278 content::RunAllPendingInMessageLoop(content::BrowserThread::FILE); | |
279 VerifyResult(); | |
280 } | |
281 | |
282 } | |
OLD | NEW |