diff options
author | Bertrand SIMONNET <bsimonnet@google.com> | 2016-03-15 17:06:45 -0700 |
---|---|---|
committer | Bertrand SIMONNET <bsimonnet@google.com> | 2016-03-16 13:14:59 -0700 |
commit | 1d56dd24b6f6f811601de5baf4c2afa5e4ba8952 (patch) | |
tree | 7592fec7ec586a084bd5e9e52952070a0b72d3f3 | |
parent | 99867e2357be2b06e676f43a32ece79e2e35581f (diff) | |
download | peripheralmanager-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.mk | 7 | ||||
-rw-r--r-- | client/gpio_unittest.cc | 150 | ||||
-rw-r--r-- | daemon/Android.mk | 53 | ||||
-rw-r--r-- | daemon/gpio_driver_mock.h | 51 | ||||
-rw-r--r-- | daemon/gpio_manager.cc | 4 | ||||
-rw-r--r-- | daemon/gpio_manager.h | 3 | ||||
-rw-r--r-- | daemon/peripheral_manager.cc | 6 | ||||
-rw-r--r-- | daemon/peripheral_manager.h | 6 |
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); }; |