1 /// Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "athena/resource_manager/memory_pressure_notifier.h" 6 #include "athena/resource_manager/public/resource_manager_delegate.h" 7 #include "athena/test/athena_test_base.h" 8 9 namespace athena { 10 namespace test { 11 12 namespace { 13 14 // Our OS delegate abstraction class to override the memory fill level. 15 class TestResourceManagerDelegate : public ResourceManagerDelegate { 16 public: 17 TestResourceManagerDelegate() : memory_fill_level_percent_(0) {} 18 virtual ~TestResourceManagerDelegate() {} 19 20 virtual int GetUsedMemoryInPercent() OVERRIDE { 21 timer_called_++; 22 return memory_fill_level_percent_; 23 } 24 25 virtual int MemoryPressureIntervalInMS() OVERRIDE { 26 return 5; 27 } 28 29 void set_memory_fill_level_percent(int memory_fill_level_percent) { 30 memory_fill_level_percent_ = memory_fill_level_percent; 31 } 32 33 // Returns the number of timer calls to the GetMemoryInPercent() calls. 34 int timer_called() { return timer_called_; } 35 36 private: 37 // The to be returned memory fill level value in percent. 38 int memory_fill_level_percent_; 39 40 // How often was the timer calling the GetUsedMemoryInPercent() function. 41 int timer_called_; 42 43 DISALLOW_COPY_AND_ASSIGN(TestResourceManagerDelegate); 44 }; 45 46 // Our memory pressure observer class. 47 class TestMemoryPressureObserver : public MemoryPressureObserver { 48 public: 49 TestMemoryPressureObserver(ResourceManagerDelegate* delegate) 50 : delegate_(delegate), 51 number_of_calls_(0), 52 pressure_(MEMORY_PRESSURE_UNKNOWN) {} 53 virtual ~TestMemoryPressureObserver() {} 54 55 // The observer. 56 virtual void OnMemoryPressure(MemoryPressure pressure) OVERRIDE { 57 number_of_calls_++; 58 pressure_ = pressure; 59 } 60 61 virtual ResourceManagerDelegate* GetDelegate() OVERRIDE { 62 return delegate_.get(); 63 } 64 65 int number_of_calls() { return number_of_calls_; } 66 MemoryPressureObserver::MemoryPressure pressure() { return pressure_; } 67 68 private: 69 scoped_ptr<ResourceManagerDelegate> delegate_; 70 71 // Number of calls received. 72 int number_of_calls_; 73 74 // Last posted memory pressure. 75 MemoryPressureObserver::MemoryPressure pressure_; 76 77 DISALLOW_COPY_AND_ASSIGN(TestMemoryPressureObserver); 78 }; 79 80 } // namespace 81 82 // Our testing base. 83 class MemoryPressureTest : public AthenaTestBase { 84 public: 85 MemoryPressureTest() : test_resource_manager_delegate_(NULL) {} 86 virtual ~MemoryPressureTest() {} 87 88 // AthenaTestBase: 89 virtual void SetUp() OVERRIDE { 90 AthenaTestBase::SetUp(); 91 // Create and install our TestAppContentDelegate with instrumentation. 92 test_resource_manager_delegate_ = 93 new TestResourceManagerDelegate(); 94 test_memory_pressure_observer_.reset(new TestMemoryPressureObserver( 95 test_resource_manager_delegate_)); 96 memory_pressure_notifier_.reset( 97 new MemoryPressureNotifier(test_memory_pressure_observer_.get())); 98 } 99 100 virtual void TearDown() OVERRIDE { 101 memory_pressure_notifier_.reset(); 102 RunAllPendingInMessageLoop(); 103 test_memory_pressure_observer_.reset(); 104 AthenaTestBase::TearDown(); 105 } 106 107 protected: 108 TestResourceManagerDelegate* test_resource_manager_delegate() { 109 return test_resource_manager_delegate_; 110 } 111 112 TestMemoryPressureObserver* test_memory_pressure_observer() { 113 return test_memory_pressure_observer_.get(); 114 } 115 116 // Waits until a timer interrupt occurs. Returns false if no timer is 117 // registered. 118 bool WaitForTimer() { 119 int first_counter = test_resource_manager_delegate()->timer_called(); 120 // Wait up to 500ms for any poll on our memory status function from the 121 // MemoryPressureNotifier. 122 for (int i = 0; i < 500; ++i) { 123 if (test_resource_manager_delegate()->timer_called() != first_counter) 124 return true; 125 usleep(1); 126 RunAllPendingInMessageLoop(); 127 } 128 return false; 129 } 130 131 private: 132 // Not owned: the resource manager delegate. 133 TestResourceManagerDelegate* test_resource_manager_delegate_; 134 scoped_ptr<TestMemoryPressureObserver> test_memory_pressure_observer_; 135 scoped_ptr<MemoryPressureNotifier> memory_pressure_notifier_; 136 DISALLOW_COPY_AND_ASSIGN(MemoryPressureTest); 137 }; 138 139 // Only creates and destroys it to see that the system gets properly shut down. 140 TEST_F(MemoryPressureTest, SimpleTest) { 141 } 142 143 // Test that we get only a single call while the memory pressure is low. 144 TEST_F(MemoryPressureTest, OneEventOnLowPressure) { 145 ASSERT_TRUE(WaitForTimer()); 146 // No call should have happened at this time to the 147 EXPECT_FALSE(test_memory_pressure_observer()->number_of_calls()); 148 // Set to something below 50% and check that we still get no call. 149 test_resource_manager_delegate()->set_memory_fill_level_percent(49); 150 ASSERT_TRUE(WaitForTimer()); 151 EXPECT_EQ(1, test_memory_pressure_observer()->number_of_calls()); 152 EXPECT_EQ(MemoryPressureObserver::MEMORY_PRESSURE_LOW, 153 test_memory_pressure_observer()->pressure()); 154 ASSERT_TRUE(WaitForTimer()); 155 EXPECT_EQ(1, test_memory_pressure_observer()->number_of_calls()); 156 EXPECT_EQ(MemoryPressureObserver::MEMORY_PRESSURE_LOW, 157 test_memory_pressure_observer()->pressure()); 158 } 159 160 // Test that we get a |MEMORY_PRESSURE_UNKNOWN| if it cannot be determined. 161 TEST_F(MemoryPressureTest, TestNoCallsOnMemoryPressureUnknown) { 162 test_resource_manager_delegate()->set_memory_fill_level_percent(0); 163 ASSERT_TRUE(WaitForTimer()); 164 // We shouldn't have gotten a single call. 165 EXPECT_FALSE(test_memory_pressure_observer()->number_of_calls()); 166 // And the memory pressure should be unknown. 167 EXPECT_EQ(MemoryPressureObserver::MEMORY_PRESSURE_UNKNOWN, 168 test_memory_pressure_observer()->pressure()); 169 } 170 171 // Test that we get a change to MODERATE if the memory pressure is at 60%. 172 TEST_F(MemoryPressureTest, TestModeratePressure) { 173 test_resource_manager_delegate()->set_memory_fill_level_percent(60); 174 ASSERT_TRUE(WaitForTimer()); 175 // At least one call should have happened. 176 int calls = test_memory_pressure_observer()->number_of_calls(); 177 EXPECT_TRUE(calls); 178 EXPECT_EQ(MemoryPressureObserver::MEMORY_PRESSURE_MODERATE, 179 test_memory_pressure_observer()->pressure()); 180 // Even if the value does not change, we should get more calls. 181 ASSERT_TRUE(WaitForTimer()); 182 EXPECT_LT(calls, test_memory_pressure_observer()->number_of_calls()); 183 EXPECT_EQ(MemoryPressureObserver::MEMORY_PRESSURE_MODERATE, 184 test_memory_pressure_observer()->pressure()); 185 } 186 187 // Test that increasing and decreasing the memory pressure does the right thing. 188 TEST_F(MemoryPressureTest, TestPressureUpAndDown) { 189 test_resource_manager_delegate()->set_memory_fill_level_percent(60); 190 ASSERT_TRUE(WaitForTimer()); 191 // At least one call should have happened. 192 int calls1 = test_memory_pressure_observer()->number_of_calls(); 193 EXPECT_TRUE(calls1); 194 EXPECT_EQ(MemoryPressureObserver::MEMORY_PRESSURE_MODERATE, 195 test_memory_pressure_observer()->pressure()); 196 197 // Check to the next level. 198 test_resource_manager_delegate()->set_memory_fill_level_percent(80); 199 ASSERT_TRUE(WaitForTimer()); 200 int calls2 = test_memory_pressure_observer()->number_of_calls(); 201 EXPECT_LT(calls1, calls2); 202 EXPECT_EQ(MemoryPressureObserver::MEMORY_PRESSURE_HIGH, 203 test_memory_pressure_observer()->pressure()); 204 205 // Check to no pressure again. 206 test_resource_manager_delegate()->set_memory_fill_level_percent(20); 207 ASSERT_TRUE(WaitForTimer()); 208 int calls3 = test_memory_pressure_observer()->number_of_calls(); 209 EXPECT_LT(calls2, calls3); 210 EXPECT_EQ(MemoryPressureObserver::MEMORY_PRESSURE_LOW, 211 test_memory_pressure_observer()->pressure()); 212 213 // Even if the value does not change, we should not get any more calls. 214 ASSERT_TRUE(WaitForTimer()); 215 EXPECT_EQ(calls3, test_memory_pressure_observer()->number_of_calls()); 216 EXPECT_EQ(MemoryPressureObserver::MEMORY_PRESSURE_LOW, 217 test_memory_pressure_observer()->pressure()); 218 } 219 220 } // namespace test 221 } // namespace athena 222