1 // 2 // Copyright (C) 2014 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include "shill/wifi/mac80211_monitor.h" 18 19 #include <vector> 20 21 #include <base/files/file_util.h> 22 #include <base/files/scoped_temp_dir.h> 23 #include <gmock/gmock.h> 24 #include <gtest/gtest.h> 25 26 #include "shill/mock_event_dispatcher.h" 27 #include "shill/mock_log.h" 28 #include "shill/mock_metrics.h" 29 #include "shill/net/mock_time.h" 30 31 using std::string; 32 using std::vector; 33 using ::testing::_; 34 using ::testing::AnyNumber; 35 using ::testing::DoAll; 36 using ::testing::ElementsAre; 37 using ::testing::HasSubstr; 38 using ::testing::Return; 39 using ::testing::SetArgumentPointee; 40 using ::testing::StrictMock; 41 42 namespace shill { 43 44 namespace { 45 46 const char kTestDeviceName[] = "test-dev"; 47 const char kJunkData[] = "junk data"; 48 49 } // namespace 50 51 typedef Mac80211Monitor::QueueState QState; 52 53 class Mac80211MonitorTest : public testing::Test { 54 public: 55 Mac80211MonitorTest() 56 : metrics_(nullptr), 57 mac80211_monitor_( 58 &event_dispatcher_, 59 kTestDeviceName, 60 kQueueLengthLimit, 61 base::Bind(&Mac80211MonitorTest::OnRepairHandler, 62 base::Unretained(this)), 63 &metrics_) { 64 mac80211_monitor_.time_ = &time_; 65 } 66 virtual ~Mac80211MonitorTest() {} 67 68 protected: 69 static const size_t kQueueLengthLimit = 5; 70 base::FilePath fake_queue_state_file_path_; // Call FakeUpSysfs() first. 71 base::FilePath fake_wake_queues_file_path_; // Call FakeUpSysfs() first. 72 73 // Getters for fixture fields. 74 MockTime& time() { return time_; } 75 MockEventDispatcher& event_dispatcher() { return event_dispatcher_; } 76 MockMetrics& metrics() { return metrics_; } 77 78 // Complex fixture methods. 79 void AllowWakeQueuesIfNeededCommonCalls() { 80 // Allow any number of these calls, as these aspects of 81 // WakeQueuesIfNeeded interaction are tested elsewhere. 82 EXPECT_CALL(event_dispatcher(), PostDelayedTask(_, _)) 83 .Times(AnyNumber()); 84 EXPECT_CALL(metrics(), SendEnumToUMA(_, _, _)) 85 .Times(AnyNumber()); 86 EXPECT_CALL(metrics(), SendToUMA(_, _, _, _, _)) 87 .Times(AnyNumber()); 88 } 89 void FakeUpNotStuckState() { 90 FakeUpQueueFiles("00: 0x00000000/10\n"); 91 } 92 void FakeUpStuckByDriverState() { 93 FakeUpQueueFiles("00: 0x00000001/10\n"); 94 } 95 void FakeUpStuckByPowerSaveState() { 96 FakeUpQueueFiles("00: 0x00000002/10\n"); 97 } 98 void FakeUpSysfs() { 99 CHECK(fake_sysfs_tree_.CreateUniqueTempDir()); 100 CHECK(base::CreateTemporaryFileInDir( 101 fake_sysfs_tree_.path(), &fake_queue_state_file_path_)); 102 CHECK(base::CreateTemporaryFileInDir( 103 fake_sysfs_tree_.path(), &fake_wake_queues_file_path_)); 104 PlumbFakeSysfs(); 105 } 106 void DeleteQueueStateFile() { 107 fake_queue_state_file_path_.clear(); 108 PlumbFakeSysfs(); 109 } 110 bool IsRunning() const { 111 return mac80211_monitor_.is_running_ && 112 !mac80211_monitor_.check_queues_callback_.IsCancelled(); 113 } 114 bool IsStopped() const { 115 return !mac80211_monitor_.is_running_ && 116 mac80211_monitor_.check_queues_callback_.IsCancelled(); 117 } 118 bool IsWakeQueuesFileModified() const { 119 CHECK(fake_sysfs_tree_.IsValid()); // Keep tests hermetic. 120 string wake_file_contents; 121 base::ReadFileToString(fake_wake_queues_file_path_, &wake_file_contents); 122 return wake_file_contents != kJunkData; 123 } 124 MOCK_METHOD0(OnRepairHandler, void()); 125 126 // Getters for Mac80211Monitor state. 127 bool GetIsDeviceConnected() const { 128 return mac80211_monitor_.is_device_connected_; 129 } 130 time_t GetLastWokeQueuesMonotonicSeconds() const { 131 return mac80211_monitor_.last_woke_queues_monotonic_seconds_; 132 } 133 const string& GetLinkName() const { 134 return mac80211_monitor_.link_name_; 135 } 136 time_t GetMinimumTimeBetweenWakesSeconds() const { 137 return Mac80211Monitor::kMinimumTimeBetweenWakesSeconds; 138 } 139 const string& GetPhyName() const { 140 return mac80211_monitor_.phy_name_; 141 } 142 const base::FilePath& GetQueueStateFilePath() const { 143 return mac80211_monitor_.queue_state_file_path_; 144 } 145 const base::FilePath& GetWakeQueuesFilePath() const { 146 return mac80211_monitor_.wake_queues_file_path_; 147 } 148 149 // Pass-through methods to Mac80211Monitor methods. 150 void StartMonitor(const string& phy_name) { 151 EXPECT_CALL( 152 event_dispatcher_, 153 PostDelayedTask( 154 _, Mac80211Monitor::kQueueStatePollIntervalSeconds * 1000)); 155 mac80211_monitor_.Start(phy_name); 156 if (fake_sysfs_tree_.IsValid()) { 157 PlumbFakeSysfs(); // Re-plumb, since un-plumbed by Start(). 158 } 159 } 160 void StopMonitor() { 161 mac80211_monitor_.Stop(); 162 } 163 uint32_t CheckAreQueuesStuck(const vector<QState>& queue_states) { 164 return mac80211_monitor_.CheckAreQueuesStuck(queue_states); 165 } 166 void UpdateConnectedState(bool new_state) { 167 mac80211_monitor_.UpdateConnectedState(new_state); 168 } 169 void WakeQueuesIfNeeded() { 170 CHECK(fake_sysfs_tree_.IsValid()); // Keep tests hermetic. 171 mac80211_monitor_.WakeQueuesIfNeeded(); 172 } 173 174 private: 175 base::ScopedTempDir fake_sysfs_tree_; // Call FakeUpSysfs() first. 176 StrictMock<MockEventDispatcher> event_dispatcher_; 177 StrictMock<MockMetrics> metrics_; 178 StrictMock<MockTime> time_; 179 Mac80211Monitor mac80211_monitor_; 180 181 void FakeUpQueueFiles(const string& queue_state_string) { 182 CHECK(fake_sysfs_tree_.IsValid()); // Keep tests hermetic. 183 base::WriteFile(fake_queue_state_file_path_, 184 queue_state_string.c_str(), 185 queue_state_string.length()); 186 ASSERT_TRUE(base::WriteFile(fake_wake_queues_file_path_, 187 kJunkData, strlen(kJunkData))); 188 } 189 void PlumbFakeSysfs() { 190 mac80211_monitor_.queue_state_file_path_ = fake_queue_state_file_path_; 191 mac80211_monitor_.wake_queues_file_path_ = fake_wake_queues_file_path_; 192 } 193 }; 194 195 // Can't be in an anonymous namespace, due to ADL. 196 // Instead, we use static to constain visibility to this unit. 197 static bool operator==(const QState& a, const QState& b) { 198 return a.queue_number == b.queue_number && 199 a.stop_flags == b.stop_flags && 200 a.queue_length == b.queue_length; 201 } 202 203 TEST_F(Mac80211MonitorTest, Ctor) { 204 EXPECT_TRUE(IsStopped()); 205 EXPECT_EQ(kTestDeviceName, GetLinkName()); 206 } 207 208 TEST_F(Mac80211MonitorTest, Start) { 209 StartMonitor("test-phy"); 210 EXPECT_TRUE(IsRunning()); 211 EXPECT_EQ("test-phy", GetPhyName()); 212 EXPECT_EQ("/sys/kernel/debug/ieee80211/test-phy/queues", 213 GetQueueStateFilePath().value()); 214 EXPECT_EQ("/sys/kernel/debug/ieee80211/test-phy/wake_queues", 215 GetWakeQueuesFilePath().value()); 216 EXPECT_EQ(0, GetLastWokeQueuesMonotonicSeconds()); 217 } 218 219 TEST_F(Mac80211MonitorTest, Stop) { 220 StartMonitor("dont-care-phy"); 221 EXPECT_TRUE(IsRunning()); 222 StopMonitor(); 223 EXPECT_TRUE(IsStopped()); 224 } 225 226 TEST_F(Mac80211MonitorTest, UpdateConnectedState) { 227 UpdateConnectedState(false); 228 EXPECT_FALSE(GetIsDeviceConnected()); 229 230 UpdateConnectedState(true); 231 EXPECT_TRUE(GetIsDeviceConnected()); 232 233 // Initial state was unknown. Ensure that we can move from true to false. 234 UpdateConnectedState(false); 235 EXPECT_FALSE(GetIsDeviceConnected()); 236 } 237 238 TEST_F(Mac80211MonitorTest, WakeQueuesIfNeededFullMacDevice) { 239 FakeUpSysfs(); 240 StartMonitor("dont-care-phy"); 241 UpdateConnectedState(false); 242 EXPECT_CALL(event_dispatcher(), PostDelayedTask(_, _)); 243 ScopedMockLog log; 244 EXPECT_CALL(log, Log(_, _, HasSubstr(": incomplete read on "))).Times(0); 245 246 // In case of using device with Full-Mac support, 247 // there is no queue state file in debugfs. 248 DeleteQueueStateFile(); 249 WakeQueuesIfNeeded(); 250 } 251 252 TEST_F(Mac80211MonitorTest, WakeQueuesIfNeededRearmsTimerWhenDisconnected) { 253 FakeUpSysfs(); 254 StartMonitor("dont-care-phy"); 255 UpdateConnectedState(false); 256 EXPECT_CALL(event_dispatcher(), PostDelayedTask(_, _)); 257 WakeQueuesIfNeeded(); 258 } 259 260 TEST_F(Mac80211MonitorTest, WakeQueuesIfNeededFailToReadQueueState) { 261 FakeUpSysfs(); 262 StartMonitor("dont-care-phy"); 263 UpdateConnectedState(false); 264 AllowWakeQueuesIfNeededCommonCalls(); 265 WakeQueuesIfNeeded(); 266 267 // In case we succeeded reading queue state before, but fail this time. 268 ScopedMockLog log; 269 EXPECT_CALL(log, Log(_, _, HasSubstr(": incomplete read on "))).Times(1); 270 DeleteQueueStateFile(); 271 WakeQueuesIfNeeded(); 272 } 273 274 TEST_F(Mac80211MonitorTest, WakeQueuesIfNeededRearmsTimerWhenConnected) { 275 FakeUpSysfs(); 276 StartMonitor("dont-care-phy"); 277 UpdateConnectedState(true); 278 EXPECT_CALL(event_dispatcher(), PostDelayedTask(_, _)); 279 WakeQueuesIfNeeded(); 280 } 281 282 TEST_F(Mac80211MonitorTest, WakeQueuesIfNeededWakeNeeded) { 283 FakeUpSysfs(); 284 FakeUpStuckByPowerSaveState(); 285 StartMonitor("dont-care-phy"); 286 EXPECT_EQ(0, GetLastWokeQueuesMonotonicSeconds()); 287 288 const time_t kNowMonotonicSeconds = GetMinimumTimeBetweenWakesSeconds(); 289 EXPECT_CALL(time(), GetSecondsMonotonic(_)) 290 .WillOnce(DoAll(SetArgumentPointee<0>(kNowMonotonicSeconds), 291 Return(true))); 292 EXPECT_CALL(*this, OnRepairHandler()); 293 AllowWakeQueuesIfNeededCommonCalls(); 294 WakeQueuesIfNeeded(); 295 296 EXPECT_EQ(kNowMonotonicSeconds, GetLastWokeQueuesMonotonicSeconds()); 297 EXPECT_TRUE(IsWakeQueuesFileModified()); 298 } 299 300 TEST_F(Mac80211MonitorTest, WakeQueuesIfNeededRateLimiting) { 301 FakeUpSysfs(); 302 FakeUpStuckByPowerSaveState(); 303 StartMonitor("dont-care-phy"); 304 EXPECT_EQ(0, GetLastWokeQueuesMonotonicSeconds()); 305 306 EXPECT_CALL(time(), GetSecondsMonotonic(_)) 307 .WillOnce(DoAll( 308 SetArgumentPointee<0>(GetMinimumTimeBetweenWakesSeconds() - 1), 309 Return(true))); 310 EXPECT_CALL(*this, OnRepairHandler()).Times(0); 311 AllowWakeQueuesIfNeededCommonCalls(); 312 WakeQueuesIfNeeded(); 313 314 EXPECT_EQ(0, GetLastWokeQueuesMonotonicSeconds()); 315 EXPECT_FALSE(IsWakeQueuesFileModified()); 316 } 317 318 TEST_F(Mac80211MonitorTest, WakeQueuesIfNeededNotStuck) { 319 FakeUpSysfs(); 320 FakeUpNotStuckState(); 321 StartMonitor("dont-care-phy"); 322 EXPECT_EQ(0, GetLastWokeQueuesMonotonicSeconds()); 323 324 EXPECT_CALL(*this, OnRepairHandler()).Times(0); 325 AllowWakeQueuesIfNeededCommonCalls(); 326 WakeQueuesIfNeeded(); 327 328 EXPECT_EQ(0, GetLastWokeQueuesMonotonicSeconds()); 329 EXPECT_FALSE(IsWakeQueuesFileModified()); 330 } 331 332 TEST_F(Mac80211MonitorTest, WakeQueuesIfNeededStuckByDriver) { 333 FakeUpSysfs(); 334 FakeUpStuckByDriverState(); 335 StartMonitor("dont-care-phy"); 336 EXPECT_EQ(0, GetLastWokeQueuesMonotonicSeconds()); 337 338 EXPECT_CALL(*this, OnRepairHandler()).Times(0); 339 AllowWakeQueuesIfNeededCommonCalls(); 340 WakeQueuesIfNeeded(); 341 342 EXPECT_EQ(0, GetLastWokeQueuesMonotonicSeconds()); 343 EXPECT_FALSE(IsWakeQueuesFileModified()); 344 } 345 346 TEST_F(Mac80211MonitorTest, ParseQueueStateSimple) { 347 // Single queue. 348 EXPECT_THAT(Mac80211Monitor::ParseQueueState("00: 0x00000000/0\n"), 349 ElementsAre(QState(0, 0, 0))); 350 351 // Multiple queues, non-empty. 352 EXPECT_THAT( 353 Mac80211Monitor::ParseQueueState( 354 "00: 0x00000000/10\n" 355 "01: 0x00000000/20\n"), 356 ElementsAre(QState(0, 0, 10), QState(1, 0, 20))); 357 } 358 359 TEST_F(Mac80211MonitorTest, ParseQueueStateStopped) { 360 // Single queue, stopped for various reasons. 361 EXPECT_THAT( 362 Mac80211Monitor::ParseQueueState("00: 0x00000001/10\n"), 363 ElementsAre(QState(0, Mac80211Monitor::kStopFlagDriver, 10))); 364 EXPECT_THAT( 365 Mac80211Monitor::ParseQueueState("00: 0x00000003/10\n"), 366 ElementsAre(QState(0, 367 Mac80211Monitor::kStopFlagDriver | 368 Mac80211Monitor::kStopFlagPowerSave, 369 10))); 370 EXPECT_THAT( 371 Mac80211Monitor::ParseQueueState("00: 0x00000007/10\n"), 372 ElementsAre(QState(0, 373 Mac80211Monitor::kStopFlagDriver | 374 Mac80211Monitor::kStopFlagPowerSave | 375 Mac80211Monitor::kStopFlagChannelSwitch, 376 10))); 377 EXPECT_THAT( 378 Mac80211Monitor::ParseQueueState("00: 0x0000000f/10\n"), 379 ElementsAre(QState(0, 380 Mac80211Monitor::kStopFlagDriver | 381 Mac80211Monitor::kStopFlagPowerSave | 382 Mac80211Monitor::kStopFlagChannelSwitch | 383 Mac80211Monitor::kStopFlagAggregation, 384 10))); 385 EXPECT_THAT( 386 Mac80211Monitor::ParseQueueState("00: 0x0000001f/10\n"), 387 ElementsAre(QState(0, 388 Mac80211Monitor::kStopFlagDriver | 389 Mac80211Monitor::kStopFlagPowerSave | 390 Mac80211Monitor::kStopFlagChannelSwitch | 391 Mac80211Monitor::kStopFlagAggregation | 392 Mac80211Monitor::kStopFlagSuspend, 393 10))); 394 EXPECT_THAT( 395 Mac80211Monitor::ParseQueueState("00: 0x0000003f/10\n"), 396 ElementsAre(QState(0, 397 Mac80211Monitor::kStopFlagDriver | 398 Mac80211Monitor::kStopFlagPowerSave | 399 Mac80211Monitor::kStopFlagChannelSwitch | 400 Mac80211Monitor::kStopFlagAggregation | 401 Mac80211Monitor::kStopFlagSuspend | 402 Mac80211Monitor::kStopFlagBufferAdd, 403 10))); 404 EXPECT_THAT( 405 Mac80211Monitor::ParseQueueState("00: 0x0000007f/10\n"), 406 ElementsAre(QState(0, 407 Mac80211Monitor::kStopFlagDriver | 408 Mac80211Monitor::kStopFlagPowerSave | 409 Mac80211Monitor::kStopFlagChannelSwitch | 410 Mac80211Monitor::kStopFlagAggregation | 411 Mac80211Monitor::kStopFlagSuspend | 412 Mac80211Monitor::kStopFlagBufferAdd | 413 Mac80211Monitor::kStopFlagChannelTypeChange, 414 10))); 415 } 416 417 TEST_F(Mac80211MonitorTest, ParseQueueStateBadInput) { 418 // Empty input -> Empty output. 419 EXPECT_TRUE(Mac80211Monitor::ParseQueueState("").empty()); 420 421 // Missing queue length for queue 0. 422 EXPECT_THAT( 423 Mac80211Monitor::ParseQueueState( 424 "00: 0x00000000\n" 425 "01: 0xffffffff/10\n"), 426 ElementsAre(QState(1, 0xffffffff, 10))); 427 428 // Missing flags for queue 0. 429 EXPECT_THAT( 430 Mac80211Monitor::ParseQueueState( 431 "00: 0\n" 432 "01: 0xffffffff/10\n"), 433 ElementsAre(QState(1, 0xffffffff, 10))); 434 435 // Bad number for queue 0. 436 EXPECT_THAT( 437 Mac80211Monitor::ParseQueueState( 438 "aa: 0xabcdefgh/0\n" 439 "01: 0xffffffff/10\n"), 440 ElementsAre(QState(1, 0xffffffff, 10))); 441 442 // Bad flags for queue 0. 443 EXPECT_THAT( 444 Mac80211Monitor::ParseQueueState( 445 "00: 0xabcdefgh/0\n" 446 "01: 0xffffffff/10\n"), 447 ElementsAre(QState(1, 0xffffffff, 10))); 448 449 // Bad length for queue 0. 450 EXPECT_THAT( 451 Mac80211Monitor::ParseQueueState( 452 "00: 0x00000000/-1\n" 453 "01: 0xffffffff/10\n"), 454 ElementsAre(QState(1, 0xffffffff, 10))); 455 } 456 457 TEST_F(Mac80211MonitorTest, CheckAreQueuesStuckNotStuck) { 458 EXPECT_FALSE(CheckAreQueuesStuck({})); 459 EXPECT_FALSE(CheckAreQueuesStuck({QState(0, 0, 0)})); 460 // Not stuck when queue length is below limit. 461 EXPECT_FALSE(CheckAreQueuesStuck({ 462 QState(0, Mac80211Monitor::kStopFlagPowerSave, kQueueLengthLimit-1)})); 463 } 464 465 TEST_F(Mac80211MonitorTest, CheckAreQueuesStuckSingleReason) { 466 EXPECT_CALL(metrics(), SendEnumToUMA( 467 Metrics::kMetricWifiStoppedTxQueueReason, 468 Mac80211Monitor::kStopReasonDriver, 469 Mac80211Monitor::kStopReasonMax)); 470 EXPECT_CALL(metrics(), SendEnumToUMA( 471 Metrics::kMetricWifiStoppedTxQueueReason, 472 Mac80211Monitor::kStopReasonPowerSave, 473 Mac80211Monitor::kStopReasonMax)); 474 EXPECT_CALL(metrics(), SendToUMA( 475 Metrics::kMetricWifiStoppedTxQueueLength, 476 kQueueLengthLimit, 477 Metrics::kMetricWifiStoppedTxQueueLengthMin, 478 Metrics::kMetricWifiStoppedTxQueueLengthMax, 479 Metrics::kMetricWifiStoppedTxQueueLengthNumBuckets)).Times(2); 480 EXPECT_EQ(Mac80211Monitor::kStopFlagDriver, 481 CheckAreQueuesStuck({ 482 QState(0, 483 Mac80211Monitor::kStopFlagDriver, 484 kQueueLengthLimit)})); 485 EXPECT_EQ(Mac80211Monitor::kStopFlagPowerSave, 486 CheckAreQueuesStuck({ 487 QState(0, 488 Mac80211Monitor::kStopFlagPowerSave, 489 kQueueLengthLimit)})); 490 } 491 492 TEST_F(Mac80211MonitorTest, CheckAreQueuesStuckMultipleReasons) { 493 EXPECT_CALL(metrics(), SendEnumToUMA( 494 Metrics::kMetricWifiStoppedTxQueueReason, 495 Mac80211Monitor::kStopReasonPowerSave, 496 Mac80211Monitor::kStopReasonMax)).Times(2); 497 EXPECT_CALL(metrics(), SendEnumToUMA( 498 Metrics::kMetricWifiStoppedTxQueueReason, 499 Mac80211Monitor::kStopReasonDriver, 500 Mac80211Monitor::kStopReasonMax)).Times(2); 501 EXPECT_CALL(metrics(), SendEnumToUMA( 502 Metrics::kMetricWifiStoppedTxQueueReason, 503 Mac80211Monitor::kStopReasonChannelSwitch, 504 Mac80211Monitor::kStopReasonMax)).Times(2); 505 EXPECT_CALL(metrics(), SendToUMA( 506 Metrics::kMetricWifiStoppedTxQueueLength, 507 kQueueLengthLimit, 508 Metrics::kMetricWifiStoppedTxQueueLengthMin, 509 Metrics::kMetricWifiStoppedTxQueueLengthMax, 510 Metrics::kMetricWifiStoppedTxQueueLengthNumBuckets)).Times(3); 511 EXPECT_EQ(Mac80211Monitor::kStopFlagDriver | 512 Mac80211Monitor::kStopFlagPowerSave, 513 CheckAreQueuesStuck({ 514 QState(0, 515 Mac80211Monitor::kStopFlagDriver | 516 Mac80211Monitor::kStopFlagPowerSave, 517 kQueueLengthLimit)})); 518 EXPECT_EQ(Mac80211Monitor::kStopFlagPowerSave | 519 Mac80211Monitor::kStopFlagChannelSwitch, 520 CheckAreQueuesStuck({ 521 QState(0, 522 Mac80211Monitor::kStopFlagPowerSave | 523 Mac80211Monitor::kStopFlagChannelSwitch, 524 kQueueLengthLimit)})); 525 EXPECT_EQ(Mac80211Monitor::kStopFlagDriver | 526 Mac80211Monitor::kStopFlagChannelSwitch, 527 CheckAreQueuesStuck({ 528 QState(0, 529 Mac80211Monitor::kStopFlagDriver | 530 Mac80211Monitor::kStopFlagChannelSwitch, 531 kQueueLengthLimit)})); 532 } 533 534 TEST_F(Mac80211MonitorTest, CheckAreQueuesStuckMultipleQueues) { 535 EXPECT_CALL(metrics(), SendEnumToUMA( 536 Metrics::kMetricWifiStoppedTxQueueReason, 537 Mac80211Monitor::kStopReasonPowerSave, 538 Mac80211Monitor::kStopReasonMax)).Times(5); 539 EXPECT_CALL(metrics(), SendEnumToUMA( 540 Metrics::kMetricWifiStoppedTxQueueReason, 541 Mac80211Monitor::kStopReasonDriver, 542 Mac80211Monitor::kStopReasonMax)).Times(2); 543 EXPECT_CALL(metrics(), SendToUMA( 544 Metrics::kMetricWifiStoppedTxQueueLength, 545 kQueueLengthLimit, 546 Metrics::kMetricWifiStoppedTxQueueLengthMin, 547 Metrics::kMetricWifiStoppedTxQueueLengthMax, 548 Metrics::kMetricWifiStoppedTxQueueLengthNumBuckets)).Times(5); 549 EXPECT_EQ(Mac80211Monitor::kStopFlagPowerSave, 550 CheckAreQueuesStuck({ 551 QState(0, 0, 0), 552 QState(0, 553 Mac80211Monitor::kStopFlagPowerSave, 554 kQueueLengthLimit)})); 555 EXPECT_EQ(Mac80211Monitor::kStopFlagPowerSave, 556 CheckAreQueuesStuck({ 557 QState(0, 558 Mac80211Monitor::kStopFlagPowerSave, 559 kQueueLengthLimit), 560 QState(0, 0, 0)})); 561 EXPECT_EQ(Mac80211Monitor::kStopFlagPowerSave, 562 CheckAreQueuesStuck({ 563 QState(0, 564 Mac80211Monitor::kStopFlagPowerSave, 565 kQueueLengthLimit), 566 QState(0, 567 Mac80211Monitor::kStopFlagPowerSave, 568 kQueueLengthLimit)})); 569 EXPECT_EQ(Mac80211Monitor::kStopFlagDriver | 570 Mac80211Monitor::kStopFlagPowerSave, 571 CheckAreQueuesStuck({ 572 QState(0, 573 Mac80211Monitor::kStopFlagPowerSave, 574 kQueueLengthLimit), 575 QState(0, 576 Mac80211Monitor::kStopFlagDriver, 577 kQueueLengthLimit)})); 578 EXPECT_EQ(Mac80211Monitor::kStopFlagDriver | 579 Mac80211Monitor::kStopFlagPowerSave, 580 CheckAreQueuesStuck({ 581 QState(0, Mac80211Monitor::kStopFlagDriver, kQueueLengthLimit), 582 QState(0, 583 Mac80211Monitor::kStopFlagPowerSave, 584 kQueueLengthLimit)})); 585 } 586 587 TEST_F(Mac80211MonitorTest, CheckAreQueuesStuckQueueLength) { 588 EXPECT_CALL(metrics(), SendEnumToUMA( 589 Metrics::kMetricWifiStoppedTxQueueReason, 590 Mac80211Monitor::kStopReasonPowerSave, 591 Mac80211Monitor::kStopReasonMax)).Times(4); 592 EXPECT_CALL(metrics(), SendToUMA( 593 Metrics::kMetricWifiStoppedTxQueueLength, 594 kQueueLengthLimit, 595 Metrics::kMetricWifiStoppedTxQueueLengthMin, 596 Metrics::kMetricWifiStoppedTxQueueLengthMax, 597 Metrics::kMetricWifiStoppedTxQueueLengthNumBuckets)).Times(4); 598 EXPECT_TRUE(CheckAreQueuesStuck({ 599 QState(0, Mac80211Monitor::kStopFlagPowerSave, kQueueLengthLimit)})); 600 EXPECT_TRUE(CheckAreQueuesStuck({ 601 QState(0, Mac80211Monitor::kStopFlagPowerSave, kQueueLengthLimit-2), 602 QState(0, Mac80211Monitor::kStopFlagPowerSave, kQueueLengthLimit-1), 603 QState(0, Mac80211Monitor::kStopFlagPowerSave, kQueueLengthLimit)})); 604 EXPECT_TRUE(CheckAreQueuesStuck({ 605 QState(0, Mac80211Monitor::kStopFlagPowerSave, kQueueLengthLimit), 606 QState(0, Mac80211Monitor::kStopFlagPowerSave, kQueueLengthLimit-1), 607 QState(0, Mac80211Monitor::kStopFlagPowerSave, kQueueLengthLimit-2)})); 608 EXPECT_TRUE(CheckAreQueuesStuck({ 609 QState(0, Mac80211Monitor::kStopFlagPowerSave, kQueueLengthLimit-1), 610 QState(0, Mac80211Monitor::kStopFlagPowerSave, kQueueLengthLimit), 611 QState(0, Mac80211Monitor::kStopFlagPowerSave, kQueueLengthLimit-2)})); 612 } 613 614 TEST_F(Mac80211MonitorTest, CheckAreQueuesStuckQueueLengthIgnoresUnstopped) { 615 EXPECT_CALL(metrics(), SendEnumToUMA( 616 Metrics::kMetricWifiStoppedTxQueueReason, 617 Mac80211Monitor::kStopReasonPowerSave, 618 Mac80211Monitor::kStopReasonMax)); 619 EXPECT_CALL(metrics(), SendToUMA( 620 Metrics::kMetricWifiStoppedTxQueueLength, 621 kQueueLengthLimit, 622 Metrics::kMetricWifiStoppedTxQueueLengthMin, 623 Metrics::kMetricWifiStoppedTxQueueLengthMax, 624 Metrics::kMetricWifiStoppedTxQueueLengthNumBuckets)); 625 EXPECT_TRUE(CheckAreQueuesStuck({ 626 QState(0, 0, kQueueLengthLimit * 10), 627 QState(0, Mac80211Monitor::kStopFlagPowerSave, kQueueLengthLimit)})); 628 } 629 630 } // namespace shill 631