Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/trace_event/trace_event.h" | 5 #include "base/trace_event/trace_event.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 | 10 |
| (...skipping 1147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1158 TraceLog::GetInstance()->AddEnabledStateObserver(&observer); | 1158 TraceLog::GetInstance()->AddEnabledStateObserver(&observer); |
| 1159 EXPECT_EQ(1u, TraceLog::GetInstance()->GetObserverCountForTest()); | 1159 EXPECT_EQ(1u, TraceLog::GetInstance()->GetObserverCountForTest()); |
| 1160 | 1160 |
| 1161 TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""), | 1161 TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""), |
| 1162 TraceLog::RECORDING_MODE); | 1162 TraceLog::RECORDING_MODE); |
| 1163 TraceLog::GetInstance()->SetDisabled(); | 1163 TraceLog::GetInstance()->SetDisabled(); |
| 1164 // The observer removed itself on disable. | 1164 // The observer removed itself on disable. |
| 1165 EXPECT_EQ(0u, TraceLog::GetInstance()->GetObserverCountForTest()); | 1165 EXPECT_EQ(0u, TraceLog::GetInstance()->GetObserverCountForTest()); |
| 1166 } | 1166 } |
| 1167 | 1167 |
| 1168 // A helper class for synchronous manipulation of an AsyncObserver object in | |
| 1169 // another thread. | |
| 1170 // AsyncObserver must be a subclass of TraceLog::AsyncEnabledStateObserver | |
| 1171 // with a GetWeakPtr() member function returning a WeakPtr of itself. | |
| 1172 template <typename AsyncObserver> | |
| 1173 class AsyncTraceEventHelper { | |
| 1174 public: | |
| 1175 AsyncTraceEventHelper() | |
| 1176 : thread_("Owner of observer"), | |
| 1177 observer_(nullptr), | |
| 1178 async_indicator_(false), | |
| 1179 cv_(&lock_) { | |
| 1180 CHECK(thread_.Start()); | |
| 1181 CHECK(thread_.message_loop()); | |
| 1182 PerformRemoteTask(&AsyncTraceEventHelper::CreateObserver); | |
| 1183 } | |
| 1184 | |
| 1185 ~AsyncTraceEventHelper() { | |
| 1186 PerformRemoteTask(&AsyncTraceEventHelper::DestroyObserver); | |
| 1187 } | |
| 1188 | |
| 1189 void PerformRemoteTask(void (AsyncTraceEventHelper::*task)(void)) { | |
| 1190 AutoLock lock(lock_); | |
| 1191 async_indicator_ = false; | |
| 1192 thread_.task_runner()->PostTask( | |
| 1193 FROM_HERE, Bind(&AsyncTraceEventHelper::RemoteTaskWrapper, | |
| 1194 Unretained(this), task)); | |
| 1195 while (!async_indicator_) | |
|
Primiano Tucci (use gerrit)
2016/05/10 14:20:26
hmm don't do this, I think that if this is not vol
| |
| 1196 cv_.Wait(); | |
| 1197 } | |
| 1198 | |
| 1199 void RemoteTaskWrapper(void (AsyncTraceEventHelper::*task)(void)) { | |
| 1200 AutoLock lock(lock_); | |
| 1201 (this->*task)(); | |
| 1202 async_indicator_ = true; | |
| 1203 cv_.Signal(); | |
| 1204 } | |
| 1205 | |
| 1206 AsyncObserver* observer() { return observer_; } | |
| 1207 | |
| 1208 void Nop() {} | |
| 1209 void CreateObserver() { observer_ = new AsyncObserver; } | |
| 1210 void DestroyObserver() { delete observer_; } | |
| 1211 void AddObserverToTraceLog() { | |
| 1212 TraceLog::GetInstance()->AddAsyncEnabledStateObserver( | |
| 1213 observer_->GetWeakPtr()); | |
| 1214 } | |
| 1215 void RemoveObserverFromTraceLog() { | |
| 1216 TraceLog::GetInstance()->RemoveAsyncEnabledStateObserver(observer_); | |
| 1217 } | |
| 1218 | |
| 1219 private: | |
| 1220 Thread thread_; | |
| 1221 AsyncObserver* observer_; // Owned, managed remotely and manually in thread_. | |
| 1222 | |
| 1223 bool async_indicator_; | |
| 1224 Lock lock_; | |
| 1225 ConditionVariable cv_; | |
| 1226 }; | |
| 1227 | |
| 1228 class MockAsyncEnabledStateChangedObserver | |
| 1229 : public TraceLog::AsyncEnabledStateObserver { | |
| 1230 public: | |
| 1231 MOCK_METHOD0(OnTraceLogEnabled, void()); | |
| 1232 MOCK_METHOD0(OnTraceLogDisabled, void()); | |
| 1233 MockAsyncEnabledStateChangedObserver() : weak_factory_(this) {} | |
| 1234 WeakPtr<MockAsyncEnabledStateChangedObserver> GetWeakPtr() { | |
| 1235 return weak_factory_.GetWeakPtr(); | |
| 1236 } | |
| 1237 | |
| 1238 private: | |
| 1239 WeakPtrFactory<MockAsyncEnabledStateChangedObserver> weak_factory_; | |
| 1240 | |
| 1241 DISALLOW_COPY_AND_ASSIGN(MockAsyncEnabledStateChangedObserver); | |
| 1242 }; | |
| 1243 | |
| 1244 TEST_F(TraceEventTestFixture, AsyncEnabledObserverFiresOnEnable) { | |
| 1245 typedef AsyncTraceEventHelper<MockAsyncEnabledStateChangedObserver> Helper; | |
| 1246 Helper helper; | |
| 1247 helper.PerformRemoteTask(&Helper::AddObserverToTraceLog); | |
| 1248 | |
| 1249 EXPECT_CALL(*helper.observer(), OnTraceLogEnabled()).Times(1); | |
| 1250 TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""), | |
| 1251 TraceLog::RECORDING_MODE); | |
| 1252 helper.PerformRemoteTask(&Helper::Nop); | |
| 1253 testing::Mock::VerifyAndClear(helper.observer()); | |
| 1254 EXPECT_TRUE(TraceLog::GetInstance()->IsEnabled()); | |
| 1255 | |
| 1256 // Cleanup. | |
| 1257 helper.PerformRemoteTask(&Helper::RemoveObserverFromTraceLog); | |
| 1258 TraceLog::GetInstance()->SetDisabled(); | |
| 1259 } | |
| 1260 | |
| 1261 TEST_F(TraceEventTestFixture, AsyncEnabledObserverDoesntFireOnSecondEnable) { | |
| 1262 TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""), | |
| 1263 TraceLog::RECORDING_MODE); | |
| 1264 | |
| 1265 typedef AsyncTraceEventHelper< | |
| 1266 testing::StrictMock<MockAsyncEnabledStateChangedObserver>> | |
| 1267 Helper; | |
| 1268 Helper helper; | |
| 1269 helper.PerformRemoteTask(&Helper::AddObserverToTraceLog); | |
| 1270 | |
| 1271 EXPECT_CALL(*helper.observer(), OnTraceLogEnabled()).Times(0); | |
| 1272 EXPECT_CALL(*helper.observer(), OnTraceLogDisabled()).Times(0); | |
| 1273 TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""), | |
| 1274 TraceLog::RECORDING_MODE); | |
| 1275 helper.PerformRemoteTask(&Helper::Nop); | |
| 1276 testing::Mock::VerifyAndClear(helper.observer()); | |
| 1277 EXPECT_TRUE(TraceLog::GetInstance()->IsEnabled()); | |
| 1278 | |
| 1279 // Cleanup. | |
| 1280 helper.PerformRemoteTask(&Helper::RemoveObserverFromTraceLog); | |
| 1281 TraceLog::GetInstance()->SetDisabled(); | |
| 1282 TraceLog::GetInstance()->SetDisabled(); | |
| 1283 } | |
| 1284 | |
| 1285 TEST_F(TraceEventTestFixture, AsyncEnabledObserverFiresOnFirstDisable) { | |
| 1286 TraceConfig tc_inc_all("*", ""); | |
| 1287 TraceLog::GetInstance()->SetEnabled(tc_inc_all, TraceLog::RECORDING_MODE); | |
| 1288 TraceLog::GetInstance()->SetEnabled(tc_inc_all, TraceLog::RECORDING_MODE); | |
| 1289 | |
| 1290 typedef AsyncTraceEventHelper< | |
| 1291 testing::StrictMock<MockAsyncEnabledStateChangedObserver>> | |
| 1292 Helper; | |
| 1293 Helper helper; | |
| 1294 helper.PerformRemoteTask(&Helper::AddObserverToTraceLog); | |
| 1295 | |
| 1296 EXPECT_CALL(*helper.observer(), OnTraceLogEnabled()).Times(0); | |
| 1297 EXPECT_CALL(*helper.observer(), OnTraceLogDisabled()).Times(1); | |
| 1298 TraceLog::GetInstance()->SetDisabled(); | |
| 1299 helper.PerformRemoteTask(&Helper::Nop); | |
| 1300 testing::Mock::VerifyAndClear(helper.observer()); | |
| 1301 EXPECT_FALSE(TraceLog::GetInstance()->IsEnabled()); | |
| 1302 | |
| 1303 // Cleanup. | |
| 1304 helper.PerformRemoteTask(&Helper::RemoveObserverFromTraceLog); | |
| 1305 TraceLog::GetInstance()->SetDisabled(); | |
| 1306 } | |
| 1307 | |
| 1308 TEST_F(TraceEventTestFixture, AsyncEnabledObserverFiresOnDisable) { | |
| 1309 TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""), | |
| 1310 TraceLog::RECORDING_MODE); | |
| 1311 | |
| 1312 typedef AsyncTraceEventHelper<MockAsyncEnabledStateChangedObserver> Helper; | |
| 1313 Helper helper; | |
| 1314 helper.PerformRemoteTask(&Helper::AddObserverToTraceLog); | |
| 1315 | |
| 1316 EXPECT_CALL(*helper.observer(), OnTraceLogDisabled()).Times(1); | |
| 1317 TraceLog::GetInstance()->SetDisabled(); | |
| 1318 helper.PerformRemoteTask(&Helper::Nop); | |
| 1319 testing::Mock::VerifyAndClear(helper.observer()); | |
| 1320 EXPECT_FALSE(TraceLog::GetInstance()->IsEnabled()); | |
| 1321 | |
| 1322 // Cleanup. | |
| 1323 helper.PerformRemoteTask(&Helper::RemoveObserverFromTraceLog); | |
| 1324 } | |
| 1325 | |
| 1326 // No test for the IsEnabled() state of TraceLog at the time when callbacks of | |
| 1327 // AsyncEnabledStateObserver are run. Such tests do not make much sense due to | |
| 1328 // the async nature of the class. | |
| 1329 | |
| 1330 // Tests that a state observer can remove itself during a callback. | |
| 1331 class SelfRemovingAsyncEnabledStateObserver | |
| 1332 : public TraceLog::AsyncEnabledStateObserver { | |
| 1333 public: | |
| 1334 SelfRemovingAsyncEnabledStateObserver() : weak_factory_(this) {} | |
| 1335 ~SelfRemovingAsyncEnabledStateObserver() override {} | |
| 1336 WeakPtr<SelfRemovingAsyncEnabledStateObserver> GetWeakPtr() { | |
| 1337 return weak_factory_.GetWeakPtr(); | |
| 1338 } | |
| 1339 | |
| 1340 // TraceLog::AsyncEnabledStateObserver overrides: | |
| 1341 void OnTraceLogEnabled() override {} | |
| 1342 void OnTraceLogDisabled() override { | |
| 1343 TraceLog::GetInstance()->RemoveAsyncEnabledStateObserver(this); | |
| 1344 } | |
| 1345 | |
| 1346 private: | |
| 1347 WeakPtrFactory<SelfRemovingAsyncEnabledStateObserver> weak_factory_; | |
| 1348 | |
| 1349 DISALLOW_COPY_AND_ASSIGN(SelfRemovingAsyncEnabledStateObserver); | |
| 1350 }; | |
| 1351 | |
| 1352 TEST_F(TraceEventTestFixture, SelfRemovingAsyncObserver) { | |
| 1353 typedef AsyncTraceEventHelper<SelfRemovingAsyncEnabledStateObserver> Helper; | |
| 1354 Helper helper; | |
| 1355 helper.PerformRemoteTask(&Helper::AddObserverToTraceLog); | |
| 1356 EXPECT_TRUE( | |
| 1357 TraceLog::GetInstance()->HasAsyncEnabledStateObserver(helper.observer())); | |
| 1358 | |
| 1359 TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""), | |
| 1360 TraceLog::RECORDING_MODE); | |
| 1361 TraceLog::GetInstance()->SetDisabled(); | |
| 1362 helper.PerformRemoteTask(&Helper::Nop); | |
| 1363 | |
| 1364 // The observer removed itself on disable. | |
| 1365 EXPECT_FALSE( | |
| 1366 TraceLog::GetInstance()->HasAsyncEnabledStateObserver(helper.observer())); | |
| 1367 } | |
| 1368 | |
| 1168 bool IsNewTrace() { | 1369 bool IsNewTrace() { |
| 1169 bool is_new_trace; | 1370 bool is_new_trace; |
| 1170 TRACE_EVENT_IS_NEW_TRACE(&is_new_trace); | 1371 TRACE_EVENT_IS_NEW_TRACE(&is_new_trace); |
| 1171 return is_new_trace; | 1372 return is_new_trace; |
| 1172 } | 1373 } |
| 1173 | 1374 |
| 1174 TEST_F(TraceEventTestFixture, NewTraceRecording) { | 1375 TEST_F(TraceEventTestFixture, NewTraceRecording) { |
| 1175 ASSERT_FALSE(IsNewTrace()); | 1376 ASSERT_FALSE(IsNewTrace()); |
| 1176 TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""), | 1377 TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""), |
| 1177 TraceLog::RECORDING_MODE); | 1378 TraceLog::RECORDING_MODE); |
| (...skipping 1916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3094 } | 3295 } |
| 3095 | 3296 |
| 3096 TEST_F(TraceEventTestFixture, SyntheticDelayConfigurationToString) { | 3297 TEST_F(TraceEventTestFixture, SyntheticDelayConfigurationToString) { |
| 3097 const char filter[] = "DELAY(test.Delay;16;oneshot)"; | 3298 const char filter[] = "DELAY(test.Delay;16;oneshot)"; |
| 3098 TraceConfig config(filter, ""); | 3299 TraceConfig config(filter, ""); |
| 3099 EXPECT_EQ(filter, config.ToCategoryFilterString()); | 3300 EXPECT_EQ(filter, config.ToCategoryFilterString()); |
| 3100 } | 3301 } |
| 3101 | 3302 |
| 3102 } // namespace trace_event | 3303 } // namespace trace_event |
| 3103 } // namespace base | 3304 } // namespace base |
| OLD | NEW |