aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBertrand SIMONNET <bsimonnet@google.com>2016-03-16 13:12:44 -0700
committerBertrand SIMONNET <bsimonnet@google.com>2016-03-21 17:24:57 -0700
commitce91d9cc8081cf805ed75fd5598a51e2fac3d5ee (patch)
treedf94575b55c17ca3fae48b1d00c6fe058b6bb5c2
parent5e56ca140ffe08d1db1fad94b4916e61b244dfc3 (diff)
downloadperipheralmanager-ce91d9cc8081cf805ed75fd5598a51e2fac3d5ee.tar.gz
Add unittests for the LEDs client interface.
Bug: 27675223 Change-Id: Id3a4739c111c8c8e6ebb828687a2c72527499ed7
-rw-r--r--client/Android.mk3
-rw-r--r--client/led_unittest.cc158
-rw-r--r--client/wrapper.cc4
-rw-r--r--daemon/led_driver_sysfs.cc9
-rw-r--r--daemon/led_driver_sysfs.h6
-rw-r--r--daemon/led_manager.cc5
-rw-r--r--daemon/led_manager.h1
-rw-r--r--daemon/peripheral_manager.cc2
-rw-r--r--daemon/peripheral_manager_client.cc2
9 files changed, 181 insertions, 9 deletions
diff --git a/client/Android.mk b/client/Android.mk
index 5b3a0ac..cd47e7f 100644
--- a/client/Android.mk
+++ b/client/Android.mk
@@ -59,7 +59,7 @@ ifdef BRILLO
LOCAL_MODULE_TAGS := debug
endif
LOCAL_CPP_EXTENSION := .cc
-LOCAL_CFLAGS := $(libperipheralman_CommonCFlags)
+LOCAL_CFLAGS := $(libperipheralman_CommonCFlags) -Wno-sign-compare
LOCAL_C_INCLUDES := $(libperipheralman_CommonCIncludes)
LOCAL_STATIC_LIBRARIES := libgtest libBionicGtestMain \
libperipheralman_binder \
@@ -72,6 +72,7 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_SRC_FILES := \
gpio_unittest.cc \
+ led_unittest.cc \
peripheral_manager_client_unittest.cc \
include $(BUILD_NATIVE_TEST)
diff --git a/client/led_unittest.cc b/client/led_unittest.cc
new file mode 100644
index 0000000..fbcba59
--- /dev/null
+++ b/client/led_unittest.cc
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <memory>
+
+#include <base/files/file_util.h>
+#include <base/files/scoped_temp_dir.h>
+#include <gtest/gtest.h>
+
+#include "led_driver_sysfs.h"
+#include "led_manager.h"
+#include "peripheral_manager.h"
+#include "peripheralmanager/led.h"
+#include "peripheralmanager/peripheral_manager_client.h"
+
+using android::LedDriverInfo;
+using android::LedDriverInfoBase;
+using android::LedDriverSysfs;
+using android::LedManager;
+using android::PeripheralManager;
+
+class LedTest : public ::testing::Test {
+ public:
+ void SetUp() {
+ CHECK(dir_.CreateUniqueTempDir());
+
+ CreateLed("led1", 255, 0);
+ CreateLed("led2", 1000, 0);
+
+ led_path_prefix_ = dir_.path().value() + "/";
+
+ // Initialize the peripheral manager with the stub binder wrapper.
+ pman_.InitForTest();
+ LedManager* man = LedManager::GetLedManager();
+
+ // Register the testing version of the LED driver and the fake LEDs.
+ man->RegisterDriver(std::unique_ptr<LedDriverInfoBase>(
+ new LedDriverInfo<LedDriverSysfs, std::string*>(&led_path_prefix_)));
+
+ man->RegisterLedSysfs("LED1", "led1");
+ man->RegisterLedSysfs("LED2", "led2");
+ }
+
+ void CreateLed(const std::string& name, int max_brightness, int brightness) {
+ base::FilePath led(dir_.path().Append(name));
+ base::CreateDirectory(led);
+
+ std::string b_str = std::to_string(brightness);
+ std::string mb_str = std::to_string(max_brightness);
+
+ ASSERT_EQ(
+ b_str.size(),
+ base::WriteFile(led.Append("brightness"), b_str.c_str(), b_str.size()));
+ ASSERT_EQ(mb_str.size(),
+ base::WriteFile(
+ led.Append("max_brightness"), mb_str.c_str(), mb_str.size()));
+ }
+
+ void TearDown() { LedManager::ResetLedManager(); }
+
+ private:
+ PeripheralManager pman_;
+ base::ScopedTempDir dir_;
+ std::string led_path_prefix_;
+};
+
+// Test that we can list the available LEDs.
+TEST_F(LedTest, CanListLeds) {
+ BPeripheralManagerClient* client = BPeripheralManagerClient_new();
+ ASSERT_NE(nullptr, client);
+
+ int nleds = -1;
+ char** leds = BPeripheralManagerClient_listLeds(client, &nleds);
+
+ EXPECT_EQ(2, nleds);
+ EXPECT_EQ("LED1", std::string(leds[0]));
+ EXPECT_EQ("LED2", std::string(leds[1]));
+
+ for (int i = 0; i < nleds; i++) {
+ free(leds[i]);
+ }
+ free(leds);
+
+ BPeripheralManagerClient_delete(client);
+}
+
+// Test that we can open an LED and act on it.
+TEST_F(LedTest, CanOpenLed) {
+ BPeripheralManagerClient* client = BPeripheralManagerClient_new();
+ ASSERT_NE(nullptr, client);
+
+ BLed* led;
+
+ ASSERT_EQ(0, BPeripheralManagerClient_openLed(client, "LED1", &led));
+
+ uint32_t max_brightness = 0;
+ EXPECT_EQ(0, BLed_getMaxBrightness(led, &max_brightness));
+ EXPECT_EQ(255, max_brightness);
+
+ uint32_t brightness = 0;
+ EXPECT_EQ(0, BLed_setBrightness(led, 10));
+ EXPECT_EQ(0, BLed_getBrightness(led, &brightness));
+ EXPECT_EQ(10, brightness);
+
+ BLed_delete(led);
+ BPeripheralManagerClient_delete(client);
+}
+
+// Test that we can't open an unexisting LED.
+TEST_F(LedTest, OpenningUnknownLed) {
+ BPeripheralManagerClient* client = BPeripheralManagerClient_new();
+ ASSERT_NE(nullptr, client);
+
+ BLed* led = nullptr;
+ EXPECT_EQ(ENODEV, BPeripheralManagerClient_openLed(client, "hello", &led));
+ EXPECT_EQ(nullptr, led);
+
+ BPeripheralManagerClient_delete(client);
+}
+
+// Test that we can't open an LED twice.
+TEST_F(LedTest, HandleConcurrentAccesses) {
+ BPeripheralManagerClient* client = BPeripheralManagerClient_new();
+ ASSERT_NE(nullptr, client);
+
+ // Can open LED1.
+ BLed* led1;
+ EXPECT_EQ(0, BPeripheralManagerClient_openLed(client, "LED1", &led1));
+
+ // Fails to open it twice.
+ BLed* led2;
+ EXPECT_EQ(EBUSY, BPeripheralManagerClient_openLed(client, "LED1", &led2));
+
+ // Can still open another LED.
+ BLed* led3;
+ EXPECT_EQ(0, BPeripheralManagerClient_openLed(client, "LED2", &led3));
+
+ // Once the LED is released, we can take ownership of it.
+ BLed_delete(led1);
+ EXPECT_EQ(0, BPeripheralManagerClient_openLed(client, "LED1", &led2));
+
+ BLed_delete(led2);
+ BLed_delete(led3);
+ BPeripheralManagerClient_delete(client);
+}
diff --git a/client/wrapper.cc b/client/wrapper.cc
index 5ef1ffc..cb13730 100644
--- a/client/wrapper.cc
+++ b/client/wrapper.cc
@@ -204,8 +204,8 @@ void BSpiDevice_delete(BSpiDevice* device) {
delete device;
}
-char** BPeripheralManagerClient_listLed(const BPeripheralManagerClient* client,
- int* num_leds) {
+char** BPeripheralManagerClient_listLeds(const BPeripheralManagerClient* client,
+ int* num_leds) {
std::vector<std::string> list;
client->impl->ListLeds(&list);
*num_leds = list.size();
diff --git a/daemon/led_driver_sysfs.cc b/daemon/led_driver_sysfs.cc
index b4e4d85..0292082 100644
--- a/daemon/led_driver_sysfs.cc
+++ b/daemon/led_driver_sysfs.cc
@@ -33,7 +33,8 @@ const char kBrightnessFilename[] = "brightness";
} // namespace
-LedDriverSysfs::LedDriverSysfs(void* arg) : fd_(-1) {}
+LedDriverSysfs::LedDriverSysfs(std::string* prefix)
+ : fd_(-1), prefix_(prefix) {}
LedDriverSysfs::~LedDriverSysfs() {
if (fd_ >= 0) {
@@ -43,7 +44,9 @@ LedDriverSysfs::~LedDriverSysfs() {
bool LedDriverSysfs::Init(const std::string& name) {
LOG(INFO) << "Opening " << name;
- std::string path = kSysfsLedPathPrefix + name;
+
+ // If a custom prefix was defined, use it.
+ std::string path = prefix_ ? *prefix_ + name : kSysfsLedPathPrefix + name;
int fd = open(path.c_str(), O_RDONLY);
if (fd < 0) {
@@ -103,4 +106,4 @@ bool LedDriverSysfs::WriteToFile(const std::string& file,
return true;
}
-} // namespace android \ No newline at end of file
+} // namespace android
diff --git a/daemon/led_driver_sysfs.h b/daemon/led_driver_sysfs.h
index 0d5ade0..ef14717 100644
--- a/daemon/led_driver_sysfs.h
+++ b/daemon/led_driver_sysfs.h
@@ -27,7 +27,7 @@ namespace android {
class LedDriverSysfs : public LedDriverInterface {
public:
- LedDriverSysfs(void* arg);
+ LedDriverSysfs(std::string* prefix);
~LedDriverSysfs();
static std::string Compat() { return "LEDSYSFS"; }
@@ -43,6 +43,10 @@ class LedDriverSysfs : public LedDriverInterface {
int fd_;
+ // Used for unit test only.
+ // Ownership is in the test.
+ std::string* prefix_;
+
DISALLOW_COPY_AND_ASSIGN(LedDriverSysfs);
};
diff --git a/daemon/led_manager.cc b/daemon/led_manager.cc
index f8173ad..72e200f 100644
--- a/daemon/led_manager.cc
+++ b/daemon/led_manager.cc
@@ -34,6 +34,11 @@ LedManager* LedManager::GetLedManager() {
return g_led_manager.get();
}
+// static
+void LedManager::ResetLedManager() {
+ g_led_manager.reset();
+}
+
bool LedManager::RegisterDriver(
std::unique_ptr<LedDriverInfoBase> driver_info) {
std::string key = driver_info->Compat();
diff --git a/daemon/led_manager.h b/daemon/led_manager.h
index 2a9710b..66681e3 100644
--- a/daemon/led_manager.h
+++ b/daemon/led_manager.h
@@ -68,6 +68,7 @@ class LedManager {
// Get the singleton.
static LedManager* GetLedManager();
+ static void ResetLedManager();
// Used by the BSP to tell PMan of an sysfs led.
bool RegisterLedSysfs(const std::string& name, const std::string& led_name);
diff --git a/daemon/peripheral_manager.cc b/daemon/peripheral_manager.cc
index be58ad9..d24cbe0 100644
--- a/daemon/peripheral_manager.cc
+++ b/daemon/peripheral_manager.cc
@@ -159,7 +159,7 @@ bool PeripheralManager::RegisterDrivers() {
}
if (!LedManager::GetLedManager()->RegisterDriver(
std::unique_ptr<LedDriverInfoBase>(
- new LedDriverInfo<LedDriverSysfs, void*>(nullptr)))) {
+ new LedDriverInfo<LedDriverSysfs, std::string*>(nullptr)))) {
LOG(ERROR) << "Failed to load driver: LedDriverSysfs";
return false;
}
diff --git a/daemon/peripheral_manager_client.cc b/daemon/peripheral_manager_client.cc
index 051f2fb..7779775 100644
--- a/daemon/peripheral_manager_client.cc
+++ b/daemon/peripheral_manager_client.cc
@@ -246,7 +246,7 @@ Status PeripheralManagerClient::OpenLed(const std::string& name) {
}
auto led = LedManager::GetLedManager()->OpenLed(name);
if (!led) {
- LOG(ERROR) << "Failed to open LED" << name;
+ LOG(ERROR) << "Failed to open LED " << name;
return Status::fromServiceSpecificError(EBUSY);
}