OSDN Git Service

tests: don't use bt_os_callouts for wakelocks
authorMarie Janssen <jamuraa@google.com>
Mon, 16 Nov 2015 18:35:17 +0000 (10:35 -0800)
committerAndre Eisenbach <eisenbach@google.com>
Wed, 2 Dec 2015 18:14:57 +0000 (18:14 +0000)
Introduces alarm_set_wake_lock_paths so wake lock paths can be changed
for testing, and adds AlarmTestHarness::WakeLockHeld to test whether a
wake lock is currently held.

Bug: 25387683
Change-Id: I9a41ae8266e252a3d436f8d41ea3f9e7ecb45cdc

osi/include/alarm.h
osi/src/alarm.c
osi/test/AlarmTestHarness.cpp
osi/test/AlarmTestHarness.h
osi/test/AllocationTestHarness.h
osi/test/alarm_test.cpp

index 9307aac..4b3e395 100644 (file)
@@ -59,3 +59,10 @@ period_ms_t alarm_get_remaining_ms(const alarm_t *alarm);
 
 // Alarm-related state cleanup
 void alarm_cleanup(void);
+
+// This function should not need to be called normally.
+// /sys/power/wake_{|un}lock are used by default.
+// This is not guaranteed to have any effect after an alarm has been
+// set with alarm_set.
+// If |lock_path| or |unlock_path| are NULL, that path is not changed.
+void alarm_set_wake_lock_paths(const char *lock_path, const char *unlock_path);
index 3e7115f..9308ad2 100644 (file)
@@ -24,6 +24,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
+#include <limits.h>
 #include <malloc.h>
 #include <pthread.h>
 #include <signal.h>
@@ -70,8 +71,10 @@ int64_t TIMER_INTERVAL_FOR_WAKELOCK_IN_MS = 3000;
 static const clockid_t CLOCK_ID = CLOCK_BOOTTIME;
 static const clockid_t CLOCK_ID_ALARM = CLOCK_BOOTTIME_ALARM;
 static const char *WAKE_LOCK_ID = "bluetooth_timer";
-static const char *WAKE_LOCK_PATH = "/sys/power/wake_lock";
-static const char *WAKE_UNLOCK_PATH = "/sys/power/wake_unlock";
+static char *DEFAULT_WAKE_LOCK_PATH = "/sys/power/wake_lock";
+static char *DEFAULT_WAKE_UNLOCK_PATH = "/sys/power/wake_unlock";
+static char *wake_lock_path = NULL;
+static char *wake_unlock_path = NULL;
 static ssize_t locked_id_len = -1;
 static pthread_once_t wake_fds_initialized = PTHREAD_ONCE_INIT;
 static int wake_lock_fd = INVALID_FD;
