Home | History | Annotate | Download | only in resource_manager
      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