aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBertrand SIMONNET <bsimonnet@google.com>2016-03-15 17:06:45 -0700
committerBertrand SIMONNET <bsimonnet@google.com>2016-03-16 13:14:59 -0700
commit1d56dd24b6f6f811601de5baf4c2afa5e4ba8952 (patch)
tree7592fec7ec586a084bd5e9e52952070a0b72d3f3
parent99867e2357be2b06e676f43a32ece79e2e35581f (diff)
downloadperipheralmanager-1d56dd24b6f6f811601de5baf4c2afa5e4ba8952.tar.gz
Add unit tests for the Gpio C API.
This tests that: * the C API is correctly implemented. * the C/C++ to AIDL conversion is done properly. * the peripheral manager client tracks ownership correctly. Bug: 27675223 Change-Id: Ie7ce869b381fcf544af967826c62f283b7ddb61c
-rw-r--r--client/Android.mk7
-rw-r--r--client/gpio_unittest.cc150
-rw-r--r--daemon/Android.mk53
-rw-r--r--daemon/gpio_driver_mock.h51
-rw-r--r--daemon/gpio_manager.cc4
-rw-r--r--daemon/gpio_manager.h3
-rw-r--r--daemon/peripheral_manager.cc6
-rw-r--r--daemon/peripheral_manager.h6
8 files changed, 264 insertions, 16 deletions
diff --git a/client/Android.mk b/client/Android.mk
index dc1ba38..5b3a0ac 100644
--- a/client/Android.mk
+++ b/client/Android.mk
@@ -61,12 +61,17 @@ endif
LOCAL_CPP_EXTENSION := .cc
LOCAL_CFLAGS := $(libperipheralman_CommonCFlags)
LOCAL_C_INCLUDES := $(libperipheralman_CommonCIncludes)
-LOCAL_STATIC_LIBRARIES := libgtest libBionicGtestMain
+LOCAL_STATIC_LIBRARIES := libgtest libBionicGtestMain \
+ libperipheralman_binder \
+ libperipheralman_internal_test \
+ libgmock \
+
LOCAL_SHARED_LIBRARIES := \
$(libperipheralman_CommonSharedLibraries) \
libperipheralman \
LOCAL_SRC_FILES := \
+ gpio_unittest.cc \
peripheral_manager_client_unittest.cc \
include $(BUILD_NATIVE_TEST)
diff --git a/client/gpio_unittest.cc b/client/gpio_unittest.cc
new file mode 100644
index 0000000..bdcaffd
--- /dev/null
+++ b/client/gpio_unittest.cc
@@ -0,0 +1,150 @@
+/*
+ * 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 <gtest/gtest.h>
+
+#include "gpio_driver_mock.h"
+#include "peripheral_manager.h"
+#include "peripheralmanager/gpio.h"
+#include "peripheralmanager/peripheral_manager_client.h"
+
+using android::GpioDriverInfo;
+using android::GpioDriverInfoBase;
+using android::GpioDriverMock;
+using android::GpioManager;
+using android::PeripheralManager;
+
+// Base class used to test the Gpio C API.
+// As we rely on static, global managers, we cannot run this tests in parallel.
+// Please use -j1 when running theses tests or you may see false negatives.
+class GpioTest : public ::testing::Test {
+ public:
+ void SetUp() {
+ pman_.InitForTest();
+ GpioManager* man = GpioManager::GetGpioManager();
+ man->RegisterDriver(std::unique_ptr<GpioDriverInfoBase>(
+ new GpioDriverInfo<GpioDriverMock, void*>(nullptr)));
+
+ man->RegisterGpioSysfs("IO1", 1);
+ man->RegisterGpioSysfs("IO2", 2);
+ man->RegisterGpioSysfs("IO3", 3);
+ man->RegisterGpioSysfs("IO4", 4);
+ man->RegisterGpioSysfs("IO5", 5);
+ }
+
+ void TearDown() { GpioManager::ResetGpioManager(); }
+
+ private:
+ PeripheralManager pman_;
+};
+
+// Test that we list the Gpios available correctly.
+TEST_F(GpioTest, CanListGpios) {
+ BPeripheralManagerClient* client = BPeripheralManagerClient_new();
+ ASSERT_NE(nullptr, client);
+
+ int ngpios;
+ char** list = BPeripheralManagerClient_listGpio(client, &ngpios);
+
+ EXPECT_EQ(5, ngpios);
+ EXPECT_EQ("IO1", std::string(list[0]));
+ EXPECT_EQ("IO2", std::string(list[1]));
+ EXPECT_EQ("IO3", std::string(list[2]));
+ EXPECT_EQ("IO4", std::string(list[3]));
+ EXPECT_EQ("IO5", std::string(list[4]));
+
+ // Free the list.
+ for (int i = 0; i < 5; i++) {
+ free(list[i]);
+ }
+ free(list);
+}
+
+// Test that we can open a Gpio and act on it.
+TEST_F(GpioTest, CanOpenGpio) {
+ BPeripheralManagerClient* client = BPeripheralManagerClient_new();
+ ASSERT_NE(nullptr, client);
+
+ BGpio* gpio;
+ EXPECT_EQ(0, BPeripheralManagerClient_openGpio(client, "IO1", &gpio));
+ ASSERT_NE(nullptr, gpio);
+
+ // Can set the direction. If the direction is invalid, we fail.
+ EXPECT_EQ(0, BGpio_setDirection(gpio, DIRECTION_OUT_INITIALLY_HIGH));
+ EXPECT_EQ(EINVAL, BGpio_setDirection(gpio, 10));
+
+ // Can set the value.
+ EXPECT_EQ(0, BGpio_setValue(gpio, 1));
+
+ // Can set the active type. If the type is unknown, we fail.
+ EXPECT_EQ(0, BGpio_setActiveType(gpio, ACTIVE_LOW));
+ EXPECT_EQ(EINVAL, BGpio_setActiveType(gpio, 5));
+
+ EXPECT_EQ(0, BGpio_setDirection(gpio, DIRECTION_IN));
+
+ // Can read the value from the Gpio.
+ int value;
+ EXPECT_EQ(0, BGpio_getValue(gpio, &value));
+
+ // Can set the edge type. If the type is unknown, we fail.
+ EXPECT_EQ(0, BGpio_setEdgeTriggerType(gpio, RISING_EDGE));
+ EXPECT_EQ(EINVAL, BGpio_setEdgeTriggerType(gpio, -1));
+
+ BGpio_delete(gpio);
+ BPeripheralManagerClient_delete(client);
+}
+
+// Test that openning an unknown Gpio fails.
+TEST_F(GpioTest, OpenningUnknownGpioFails) {
+ BPeripheralManagerClient* client = BPeripheralManagerClient_new();
+ ASSERT_NE(nullptr, client);
+
+ BGpio* gpio = nullptr;
+ EXPECT_EQ(ENODEV,
+ BPeripheralManagerClient_openGpio(client, "unknown", &gpio));
+ EXPECT_EQ(nullptr, gpio);
+
+ BPeripheralManagerClient_delete(client);
+}
+
+// Test that we track ownership correctly (can't open a Gpio twice).
+TEST_F(GpioTest, GpioOnlyOpenedOnce) {
+ BPeripheralManagerClient* client = BPeripheralManagerClient_new();
+ ASSERT_NE(nullptr, client);
+
+ BGpio* gpio1;
+ BGpio* gpio2;
+ BGpio* gpio3;
+
+ EXPECT_EQ(0, BPeripheralManagerClient_openGpio(client, "IO1", &gpio1));
+ EXPECT_NE(nullptr, gpio1);
+
+ // Can't open the same Gpio.
+ EXPECT_EQ(EBUSY, BPeripheralManagerClient_openGpio(client, "IO1", &gpio2));
+
+ // Can open another Gpio.
+ EXPECT_EQ(0, BPeripheralManagerClient_openGpio(client, "IO3", &gpio3));
+
+ // Once we delete the struct, the Gpio is released and we can open it.
+ BGpio_delete(gpio1);
+ EXPECT_EQ(0, BPeripheralManagerClient_openGpio(client, "IO1", &gpio2));
+
+ BGpio_delete(gpio2);
+ BGpio_delete(gpio3);
+ BPeripheralManagerClient_delete(client);
+}
diff --git a/daemon/Android.mk b/daemon/Android.mk
index caf1a3d..c8410da 100644
--- a/daemon/Android.mk
+++ b/daemon/Android.mk
@@ -30,6 +30,20 @@ peripheralman_CommonSharedLibraries := \
libutils \
libhardware \
+libperipheralman_internal_CommonSources := \
+ char_device.cc \
+ gpio_driver_sysfs.cc \
+ gpio_manager.cc \
+ i2c_driver_i2cdev.cc \
+ i2c_manager.cc \
+ led_driver_sysfs.cc \
+ led_manager.cc \
+ peripheral_manager.cc \
+ peripheral_manager_client.cc \
+ pin_mux_manager.cc \
+ spi_driver_spidev.cc \
+ spi_manager.cc \
+
# peripheralman executable
# ========================================================
@@ -70,20 +84,33 @@ LOCAL_STATIC_LIBRARIES := \
LOCAL_SHARED_LIBRARIES := \
$(peripheralman_CommonSharedLibraries) \
-LOCAL_SRC_FILES := \
- char_device.cc \
- gpio_driver_sysfs.cc \
- gpio_manager.cc \
- i2c_driver_i2cdev.cc \
- i2c_manager.cc \
- led_driver_sysfs.cc \
- led_manager.cc \
- peripheral_manager.cc \
- peripheral_manager_client.cc \
- pin_mux_manager.cc \
- spi_driver_spidev.cc \
- spi_manager.cc \
+LOCAL_SRC_FILES := $(libperipheralman_internal_CommonSources)
+include $(BUILD_STATIC_LIBRARY)
+
+# libperipheral_internal_test static lib used to test the client.
+# ===============================================================
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libperipheralman_internal_test
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_CFLAGS := $(peripheralman_CommonCFlags)
+LOCAL_C_INCLUDES := $(peripheralman_CommonCIncludes)
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/../include \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/../hal \
+
+LOCAL_STATIC_LIBRARIES := \
+ libperipheralman_binder \
+ peripheral_manager_hal_headers \
+
+LOCAL_SHARED_LIBRARIES := \
+ libbinder \
+ libbinderwrapper_test_support \
+ libchrome \
+ libutils \
+ libhardware \
+LOCAL_SRC_FILES := $(libperipheralman_internal_CommonSources)
include $(BUILD_STATIC_LIBRARY)
# peripheralman internals library for host tests
diff --git a/daemon/gpio_driver_mock.h b/daemon/gpio_driver_mock.h
new file mode 100644
index 0000000..0025325
--- /dev/null
+++ b/daemon/gpio_driver_mock.h
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+#ifndef SYSTEM_PERIPHERALMANAGER_DAEMON_GPIO_DRIVER_MOCK_H_
+#define SYSTEM_PERIPHERALMANAGER_DAEMON_GPIO_DRIVER_MOCK_H_
+
+#include <stdint.h>
+
+#include <base/macros.h>
+#include <gmock/gmock.h>
+
+#include "gpio_driver.h"
+
+namespace android {
+
+class GpioDriverMock : public GpioDriverInterface {
+ public:
+ GpioDriverMock(void* arg) {}
+ ~GpioDriverMock() {}
+
+ static std::string Compat() { return "GPIOSYSFS"; }
+
+ bool Init(uint32_t index) { return true; }
+
+ bool SetValue(bool val) { return true; };
+ bool GetValue(bool* val) { return true; };
+ bool SetActiveType(GpioActiveType type) { return true; };
+ bool SetDirection(GpioDirection direction) { return true; };
+ bool SetEdgeType(GpioEdgeType type) { return true; };
+ bool GetPollingFd(ScopedFd* fd) { return true; };
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(GpioDriverMock);
+};
+
+} // namespace android
+
+#endif // SYSTEM_PERIPHERALMANAGER_DAEMON_GPIO_DRIVER_MOCK_H_
diff --git a/daemon/gpio_manager.cc b/daemon/gpio_manager.cc
index 062b3af..1a47941 100644
--- a/daemon/gpio_manager.cc
+++ b/daemon/gpio_manager.cc
@@ -34,6 +34,10 @@ GpioManager* GpioManager::GetGpioManager() {
return g_gpio_manager.get();
}
+void GpioManager::ResetGpioManager() {
+ g_gpio_manager.reset();
+}
+
bool GpioManager::RegisterGpioSysfs(const std::string& name, uint32_t index) {
if (sysfs_pins_.count(name))
return false;
diff --git a/daemon/gpio_manager.h b/daemon/gpio_manager.h
index dd60024..a72431a 100644
--- a/daemon/gpio_manager.h
+++ b/daemon/gpio_manager.h
@@ -90,6 +90,9 @@ class GpioManager {
// Get the singleton.
static GpioManager* GetGpioManager();
+ // Delete the GpioManager (used for test);
+ static void ResetGpioManager();
+
// Used by the BSP to tell PMan of an GPIO Pin.
bool RegisterGpioSysfs(const std::string& name, uint32_t index);
bool SetPinMux(const std::string& name, const std::string& mux);
diff --git a/daemon/peripheral_manager.cc b/daemon/peripheral_manager.cc
index 5d81b77..be58ad9 100644
--- a/daemon/peripheral_manager.cc
+++ b/daemon/peripheral_manager.cc
@@ -113,6 +113,12 @@ bool PeripheralManager::Init() {
return BinderWrapper::Get()->RegisterService(interface_desc.string(), this);
}
+bool PeripheralManager::InitForTest() {
+ BinderWrapper::Create();
+ String8 interface_desc(getInterfaceDescriptor());
+ return BinderWrapper::Get()->RegisterService(interface_desc.string(), this);
+}
+
Status PeripheralManager::GetClient(const sp<IBinder>& lifeline,
sp<os::IPeripheralManagerClient>* client) {
sp<PeripheralManagerClient> c = new PeripheralManagerClient;
diff --git a/daemon/peripheral_manager.h b/daemon/peripheral_manager.h
index 272085a..a1e354f 100644
--- a/daemon/peripheral_manager.h
+++ b/daemon/peripheral_manager.h
@@ -38,6 +38,8 @@ class PeripheralManager : public BnPeripheralManager,
bool Init();
+ bool InitForTest();
+
// IPeripheralManager Interface
Status GetClient(const sp<IBinder>& lifeline,
sp<os::IPeripheralManagerClient>* _aidl_return);
@@ -47,9 +49,9 @@ class PeripheralManager : public BnPeripheralManager,
private:
bool InitHal();
bool RegisterDrivers();
-
+
std::map<IBinder*, sp<PeripheralManagerClient>> mapping_;
-
+
DISALLOW_COPY_AND_ASSIGN(PeripheralManager);
};