@@ -214,7 +217,17 @@ void alarm_cancel(alarm_t *alarm) {
 }
 
 void alarm_cleanup(void) {
-  // If lazy_initialize never ran there is nothing to do
+  if (wake_lock_path && wake_lock_path != DEFAULT_WAKE_LOCK_PATH) {
+    osi_free(wake_lock_path);
+    wake_lock_path = NULL;
+  }
+
+  if (wake_unlock_path && wake_unlock_path != DEFAULT_WAKE_UNLOCK_PATH) {
+    osi_free(wake_unlock_path);
+    wake_unlock_path = NULL;
+  }
+
+  // If lazy_initialize never ran there is nothing else to do
   if (!alarms)
     return;
 
@@ -229,9 +242,26 @@ void alarm_cleanup(void) {
   list_free(alarms);
   alarms = NULL;
 
+  wake_fds_initialized = PTHREAD_ONCE_INIT;
+
   pthread_mutex_destroy(&monitor);
 }
 
+void alarm_set_wake_lock_paths(const char *lock_path, const char *unlock_path) {
+  if (lock_path) {
+    if (wake_lock_path && wake_lock_path != DEFAULT_WAKE_LOCK_PATH)
+      osi_free(wake_lock_path);
+    wake_lock_path = osi_strndup(lock_path, PATH_MAX);
+  }
+
+  if (unlock_path) {
+    if (wake_unlock_path && wake_unlock_path != DEFAULT_WAKE_UNLOCK_PATH)
+      osi_free(wake_unlock_path);
+    wake_unlock_path = osi_strndup(unlock_path, PATH_MAX);
+  }
+
+}
+
 static bool lazy_initialize(void) {
   assert(alarms == NULL);
 
@@ -478,16 +508,22 @@ static void callback_dispatch(UNUSED_ATTR void *context) {
 static void initialize_wake_fds(void) {
   LOG_DEBUG(LOG_TAG, "%s opening wake locks", __func__);
 
-  wake_lock_fd = open(WAKE_LOCK_PATH, O_RDWR | O_CLOEXEC);
+  if (!wake_lock_path)
+    wake_lock_path = DEFAULT_WAKE_LOCK_PATH;
+
+  wake_lock_fd = open(wake_lock_path, O_RDWR | O_CLOEXEC);
   if (wake_lock_fd == INVALID_FD) {
     LOG_ERROR(LOG_TAG, "%s can't open wake lock %s: %s",
-              __func__, WAKE_LOCK_PATH, strerror(errno));
+              __func__, wake_lock_path, strerror(errno));
   }
 
-  wake_unlock_fd = open(WAKE_UNLOCK_PATH, O_RDWR | O_CLOEXEC);
+  if (!wake_unlock_path)
+    wake_unlock_path = DEFAULT_WAKE_UNLOCK_PATH;
+
+  wake_unlock_fd = open(wake_unlock_path, O_RDWR | O_CLOEXEC);
   if (wake_unlock_fd == INVALID_FD) {
     LOG_ERROR(LOG_TAG, "%s can't open wake unlock %s: %s",
-              __func__, WAKE_UNLOCK_PATH, strerror(errno));
+              __func__, wake_unlock_path, strerror(errno));
   }
 }
 
index 1f0cdb5..39407dd 100644 (file)
  *
  ******************************************************************************/
 
-#include <gtest/gtest.h>
-#include <hardware/bluetooth.h>
+#include "AlarmTestHarness.h"
+
+#include <fcntl.h>
+#include <sys/mman.h>
 #include <unistd.h>
 
-#include "AlarmTestHarness.h"
+#include <hardware/bluetooth.h>
 
 extern "C" {
 #include "osi/include/alarm.h"
@@ -41,7 +43,6 @@ void AlarmTestHarness::SetUp() {
 
   current_harness = this;
   TIMER_INTERVAL_FOR_WAKELOCK_IN_MS = 100;
-  lock_count = 0;
 
   struct sigevent sigevent;
   memset(&sigevent, 0, sizeof(sigevent));
@@ -49,44 +50,76 @@ void AlarmTestHarness::SetUp() {
   sigevent.sigev_notify_function = (void (*)(union sigval))timer_callback;
   sigevent.sigev_value.sival_ptr = NULL;
   timer_create(CLOCK_BOOTTIME, &sigevent, &timer);
+
+  // TODO (jamuraa): maybe use base::CreateNewTempDirectory instead?
+#if defined(OS_GENERIC)
+  tmp_dir_ = "/tmp/btwlXXXXXX";
+#else  // !defined(OS_GENERIC)
+  tmp_dir_ = "/data/local/tmp/btwlXXXXXX";
+#endif  // !defined(OS_GENERIC)
+
+  char *buffer = const_cast<char *>(tmp_dir_.c_str());
+  char *dtemp = mkdtemp(buffer);
+  if (!dtemp) {
+    perror("Can't make wake lock test directory: ");
+    assert(false);
+  }
+
+  lock_path_ = tmp_dir_ + "/wake_lock";
+  unlock_path_ = tmp_dir_ + "/wake_unlock";
+
+  creat(lock_path_.c_str(), S_IRWXU);
+  creat(unlock_path_.c_str(), S_IRWXU);
+
+  alarm_set_wake_lock_paths(lock_path_.c_str(), unlock_path_.c_str());
 }
 
 void AlarmTestHarness::TearDown() {
   alarm_cleanup();
+
+  // clean up the temp wake lock directory
+  unlink(lock_path_.c_str());
+  unlink(unlock_path_.c_str());
+  rmdir(tmp_dir_.c_str());
+
   timer_delete(timer);
   AllocationTestHarness::TearDown();
 }
 
-static bool set_wake_alarm(uint64_t delay_millis, bool, alarm_cb cb, void *data) {
-  saved_callback = cb;
-  saved_data = data;
 
-  struct itimerspec wakeup_time;
-  memset(&wakeup_time, 0, sizeof(wakeup_time));
-  wakeup_time.it_value.tv_sec = (delay_millis / 1000);
-  wakeup_time.it_value.tv_nsec = (delay_millis % 1000) * 1000000LL;
-  timer_settime(timer, 0, &wakeup_time, NULL);
-  return true;
-}
+bool AlarmTestHarness::WakeLockHeld() {
+  bool held = false;
 
-static int acquire_wake_lock(const char *) {
-  if (!current_harness->lock_count)
-    current_harness->lock_count = 1;
-  return BT_STATUS_SUCCESS;
-}
+  int lock_fd = open(lock_path_.c_str(), O_RDONLY);
+  assert(lock_fd >= 0);
 
-static int release_wake_lock(const char *) {
-  if (current_harness->lock_count)
-    current_harness->lock_count = 0;
-  return BT_STATUS_SUCCESS;
-}
+  int unlock_fd = open(unlock_path_.c_str(), O_RDONLY);
+  assert(unlock_fd >= 0);
 
-static bt_os_callouts_t stub = {
-  sizeof(bt_os_callouts_t),
-  set_wake_alarm,
-  acquire_wake_lock,
-  release_wake_lock,
-};
+  struct stat lock_stat, unlock_stat;
+  fstat(lock_fd, &lock_stat);
+  fstat(unlock_fd, &unlock_stat);
 
-bt_os_callouts_t *bt_os_callouts = &stub;
+  assert(lock_stat.st_size >= unlock_stat.st_size);
 
+  void *lock_file = mmap(nullptr, lock_stat.st_size, PROT_READ,
+                         MAP_PRIVATE, lock_fd, 0);
+
+  void *unlock_file = mmap(nullptr, unlock_stat.st_size, PROT_READ,
+                           MAP_PRIVATE, unlock_fd, 0);
+
+  if (memcmp(lock_file, unlock_file, unlock_stat.st_size) == 0) {
+    held = lock_stat.st_size > unlock_stat.st_size;
+  } else {
+    // these files should always either be with a lock that has more,
+    // or equal.
+    assert(false);
+  }
+
+  munmap(lock_file, lock_stat.st_size);
+  munmap(unlock_file, unlock_stat.st_size);
+  close(lock_fd);
+  close(unlock_fd);
+
+  return held;
+}
index d4146bb..dbd09b0 100644 (file)
@@ -27,6 +27,11 @@ class AlarmTestHarness : public AllocationTestHarness {
     virtual void SetUp();
     virtual void TearDown();
 
+    std::string tmp_dir_;
+    std::string lock_path_;
+    std::string unlock_path_;
+
   public:
-    int lock_count;
+    // Returns true if a wake lock is held.
+    bool WakeLockHeld();
 };
index b906936..65fc0b0 100644 (file)
@@ -18,6 +18,8 @@
 
 #pragma once
 
+#include <gtest/gtest.h>
+
 class AllocationTestHarness : public ::testing::Test {
   protected:
     virtual void SetUp();
index 32e1103..1b4895c 100644 (file)
@@ -79,7 +79,7 @@ TEST_F(AlarmTest, test_cancel) {
   msleep(10 + EPSILON_MS);
 
   EXPECT_EQ(cb_counter, 0);
-  EXPECT_EQ(lock_count, 0);
+  EXPECT_FALSE(WakeLockHeld());;
   alarm_free(alarm);
 }
 
@@ -97,12 +97,12 @@ TEST_F(AlarmTest, test_set_short) {
   alarm_set(alarm, 10, cb, NULL);
 
   EXPECT_EQ(cb_counter, 0);
-  EXPECT_EQ(lock_count, 1);
+  EXPECT_TRUE(WakeLockHeld());
 
   semaphore_wait(semaphore);
 
   EXPECT_EQ(cb_counter, 1);
-  EXPECT_EQ(lock_count, 0);
+  EXPECT_FALSE(WakeLockHeld());
 
   alarm_free(alarm);
 }
@@ -112,12 +112,12 @@ TEST_F(AlarmTest, test_set_long) {
   alarm_set(alarm, TIMER_INTERVAL_FOR_WAKELOCK_IN_MS, cb, NULL);
 
   EXPECT_EQ(cb_counter, 0);
-  EXPECT_EQ(lock_count, 0);
+  EXPECT_FALSE(WakeLockHeld());
 
   semaphore_wait(semaphore);
 
   EXPECT_EQ(cb_counter, 1);
-  EXPECT_EQ(lock_count, 0);
+  EXPECT_FALSE(WakeLockHeld());
 
   alarm_free(alarm);
 }
@@ -132,17 +132,17 @@ TEST_F(AlarmTest, test_set_short_short) {
   alarm_set(alarm[1], 20, cb, NULL);
 
   EXPECT_EQ(cb_counter, 0);
-  EXPECT_EQ(lock_count, 1);
+  EXPECT_TRUE(WakeLockHeld());
 
   semaphore_wait(semaphore);
 
   EXPECT_EQ(cb_counter, 1);
-  EXPECT_EQ(lock_count, 1);
+  EXPECT_TRUE(WakeLockHeld());
 
   semaphore_wait(semaphore);
 
   EXPECT_EQ(cb_counter, 2);
-  EXPECT_EQ(lock_count, 0);
+  EXPECT_FALSE(WakeLockHeld());
 
   alarm_free(alarm[0]);
   alarm_free(alarm[1]);
@@ -158,17 +158,17 @@ TEST_F(AlarmTest, test_set_short_long) {
   alarm_set(alarm[1], 10 + TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL);
 
   EXPECT_EQ(cb_counter, 0);
-  EXPECT_EQ(lock_count, 1);
+  EXPECT_TRUE(WakeLockHeld());
 
   semaphore_wait(semaphore);
 
   EXPECT_EQ(cb_counter, 1);
-  EXPECT_EQ(lock_count, 0);
+  EXPECT_FALSE(WakeLockHeld());
 
   semaphore_wait(semaphore);
 
   EXPECT_EQ(cb_counter, 2);
-  EXPECT_EQ(lock_count, 0);
+  EXPECT_FALSE(WakeLockHeld());
 
   alarm_free(alarm[0]);
   alarm_free(alarm[1]);
@@ -184,17 +184,17 @@ TEST_F(AlarmTest, test_set_long_long) {
   alarm_set(alarm[1], 2 * TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL);
 
   EXPECT_EQ(cb_counter, 0);
-  EXPECT_EQ(lock_count, 0);
+  EXPECT_FALSE(WakeLockHeld());
 
   semaphore_wait(semaphore);
 
   EXPECT_EQ(cb_counter, 1);
-  EXPECT_EQ(lock_count, 0);
+  EXPECT_FALSE(WakeLockHeld());
 
   semaphore_wait(semaphore);
 
   EXPECT_EQ(cb_counter, 2);
-  EXPECT_EQ(lock_count, 0);
+  EXPECT_FALSE(WakeLockHeld());
 
   alarm_free(alarm[0]);
   alarm_free(alarm[1]);