Home | History | Annotate | Download | only in test
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2016 Google, Inc.
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 #include <gtest/gtest.h>
     20 
     21 #include <base/logging.h>
     22 #include <fcntl.h>
     23 #include <sys/mman.h>
     24 #include <sys/stat.h>
     25 #include <sys/types.h>
     26 
     27 #include "osi/include/wakelock.h"
     28 
     29 #include "AllocationTestHarness.h"
     30 
     31 static bool is_wake_lock_acquired = false;
     32 
     33 static int acquire_wake_lock_cb(const char* lock_name) {
     34   is_wake_lock_acquired = true;
     35   return BT_STATUS_SUCCESS;
     36 }
     37 
     38 static int release_wake_lock_cb(const char* lock_name) {
     39   is_wake_lock_acquired = false;
     40   return BT_STATUS_SUCCESS;
     41 }
     42 
     43 static bt_os_callouts_t bt_wakelock_callouts = {
     44     sizeof(bt_os_callouts_t), NULL, acquire_wake_lock_cb, release_wake_lock_cb};
     45 
     46 class WakelockTest : public AllocationTestHarness {
     47  protected:
     48   virtual void SetUp() {
     49     AllocationTestHarness::SetUp();
     50 
     51 // TODO (jamuraa): maybe use base::CreateNewTempDirectory instead?
     52 #if defined(OS_GENERIC)
     53     tmp_dir_ = "/tmp/btwlXXXXXX";
     54 #else
     55     tmp_dir_ = "/data/local/tmp/btwlXXXXXX";
     56 #endif  // !defined(OS_GENERIC)
     57 
     58     char* buffer = const_cast<char*>(tmp_dir_.c_str());
     59     char* dtemp = mkdtemp(buffer);
     60     if (!dtemp) {
     61       perror("Can't make wake lock test directory: ");
     62       CHECK(false);
     63     }
     64 
     65     lock_path_ = tmp_dir_ + "/wake_lock";
     66     unlock_path_ = tmp_dir_ + "/wake_unlock";
     67 
     68     creat(lock_path_.c_str(), S_IRWXU);
     69     creat(unlock_path_.c_str(), S_IRWXU);
     70   }
     71 
     72   virtual void TearDown() {
     73     is_wake_lock_acquired = false;
     74     wakelock_cleanup();
     75     wakelock_set_os_callouts(NULL);
     76 
     77     // Clean up the temp wake lock directory
     78     unlink(lock_path_.c_str());
     79     unlink(unlock_path_.c_str());
     80     rmdir(tmp_dir_.c_str());
     81 
     82     AllocationTestHarness::TearDown();
     83   }
     84 
     85   //
     86   // Test whether the file-based wakelock is acquired.
     87   //
     88   bool IsFileWakeLockAcquired() {
     89     bool acquired = false;
     90 
     91     int lock_fd = open(lock_path_.c_str(), O_RDONLY);
     92     CHECK(lock_fd >= 0);
     93 
     94     int unlock_fd = open(unlock_path_.c_str(), O_RDONLY);
     95     CHECK(unlock_fd >= 0);
     96 
     97     struct stat lock_stat, unlock_stat;
     98     fstat(lock_fd, &lock_stat);
     99     fstat(unlock_fd, &unlock_stat);
    100 
    101     CHECK(lock_stat.st_size >= unlock_stat.st_size);
    102 
    103     void* lock_file =
    104         mmap(nullptr, lock_stat.st_size, PROT_READ, MAP_PRIVATE, lock_fd, 0);
    105 
    106     void* unlock_file = mmap(nullptr, unlock_stat.st_size, PROT_READ,
    107                              MAP_PRIVATE, unlock_fd, 0);
    108 
    109     if (memcmp(lock_file, unlock_file, unlock_stat.st_size) == 0) {
    110       acquired = lock_stat.st_size > unlock_stat.st_size;
    111     } else {
    112       // these files should always either be with a lock that has more,
    113       // or equal.
    114       CHECK(false);
    115     }
    116 
    117     munmap(lock_file, lock_stat.st_size);
    118     munmap(unlock_file, unlock_stat.st_size);
    119     close(lock_fd);
    120     close(unlock_fd);
    121 
    122     return acquired;
    123   }
    124 
    125   std::string tmp_dir_;
    126   std::string lock_path_;
    127   std::string unlock_path_;
    128 };
    129 
    130 TEST_F(WakelockTest, test_set_os_callouts) {
    131   wakelock_set_os_callouts(&bt_wakelock_callouts);
    132 
    133   // Initially, the wakelock is not acquired
    134   ASSERT_FALSE(is_wake_lock_acquired);
    135 
    136   for (size_t i = 0; i < 1000; i++) {
    137     wakelock_acquire();
    138     ASSERT_TRUE(is_wake_lock_acquired);
    139     wakelock_release();
    140     ASSERT_FALSE(is_wake_lock_acquired);
    141   }
    142 }
    143 
    144 TEST_F(WakelockTest, test_set_paths) {
    145   wakelock_set_os_callouts(NULL);  // Make sure we use native wakelocks
    146   wakelock_set_paths(lock_path_.c_str(), unlock_path_.c_str());
    147 
    148   // Initially, the wakelock is not acquired
    149   ASSERT_FALSE(IsFileWakeLockAcquired());
    150 
    151   for (size_t i = 0; i < 1000; i++) {
    152     wakelock_acquire();
    153     ASSERT_TRUE(IsFileWakeLockAcquired());
    154     wakelock_release();
    155     ASSERT_FALSE(IsFileWakeLockAcquired());
    156   }
    157 }
    158