Add unit testing framework

pull/7819/head
Lari-Matias Orjala 2018-08-17 17:37:11 +03:00
parent 3c25b96441
commit 4dde13db6d
62 changed files with 3934 additions and 1 deletions

1
UNITTESTS/.mbedignore Normal file
View File

@ -0,0 +1 @@
*

169
UNITTESTS/CMakeLists.txt Normal file
View File

@ -0,0 +1,169 @@
cmake_minimum_required(VERSION 3.0.2)
set(PROJECT_NAME unittests)
set(LIB_NAME MbedOS)
project(${PROJECT_NAME})
# Setup c++ standard
macro(use_cxx14)
if (CMAKE_VERSION VERSION_LESS 3.1)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++98")
endif()
else()
set(CMAKE_CXX_STANDARD 98)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
endif()
endmacro()
use_cxx14()
####################
# GTEST
####################
# Download and unpack googletest at configure time
configure_file(googletest-CMakeLists.txt.in googletest-download/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download)
if (result)
message(FATAL_ERROR "CMake failed for google test: ${result}")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download)
if (result)
message(FATAL_ERROR "Build failed for google test: ${result}")
endif()
# Prevent overriding the parent project's compiler/linker
# settings on Windows
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
# Add googletest directly to our build. This defines
# the gtest and gtest_main targets.
add_subdirectory(${CMAKE_BINARY_DIR}/googletest-src
${CMAKE_BINARY_DIR}/googletest-build
EXCLUDE_FROM_ALL)
# The gtest/gtest_main/gmock/gmock_main targets carry header search path
# dependencies automatically when using CMake 2.8.11 or
# later.
target_include_directories(gmock_main SYSTEM BEFORE INTERFACE
"${gtest_SOURCE_DIR}/include"
"${gmock_SOURCE_DIR}/include")
####################
# TESTING
####################
enable_testing()
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES
"${CMAKE_BINARY_DIR}/Testing"
)
####################
# CODE COVERAGE SETUP
####################
if (COVERAGE)
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
message(WARNING "Non-debug build may result misleading code coverage results.")
endif()
# Append coverage compiler flags
set(COVERAGE_COMPILER_FLAGS "-g -O0 --coverage -fprofile-arcs -ftest-coverage")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_COMPILER_FLAGS}")
endif(COVERAGE)
####################
# UNIT TESTS
####################
# Set include dirs.
set(unittest-includes-base
"${PROJECT_SOURCE_DIR}/target_h"
"${PROJECT_SOURCE_DIR}/target_h/events"
"${PROJECT_SOURCE_DIR}/stubs"
"${PROJECT_SOURCE_DIR}/.."
"${PROJECT_SOURCE_DIR}/../features"
"${PROJECT_SOURCE_DIR}/../platform"
"${PROJECT_SOURCE_DIR}/../drivers"
"${PROJECT_SOURCE_DIR}/../hal"
"${PROJECT_SOURCE_DIR}/../events"
"${PROJECT_SOURCE_DIR}/../rtos/TARGET_CORTEX"
"${PROJECT_SOURCE_DIR}/../rtos/TARGET_CORTEX/rtx5/Include"
"${PROJECT_SOURCE_DIR}/../cmsis"
)
# Create a list for test suites.
set(TEST_SUITES)
# Get all matched tests.
file(GLOB_RECURSE unittest-file-list
"unittest.cmake"
)
if ("${unittest-file-list}" STREQUAL "")
message(FATAL_ERROR "No tests found. Exiting...")
endif()
# Create unit test targets
foreach(testfile ${unittest-file-list})
####################
# DEFINE TARGETS
####################
# Init file lists.
set(unittest-includes ${unittest-includes-base})
set(unittest-sources)
set(unittest-test-sources)
# Get source files
include("${testfile}")
if(TEST_SUITE_NAME)
set(TEST_SUITES ${TEST_SUITES} ${TEST_SUITE_NAME})
else()
message(FATAL_ERROR "No TEST_SUITE_NAME found in test file. Add it to ${testfile}.")
endif()
set(LIBS_TO_BE_LINKED gmock_main)
# Build directories list
set(BUILD_DIRECTORIES)
if (unittest-sources)
# Create the testable static library.
add_library("${TEST_SUITE_NAME}.${LIB_NAME}" STATIC ${unittest-sources})
target_include_directories("${TEST_SUITE_NAME}.${LIB_NAME}" PRIVATE
${unittest-includes})
set(LIBS_TO_BE_LINKED ${LIBS_TO_BE_LINKED} "${TEST_SUITE_NAME}.${LIB_NAME}")
# Append lib build directory to list
list(APPEND BUILD_DIRECTORIES "./CMakeFiles/${TEST_SUITE_NAME}.${LIB_NAME}.dir")
endif(unittest-sources)
if (unittest-test-sources)
# Create the executable.
add_executable(${TEST_SUITE_NAME} ${unittest-test-sources})
target_include_directories(${TEST_SUITE_NAME} PRIVATE
${unittest-includes})
# Link the executable with the libraries.
target_link_libraries(${TEST_SUITE_NAME} ${LIBS_TO_BE_LINKED})
add_test(NAME "${TEST_SUITE_NAME}UnitTests" COMMAND ${TEST_SUITE_NAME})
# Append test build directory to list
list(APPEND BUILD_DIRECTORIES "./CMakeFiles/${TEST_SUITE_NAME}.dir")
else()
message(WARNING "No test source files found for ${TEST_SUITE_NAME}.\n")
endif(unittest-test-sources)
endforeach(testfile)

View File

@ -0,0 +1,30 @@
{
"configurations": [
{
"name": "GNU-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": [ "mingw64" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"environments": [
{
"environment": "mingw64"
}
]
},
{
"name": "GNU-Release",
"generator": "Ninja",
"configurationType": "Release",
"inheritEnvironments": [ "mingw64" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"environments": [
{
"environment": "mingw64"
}
]
}
]
}

294
UNITTESTS/README.md Normal file
View File

@ -0,0 +1,294 @@
# Unit testing Mbed OS
This document describes how to run and write unit tests for Mbed OS.
## Prerequisites
* GNU toolchains installed.
* GCC 6 or later
* MinGW-W64 GCC-6.4.0 or MinGW-W64 GCC-7.3.0 (Windows)
* CMake 3.0+ installed.
* Python 2.7.x or >3.5 and pip 10.0 (or newer) installed.
* gcovr >=4.1
### Installing dependencies on Debian/Ubuntu
1. `sudo apt-get -y install build-essential cmake`
2. Install python and pip:
```
sudo apt-get -y install python python-setuptools
sudo easy_install pip
```
3. Install [gcovr](#installing-covr).
4. (Optional) Install [Mbed CLI](https://os.mbed.com/docs/latest/tools/arm-mbed-cli.html).
### Installing dependencies on Mac OS
1. Install [Homebrew](https://brew.sh/).
2. Install gcc compilers and cmake with: `brew install gcc cmake`
3. Install python and pip:
```
brew install python
sudo easy_install pip
```
3. Install [gcovr](#installing-covr).
4. (Optional) Install [Mbed CLI](https://os.mbed.com/docs/latest/tools/arm-mbed-cli.html).
### Installing dependencies on Windows
1. Download and install [MinGW-W64](http://mingw-w64.org/).
2. Download CMake binaries from https://cmake.org/download/ and run the installer.
3. Download Python2.7 or Python3 from https://www.python.org/getit/ and run the installer.
4. Add MinGW, CMake and Python into PATH.
5. Install [gcovr](#installing-covr).
6. (Optional) Install [Mbed CLI](https://os.mbed.com/docs/latest/tools/arm-mbed-cli.html).
### Installing covr
Install gcovr code coverage tool globally with `pip install 'gcovr>=4.1'` or using virtualenv:
#### virtualenv
1. Install virtualenv if not installed with `pip install virtualenv`
2. Install gcovr with:
**[Debian/Linux/Mac OS]**
```
virtualenv pyenv
. pyenv/bin/activate
pip install 'gcovr>=4.1'
```
**[Windows]**
```
virtualenv pyenv
pyenv\\Scripts\\activate
pip install 'gcovr>=4.1'
```
## Building and running unit tests
> In case of running into problems see [troubleshooting](#troubleshooting) section.
`UNITTESTS/mbed_unittest.py` contains testing scripts for Mbed OS unit testing. Mbed CLI supports unit testing through `mbed unittest` command with the same arguments.
### Testing with Mbed CLI
```
mbed unittest
```
A subset of tests can be run by providing `-r` flag for the tool which runs tests matching a regular expression.
e.g. `mbed unittest --run -r features_netsocket`
### Build manually without Python tools
1. Create a build directory e.g. `mkdir UNITTESTS/build`.
2. Move to the build directory `cd UNITTESTS/build`.
3. Run CMake with `cmake [RELATIVE PATH TO UNITTESTS DIR] [OPTIONAL ARGUMENTS]` e.g. `cmake ..`:
* Add `-g [generator]` argument if target other than Unix Makefiles e.g. MinGW `-g "MinGW Makefiles"`
4. Run make program (make, gmake, mingw32-make, etc).
##### Run CMake and build Unix Makefiles (GNU make)
```
cmake ..
make
```
##### Run CMake and build MinGW Makefiles (mingw32-make)
```
cmake -G "MinGW Makefiles" ..
mingw32-make
```
#### Custom CMake variables
Usage:
`cmake [RELATIVE PATH TO UNITTESTS DIR] [OPTIONS]`
Keyword variables (usage `cmake -D<VARIABLE>(:<TYPE>)=<value>`:
| Variable | Type | Accepted values | Description |
| -------- | ---- | --------------- | ----------- |
| COVERAGE | STRING | merged<br>separate | Generate merged or individual reports |
### Run in terminal
Unit tests can be run separately from each executable or by using ctest test runner. Run ctest with make program using target test. Options can be passed to ctest using ARGS argument. See [ctest manual](https://cmake.org/cmake/help/v3.0/manual/ctest.1.html) for more information.
Run ctest on test suite level:
```
{MAKE_PROGRAM} test -C [RELATIVE PATH TO BUILD DIRECTORY]
```
e.g. `make test -C UNITTESTS/build` or `mingw32-make test -C UNITTESTS/build`
Run ctest verbose (show each test case):
```
{MAKE_PROGRAM} test -C UNITTESTS/build ARGS="-V"
```
Run ctest dashboard test and create test results:
```
{MAKE_PROGRAM} test --C UNITTESTS/build ARGS="-D ExperimentalTest"
```
### Run with GUI test runner
1. Build and/or install *gtest-runner* using the documentation: https://github.com/nholthaus/gtest-runner
2. Run the application, add built test executables into the list and run it.
### Get code coverage
Python tools use gcovr to build code coverage reports. Generate html report `UNITTESTS/build/coverage/index.html` with:
```
mbed unittest --coverage html
```
To get coverage for a single test suite, run gcovr separately for suite coverage data directory. See [gcovr documentation](https://gcovr.com/guide.html#filter-options) for more information.
e.g. for features/netsocket/InternetSocket coverage:
Debian/Ubuntu/Mac OS:
```
mkdir UNITTESTS/build
cd UNITTESTS/build
cmake -DCMAKE_BUILD_TYPE=Debug -DCOVERAGE:STRING=html ..
make
./features_netsocket_InternetSocket
gcovr -r ../.. --html --html-detail -o ./index.html ./CMakeFiles/features_netsocket_InternetSocket.MbedOS.dir/
```
Windows:
```
mkdir UNITTESTS/build
cd UNITTESTS/build
cmake -DCMAKE_BUILD_TYPE=Debug -DCOVERAGE:STRING=html -g "MinGW Makefiles" ..
mingw32-make
features_netsocket_InternetSocket.exe
gcovr -r ..\.. --html --html-detail -o .\index.html .\CMakeFiles\features_netsocket_InternetSocket.MbedOS.dir\
```
## The structure of unit tests
The structure of the unit tests directory looks like this:
```
UNITTESTS
├── mbed_unittest.py Python tool for unit testing
├── unit_test Python tool modules
├── CMakeLists.txt CMake project definition file
├── CMakeSettings.json CMake configurations for Visual Studio 2017
├── README.md
├── googletest-CMakeLists.txt.in CMake project definition file for Google Test
├── features
│ └── netsocket Directory tree that mirrors Mbed OS root
│ ├── NetworkInterface Name of the class to be tested
│ │ ├── test_NetworkInterface.cpp
│ │ └── unittest.cmake CMake module for unit test
│ └── Socket
├── stubs Shared stubs which can be used for tests.
├── target_h Shared headers which can be used for tests.
└── template Templates for creating new unittests
```
Each unit test has an identical directory tree as seen in the Mbed OS root folder. This is not a mandatory requirement but helps to maintain tests. Each class to be tested have their own `unittest.cmake` which is found by `CMakeLists.txt`.
## Creating a unit test
Each class to be tested requires two files for unit testing:
1. C++ unit test source file (e.g. `test_NetworkInterface.cpp`)
2. CMake module file for unit test definition (`unittest.cmake`)
A unit test definition file `unittest.cmake` requires variables to be set for a test to be configured. File source paths in `unittest.cmake` files need to be relative to the unit test folder and `CMakeLists.txt`.
* **TEST_SUITE_NAME** - Identifier for the test suite. Use naming convention *PATH_TO_THE_TESTABLE_FILE* e.g. *features_netsocket_InternetSocket*
* **unittest-includes** - Include paths for headers needed to build the tests in addition to the base include paths listed in [CMakeLists.txt](CMakeLists.txt). Optional.
* **unittest-sources** - Mbed OS source files and stubs included for the build.
* **unittest-test-sources** - Unit test source files.
#### Creating unit tests files with Mbed CLI
```
mbed unittest --new <FILEPATH>
```
E.g. `mbed unittest --new rtos/Semaphore.cpp`
The generator script only creates the files required for a unit test. It does not write unit tests automatically nor does it handle source dependencies.
#### Create files manually
For example to create a unit test for `rtos/Semaphore.cpp`:
1. Create a directory for unit test files in `UNITTESTS/rtos/Semaphore`.
2. Create a test definition file `UNITTESTS/rtos/Semaphore/unittest.cmake` with the following content:
```
set(TEST_SUITE_NAME "rtos_Semaphore")
set(unittest-sources
stubs/mbed_assert.c
../rtos/Semaphore.cpp
)
set(unittest-test-sources
rtos/Semaphore/test_Semaphore.cpp
)
```
3. Create a test source file `UNITTESTS/rtos/Semaphore/test_Semaphore.cpp` with the following content:
```
#include "gtest/gtest.h"
#include "rtos/Semaphore.h"
static osStatus_t retval = osOK;
static uint32_t count = 0;
// Test stubs
osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout)
{
return retval;
}
osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphore_id)
{
return retval;
}
osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id)
{
return retval;
}
uint32_t osSemaphoreGetCount(osSemaphoreId_t semaphore_id)
{
return count;
}
osSemaphoreId_t osSemaphoreNew(uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr)
{
return (void *)&count; // Just a dymmy reference
}
class TestSemaphore : public testing::Test {
protected:
rtos::Semaphore *sem;
virtual void SetUp()
{
sem = new rtos::Semaphore();
}
virtual void TearDown()
{
delete sem;
}
};
TEST_F(TestSemaphore, constructor)
{
EXPECT_TRUE(sem);
}
```
## Troubleshooting
**Problem:** virus protection identifies files generated by CMake as malicious and quarantines the files on Windows.
* **Solution**: restore the false positive files from the quarantine.

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2018, Arm Limited and affiliates
* SPDX-License-Identifier: Apache-2.0
*
* 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 "gtest/gtest.h"
#include "test_at_cellularbase.h"
#include "AT_CellularBase.h"
class TestAT_CellularBase : public testing::Test {
protected:
Test_AT_CellularBase *unit;
virtual void SetUp()
{
unit = new Test_AT_CellularBase();
}
virtual void TearDown()
{
delete unit;
}
};
TEST_F(TestAT_CellularBase, Create)
{
EXPECT_TRUE(unit);
}
TEST_F(TestAT_CellularBase, test_AT_CellularBase_get_at_handler)
{
unit->test_AT_CellularBase_get_at_handler();
}
TEST_F(TestAT_CellularBase, test_AT_CellularBase_get_device_error)
{
unit->test_AT_CellularBase_get_device_error();
}

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 "gtest/gtest.h"
#include "test_at_cellularbase.h"
#include "EventQueue.h"
#include "AT_CellularBase.h"
#include "ATHandler_stub.h"
#include "FileHandle_stub.h"
#include <string.h>
using namespace mbed;
using namespace events;
Test_AT_CellularBase::Test_AT_CellularBase()
{
}
Test_AT_CellularBase::~Test_AT_CellularBase()
{
}
void Test_AT_CellularBase::test_AT_CellularBase_get_at_handler()
{
EventQueue eq;
FileHandle_stub fh;
ATHandler ah(&fh, eq, 100, ",");
AT_CellularBase at(ah);
EXPECT_EQ(&ah, &at.get_at_handler());
}
void Test_AT_CellularBase::test_AT_CellularBase_get_device_error()
{
EventQueue eq;
FileHandle_stub fh;
ATHandler ah(&fh, eq, 0, ",");
AT_CellularBase at(ah);
ATHandler_stub::device_err_value.errCode = 8;
EXPECT_EQ(8, at.get_device_error().errCode);
ATHandler_stub::device_err_value.errCode = 0;
}

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 TEST_AT_CELLULARBASE_H
#define TEST_AT_CELLULARBASE_H
class Test_AT_CellularBase {
public:
Test_AT_CellularBase();
virtual ~Test_AT_CellularBase();
void test_AT_CellularBase_get_at_handler();
void test_AT_CellularBase_get_device_error();
};
#endif // TEST_AT_CELLULARBASE_H

View File

@ -0,0 +1,32 @@
####################
# UNIT TESTS
####################
# Unit test suite name
set(TEST_SUITE_NAME "cellular_framework_AT_AT_CellularBase")
# Add test specific include paths
set(unittest-includes ${unittest-includes}
features/cellular/framework/AT/AT_CellularBase
../features/cellular/framework/AT
../features/cellular/framework/common
../features/frameworks/mbed-trace
../features/frameworks/nanostack-libservice/mbed-client-libservice
../features/netsocket
)
# Source files
set(unittest-sources
../features/cellular/framework/AT/AT_CellularBase.cpp
)
# Test files
set(unittest-test-sources
stubs/mbed_assert_stub.c
stubs/ATHandler_stub.cpp
stubs/EventQueue_stub.cpp
stubs/FileHandle_stub.cpp
features/cellular/framework/AT/AT_CellularBase/test_at_cellularbase.cpp
features/cellular/framework/AT/AT_CellularBase/at_cellularbasetest.cpp
)

View File

@ -0,0 +1,179 @@
/*
* Copyright (c) 2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 "gtest/gtest.h"
#include "test_util.h"
#include <string.h>
#include "CellularUtil.h"
#include <iostream>
using namespace mbed_cellular_util;
Test_util::Test_util()
{
}
Test_util::~Test_util()
{
}
void Test_util::test_util_uint_to_binary_string()
{
char str[33];
uint_to_binary_str(15, str, 33, 32);
str[32] = '\0';
// 15 is "1111" in binary but we ask all 32 bits so it should return "00000000000000000000000000001111"
EXPECT_STREQ("00000000000000000000000000001111", str);
// test NULL pointer
uint_to_binary_str(15, NULL, 0, 32);
// test give too small buffer
char too_small[5];
uint_to_binary_str(15, too_small, 5, 6);
}
void Test_util::test_util_char_str_to_hex()
{
// basic conversion test, happy days
char hex_buf[50];
uint16_t number_of_hex_chars = char_str_to_hex_str("1234", 4, hex_buf);
hex_buf[number_of_hex_chars] = '\0';
EXPECT_STREQ("31323334", hex_buf);
EXPECT_EQ(8, number_of_hex_chars);
number_of_hex_chars = char_str_to_hex_str("wuhuu", 5, hex_buf);
hex_buf[number_of_hex_chars] = '\0';
EXPECT_STREQ("7775687575", hex_buf);
EXPECT_EQ(10, number_of_hex_chars);
// First don't omit the leading zero and then omit and check that leading zero is missing
number_of_hex_chars = char_str_to_hex_str("\nwuhuu", 6, hex_buf);
hex_buf[number_of_hex_chars] = '\0';
EXPECT_STREQ("0A7775687575", hex_buf);
EXPECT_EQ(12, number_of_hex_chars);
number_of_hex_chars = char_str_to_hex_str("\nwuhuu", 6, hex_buf, true);
hex_buf[number_of_hex_chars] = '\0';
EXPECT_STREQ("A7775687575", hex_buf);
EXPECT_EQ(11, number_of_hex_chars);
// test giving a null pointer
number_of_hex_chars = char_str_to_hex_str(NULL, 4, hex_buf);
EXPECT_EQ(0, number_of_hex_chars);
number_of_hex_chars = char_str_to_hex_str("1234", 4, NULL);
EXPECT_EQ(0, number_of_hex_chars);
}
void Test_util::test_util_convert_ipv6()
{
// leading zeros omitted
char ipv6[64];
strncpy(ipv6, "1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1", 64);
convert_ipv6(ipv6);
EXPECT_STREQ("101:101:101:101:101:101:101:101", ipv6);
EXPECT_EQ(31, strlen(ipv6));
// some omitted and some not so much
strncpy(ipv6, "255.1.120.2.244.12.55.45.201.110.11.2.233.154.85.96", 64);
convert_ipv6(ipv6);
EXPECT_STREQ("FF01:7802:F40C:372D:C96E:B02:E99A:5560", ipv6);
EXPECT_EQ(38, strlen(ipv6));
// test giving a null pointer
convert_ipv6(NULL);
}
void Test_util::test_util_prefer_ipv6()
{
char tt[20] = "62.241.198.246";
char temp[64] = "2001:14B8:1000:000:000:000:000:002";
// not enough space to swap, arrays should stay the same
prefer_ipv6(tt, sizeof(tt), temp, sizeof(temp));
EXPECT_STREQ("62.241.198.246", tt);
EXPECT_STREQ("2001:14B8:1000:000:000:000:000:002", temp);
// should swap as first one was ip4 and later was ipv6 and enough space
char tt2[64] = "62.241.198.246";
prefer_ipv6(tt2, sizeof(tt2), temp, sizeof(temp));
EXPECT_STREQ("62.241.198.246", temp);
EXPECT_STREQ("2001:14B8:1000:000:000:000:000:002", tt2);
}
void Test_util::test_util_separate_ip_addresses()
{
char *s = (char *)calloc(128, 1);
char ip[64] = {0};
char subnet[64] = {0};
strncpy(s, "32.1.20.187.1.112.139.245.251.136.232.110.123.51.230.138.0.1.2.3.4.5.6.7.8.9.10.11.12.13.14.15", 94);
separate_ip_addresses(s, ip, sizeof(ip), subnet, sizeof(subnet));
EXPECT_STREQ("2001:14BB:170:8BF5:FB88:E86E:7B33:E68A", ip);
EXPECT_STREQ("001:203:405:607:809:A0B:C0D:E0F", subnet);
strncpy(s, "32:1:20:187:1:112:139:245:251:136:232:110:123:51:230:138 0:1:2:3:4:5:6:7:8:9:10:11:12:13:14:15", 94);
separate_ip_addresses(s, ip, sizeof(ip), subnet, sizeof(subnet));
EXPECT_STREQ("32:1:20:187:1:112:139:245:251:136:232:110:123:51:230:138", ip);
EXPECT_STREQ("0:1:2:3:4:5:6:7:8:9:10:11:12:13:14:15", subnet);
ip[0] = '\0';
subnet[0] = '\0';
strncpy(s, "1.2.3.4\0", 8);
separate_ip_addresses(s, ip, sizeof(ip), subnet, sizeof(subnet));
EXPECT_STREQ("1.2.3.4", ip);
EXPECT_STREQ("", subnet);
ip[0] = '\0';
subnet[0] = '\0';
strncpy(s, "1.2.3.4.5.6.7.8\0", 16);
separate_ip_addresses(s, ip, sizeof(ip), subnet, sizeof(subnet));
EXPECT_STREQ("1.2.3.4", ip);
EXPECT_STREQ("5.6.7.8", subnet);
ip[0] = '\0';
subnet[0] = '\0';
strncpy(s, "1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16\0", 39);
separate_ip_addresses(s, ip, sizeof(ip), subnet, sizeof(subnet));
EXPECT_STREQ("102:304:506:708:90A:B0C:D0E:F10", ip);
EXPECT_STREQ("", subnet);
ip[0] = '\0';
subnet[0] = '\0';
strncpy(s, "32:1:20:187:1:112:139:245:251:136:232:110:123:51:230:138\0", 57);
separate_ip_addresses(s, ip, sizeof(ip), subnet, sizeof(subnet));
EXPECT_STREQ("32:1:20:187:1:112:139:245:251:136:232:110:123:51:230:138", ip);
EXPECT_STREQ("", subnet);
ip[0] = '\0';
subnet[0] = '\0';
strncpy(s, "1.2.3.4 32:1:20:187:1:112:139:245:251:136:232:110:123:51:230:138\0", 65);
separate_ip_addresses(s, ip, sizeof(ip), subnet, sizeof(subnet));
EXPECT_STREQ("1.2.3.4", ip);
EXPECT_STREQ("32:1:20:187:1:112:139:245:251:136:232:110:123:51:230:138", subnet);
ip[0] = '\0';
subnet[0] = '\0';
strncpy(s, "1.2.3.4 5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20\0", 51);
separate_ip_addresses(s, ip, sizeof(ip), subnet, sizeof(subnet));
EXPECT_STREQ("1.2.3.4", ip);
EXPECT_STREQ("506:708:90A:B0C:D0E:F10:1112:1314", subnet);
EXPECT_STREQ("1.2.3.4 5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20", s);
free(s);
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 TEST_UTIL_H
#define TEST_UTIL_H
class Test_util {
public:
Test_util();
virtual ~Test_util();
void test_util_uint_to_binary_string();
void test_util_char_str_to_hex();
void test_util_convert_ipv6();
void test_util_prefer_ipv6();
void test_util_separate_ip_addresses();
};
#endif // TEST_UTIL_H

View File

@ -0,0 +1,26 @@
####################
# UNIT TESTS
####################
# Unit test suite name
set(TEST_SUITE_NAME "cellular_framework_common_util")
# Add test specific include paths
set(unittest-includes ${unittest-includes}
features/cellular/framework/common/util
../features/cellular/framework/common
../features/frameworks/mbed-client-randlib/mbed-client-randlib
)
# Source files
set(unittest-sources
../features/cellular/framework/common/CellularUtil.cpp
)
# Test files
set(unittest-test-sources
stubs/randLIB_stub.c
features/cellular/framework/common/util/test_util.cpp
features/cellular/framework/common/util/utiltest.cpp
)

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2018, Arm Limited and affiliates
* SPDX-License-Identifier: Apache-2.0
*
* 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 "gtest/gtest.h"
#include "test_util.h"
class TestUtil : public testing::Test {
protected:
Test_util *unit;
virtual void SetUp()
{
unit = new Test_util();
}
virtual void TearDown()
{
delete unit;
}
};
TEST_F(TestUtil, Create)
{
EXPECT_TRUE(unit);
}
TEST_F(TestUtil, test_util_uint_to_binary_string)
{
unit->test_util_uint_to_binary_string();
}
TEST_F(TestUtil, char_str_to_hex)
{
unit->test_util_char_str_to_hex();
}
TEST_F(TestUtil, convert_ipv6)
{
unit->test_util_convert_ipv6();
}
TEST_F(TestUtil, prefer_ipv6)
{
unit->test_util_prefer_ipv6();
}
TEST_F(TestUtil, separate_ip_addresses)
{
unit->test_util_separate_ip_addresses();
}

View File

@ -0,0 +1,159 @@
/*
* Copyright (c) 2018, Arm Limited and affiliates
* SPDX-License-Identifier: Apache-2.0
*
* 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 "gtest/gtest.h"
#include "features/netsocket/InternetSocket.h"
#include "NetworkStack_stub.h"
class stubInternetSocket : public InternetSocket {
protected:
nsapi_error_t return_value = 0;
public:
virtual void event()
{
if (_callback) {
_callback.call();
}
}
virtual nsapi_error_t connect(const SocketAddress &address)
{
return return_value;
}
virtual nsapi_size_or_error_t send(const void *data, nsapi_size_t size)
{
return return_value;
}
virtual nsapi_size_or_error_t recv(void *data, nsapi_size_t size)
{
return return_value;
}
virtual nsapi_size_or_error_t sendto(const SocketAddress &address,
const void *data, nsapi_size_t size)
{
return return_value;
}
virtual nsapi_size_or_error_t recvfrom(SocketAddress *address,
void *data, nsapi_size_t size)
{
return return_value;
}
virtual Socket *accept(nsapi_error_t *error = NULL)
{
return NULL;
}
virtual nsapi_error_t listen(int backlog = 1)
{
return return_value;
}
protected:
virtual nsapi_protocol_t get_proto()
{
return NSAPI_TCP;
}
};
static bool callback_is_called;
static void my_callback()
{
callback_is_called = true;
}
class TestInternetSocket : public testing::Test {
protected:
stubInternetSocket *socket;
NetworkStackstub stack;
virtual void SetUp()
{
socket = new stubInternetSocket;
}
virtual void TearDown()
{
delete socket;
}
};
TEST_F(TestInternetSocket, constructor)
{
EXPECT_TRUE(socket);
}
TEST_F(TestInternetSocket, open_null_stack)
{
EXPECT_EQ(socket->open(NULL), NSAPI_ERROR_PARAMETER);
}
TEST_F(TestInternetSocket, open_error)
{
stack.return_value = NSAPI_ERROR_PARAMETER;
EXPECT_EQ(socket->open((NetworkStack *)&stack), NSAPI_ERROR_PARAMETER);
}
TEST_F(TestInternetSocket, open)
{
stack.return_value = NSAPI_ERROR_OK;
EXPECT_EQ(socket->open((NetworkStack *)&stack), NSAPI_ERROR_OK);
}
TEST_F(TestInternetSocket, open_twice)
{
stack.return_value = NSAPI_ERROR_OK;
EXPECT_EQ(socket->open((NetworkStack *)&stack), NSAPI_ERROR_OK);
EXPECT_EQ(socket->open((NetworkStack *)&stack), NSAPI_ERROR_PARAMETER);
}
TEST_F(TestInternetSocket, close)
{
stack.return_value = NSAPI_ERROR_OK;
socket->open((NetworkStack *)&stack);
EXPECT_EQ(socket->close(), NSAPI_ERROR_OK);
}
TEST_F(TestInternetSocket, modify_multicast_group)
{
SocketAddress a("127.0.0.1", 1024);
stack.return_value = NSAPI_ERROR_OK;
socket->open((NetworkStack *)&stack);
EXPECT_EQ(socket->join_multicast_group(a), NSAPI_ERROR_UNSUPPORTED);
EXPECT_EQ(socket->leave_multicast_group(a), NSAPI_ERROR_UNSUPPORTED);
}
TEST_F(TestInternetSocket, set_blocking)
{
socket->set_blocking(false);
socket->set_blocking(true);
}
TEST_F(TestInternetSocket, setsockopt_no_stack)
{
socket->close();
EXPECT_EQ(socket->setsockopt(0, 0, 0, 0), NSAPI_ERROR_NO_SOCKET);
}
TEST_F(TestInternetSocket, sigio)
{
callback_is_called = false;
// I'm calling sigio() through the DEPRECATED method, just to get coverage for both.
// Not sure if this is wise at all, we should not aim for 100%
socket->attach(mbed::callback(my_callback));
socket->event();
EXPECT_EQ(callback_is_called, true);
}

View File

@ -0,0 +1,24 @@
####################
# UNIT TESTS
####################
# Unit test suite name
set(TEST_SUITE_NAME "features_netsocket_InternetSocket")
set(unittest-sources
../features/netsocket/SocketAddress.cpp
../features/netsocket/NetworkStack.cpp
../features/netsocket/InternetSocket.cpp
)
set(unittest-test-sources
stubs/Mutex_stub.cpp
stubs/mbed_assert_stub.c
stubs/equeue_stub.c
stubs/EventQueue_stub.cpp
stubs/mbed_shared_queues_stub.cpp
stubs/nsapi_dns_stub.cpp
stubs/EventFlags_stub.cpp
features/netsocket/InternetSocket/test_InternetSocket.cpp
)

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2018, Arm Limited and affiliates
* SPDX-License-Identifier: Apache-2.0
*
* 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 "gtest/gtest.h"
#include "features/netsocket/NetworkInterface.h"
class stubNetworkInterface : public NetworkInterface {
virtual nsapi_error_t connect()
{
return NSAPI_ERROR_OK;
};
virtual nsapi_error_t disconnect()
{
return NSAPI_ERROR_OK;
};
virtual NetworkStack *get_stack()
{
return NULL;
};
};
class TestNetworkInterface : public testing::Test {
protected:
NetworkInterface *iface;
virtual void SetUp()
{
iface = new stubNetworkInterface();
}
virtual void TearDown()
{
delete iface;
}
};
TEST_F(TestNetworkInterface, constructor)
{
EXPECT_TRUE(iface);
}
TEST_F(TestNetworkInterface, get_mac_address)
{
char *n = 0;
EXPECT_EQ(iface->get_mac_address(), n);
}

View File

@ -0,0 +1,17 @@
####################
# UNIT TESTS
####################
# Unit test suite name
set(TEST_SUITE_NAME "features_netsocket_NetworkInterface")
# Source files
set(unittest-sources
../features/netsocket/NetworkInterface.cpp
)
# Test files
set(unittest-test-sources
features/netsocket/NetworkInterface/test_NetworkInterface.cpp
)

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2018, Arm Limited and affiliates
* SPDX-License-Identifier: Apache-2.0
*
* 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 "gtest/gtest.h"
#include "features/netsocket/TCPSocket.h"
class TestTCPSocket : public testing::Test {
protected:
TCPSocket *socket;
virtual void SetUp()
{
socket = new TCPSocket();
}
virtual void TearDown()
{
delete socket;
}
};
TEST_F(TestTCPSocket, constructor)
{
EXPECT_TRUE(socket);
}

View File

@ -0,0 +1,20 @@
####################
# UNIT TESTS
####################
# Unit test suite name
set(TEST_SUITE_NAME "features_netsocket_TCPSocket")
set(unittest-sources
../features/netsocket/SocketAddress.cpp
../features/netsocket/InternetSocket.cpp
../features/netsocket/TCPSocket.cpp
)
set(unittest-test-sources
stubs/Mutex_stub.cpp
stubs/mbed_assert_stub.c
stubs/EventFlags_stub.cpp
features/netsocket/TCPSocket/test_TCPSocket.cpp
)

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2018, Arm Limited and affiliates
* SPDX-License-Identifier: Apache-2.0
*
* 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 "gtest/gtest.h"
#include "features/netsocket/UDPSocket.h"
#include "features/netsocket/nsapi_dns.h"
#include "NetworkStack_stub.h"
/**
* This test needs to access a private function
* which is why it is declared as friend
* following the documentation of google test.
* [*](https://github.com/google/googletest/blob/master/googletest/docs/advanced.md)
*/
class stubUDPSocket : public UDPSocket {
friend class TestUDPSocket;
FRIEND_TEST(TestUDPSocket, get_proto);
};
class TestUDPSocket : public testing::Test {
protected:
stubUDPSocket *socket;
NetworkStackstub stack;
virtual void SetUp()
{
socket = new stubUDPSocket;
stack.return_value = NSAPI_ERROR_OK;
socket->open((NetworkStack *)&stack);
}
virtual void TearDown()
{
delete socket;
}
};
TEST_F(TestUDPSocket, get_proto)
{
EXPECT_EQ(socket->get_proto(), NSAPI_UDP);
}
TEST_F(TestUDPSocket, sendto_addr_port)
{
stack.return_value = NSAPI_ERROR_PARAMETER;
EXPECT_EQ(socket->sendto("127.0.0.1", 0, 0, 0), NSAPI_ERROR_DNS_FAILURE);
stack.return_value = NSAPI_ERROR_OK;
EXPECT_EQ(socket->sendto("127.0.0.1", 0, 0, 0), 0);
}
TEST_F(TestUDPSocket, sendto)
{
SocketAddress addr("127.0.0.1", 1024);
stack.return_value = NSAPI_ERROR_OK;
socket->open((NetworkStack *)&stack);
stack.return_value = 100;
EXPECT_EQ(socket->sendto(addr, 0, 100), 100);
socket->set_timeout(0);
stack.return_value = NSAPI_ERROR_WOULD_BLOCK;
EXPECT_EQ(socket->sendto(addr, 0, 100), NSAPI_ERROR_WOULD_BLOCK);
socket->set_timeout(-1);
stack.return_value = NSAPI_ERROR_NO_CONNECTION;
EXPECT_EQ(socket->sendto(addr, 0, 100), NSAPI_ERROR_NO_CONNECTION);
}

View File

@ -0,0 +1,25 @@
####################
# UNIT TESTS
####################
# Unit test suite name
set(TEST_SUITE_NAME "features_netsocket_UDPSocket")
set(unittest-sources
../features/netsocket/SocketAddress.cpp
../features/netsocket/NetworkStack.cpp
../features/netsocket/InternetSocket.cpp
../features/netsocket/UDPSocket.cpp
)
set(unittest-test-sources
stubs/Mutex_stub.cpp
stubs/mbed_assert_stub.c
stubs/equeue_stub.c
stubs/EventQueue_stub.cpp
stubs/mbed_shared_queues_stub.cpp
stubs/EventFlags_stub.cpp
stubs/nsapi_dns_stub.cpp
features/netsocket/UDPSocket/test_UDPSocket.cpp
)

View File

@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 2.8.11)
project(googletest-download NONE)
include(ExternalProject)
ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG 8bc11c040a1dcbe50c340b21d78175d152dd3837
SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)

146
UNITTESTS/mbed_unittest.py Executable file
View File

@ -0,0 +1,146 @@
#!/usr/bin/env python
"""
Copyright (c) 2018, Arm Limited
SPDX-License-Identifier: Apache-2.0
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.
UNIT TEST BUILD & RUN
"""
from __future__ import print_function
import os
import logging
from unit_test.options import get_options_parser, \
pretty_print_test_options
from unit_test.settings import DEFAULT_CMAKE_GENERATORS
from unit_test.test import UnitTestTool
from unit_test.new import UnitTestGeneratorTool
def _mbed_unittest_test(options, cwd, pwd):
if options is None:
return
if options.coverage:
options.debug_build = True
if options.cmake_generator is None:
options.cmake_generator = DEFAULT_CMAKE_GENERATORS.get(
options.make_program,
"Unix Makefiles")
# Do not clean directory if only run.
if options.clean and options.run_only and not options.compile_only:
options.clean = False
# Build and run by default
if (not options.compile_only and
not options.run_only and
not options.clean):
options.compile_only = True
options.run_only = True
# Set build path
if not os.path.isabs(options.build):
options.build = os.path.normpath(
os.path.join(cwd, options.build))
pretty_print_test_options(options)
# Create test tool
tool = UnitTestTool(make_program=options.make_program)
# Prepare build directory
tool.prepare_build_directory(path_to_src=pwd,
build_path=options.build,
clean=options.clean)
if options.compile_only:
# Create makefiles
src_path = os.path.relpath(pwd, options.build)
tool.create_makefiles(path_to_src=src_path,
generator=options.cmake_generator,
coverage_output_type=options.coverage,
debug=options.debug_build)
# Build tests
tool.build_tests()
if options.run_only:
# If code coverage generation:
if options.coverage:
# Run tests and generate reports
tool.generate_coverage_report(coverage_output_type=options.coverage,
excludes=[pwd, options.build],
build_path=options.build)
else:
tool.run_tests(filter_regex=options.test_regex) # Only run tests
def _mbed_unittest_new(options, pwd):
if options is None:
return
generator = UnitTestGeneratorTool()
mbed_os_root = os.path.normpath(
os.path.join(pwd, "..")
)
for filepath in options.new_files:
generator.create(
mbed_os_root=mbed_os_root,
filepath=filepath)
def mbed_unittest(options=None):
"""
Create, build and run unit tests
"""
if options is None:
return
cwd = os.getcwd()
# Change current working directory to script location
unittest_dir = os.path.dirname(os.path.realpath(__file__))
os.chdir(unittest_dir)
if options.new_files:
_mbed_unittest_new(options, unittest_dir)
else:
_mbed_unittest_test(options, cwd, unittest_dir)
def mbed_unittest_main():
"""
Create, build and run unit tests - main
"""
# Get parser and parse command line arguments
parser = get_options_parser()
options = parser.parse_args()
# Setup logger
if options.log_level:
logging.basicConfig(level=getattr(logging, options.log_level),
format="%(message)s")
else:
logging.basicConfig(level=logging.INFO,
format="%(message)s")
mbed_unittest(options)
if __name__ == "__main__":
mbed_unittest_main()

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2018, Arm Limited and affiliates
* SPDX-License-Identifier: Apache-2.0
*
* 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 "gtest/gtest.h"
#include "platform/CircularBuffer.h"
class TestCircularBuffer : public testing::Test {
protected:
mbed::CircularBuffer<int, 10> *buf;
virtual void SetUp()
{
buf = new mbed::CircularBuffer<int, 10>;
}
virtual void TearDown()
{
delete buf;
}
};
TEST_F(TestCircularBuffer, constructor)
{
EXPECT_TRUE(buf);
}

View File

@ -0,0 +1,14 @@
####################
# UNIT TESTS
####################
# Unit test suite name
set(TEST_SUITE_NAME "platform_CircularBuffer")
set(unittest-sources
)
set(unittest-test-sources
platform/CircularBuffer/test_CircularBuffer.cpp
)

View File

@ -0,0 +1,226 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 <ctype.h>
#include "nsapi_types.h"
#include "ATHandler.h"
#include "EventQueue.h"
#include "ATHandler_stub.h"
using namespace mbed;
using namespace events;
#include "CellularLog.h"
const int DEFAULT_AT_TIMEOUT = 1000; // at default timeout in milliseconds
nsapi_error_t ATHandler_stub::nsapi_error_value = 0;
uint8_t ATHandler_stub::nsapi_error_ok_counter = 0;
int ATHandler_stub::int_value = -1;
ssize_t ATHandler_stub::ssize_value = 0;
char *ATHandler_stub::read_string_value = NULL;
size_t ATHandler_stub::size_value = 0;
size_t ATHandler_stub::return_given_size = false;
bool ATHandler_stub::bool_value = false;
uint8_t ATHandler_stub::uint8_value = 0;
FileHandle_stub *ATHandler_stub::fh_value = NULL;
device_err_t ATHandler_stub::device_err_value;
Callback<void()> ATHandler_stub::callback = NULL;
uint8_t ATHandler_stub::resp_info_true_counter = false;
ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char *output_delimiter, uint16_t send_delay) : _nextATHandler(0),
_fileHandle(fh),
_queue(queue)
{
}
ATHandler::~ATHandler()
{
}
void ATHandler::inc_ref_count()
{
}
void ATHandler::dec_ref_count()
{
}
int ATHandler::get_ref_count()
{
return ATHandler_stub::int_value;
}
FileHandle *ATHandler::get_file_handle()
{
return ATHandler_stub::fh_value;
}
void ATHandler::set_file_handle(FileHandle *fh)
{
}
nsapi_error_t ATHandler::set_urc_handler(const char *urc, mbed::Callback<void()> cb)
{
ATHandler_stub::callback = cb;
return NSAPI_ERROR_OK;
}
void ATHandler::remove_urc_handler(const char *prefix, mbed::Callback<void()> callback)
{
}
nsapi_error_t ATHandler::get_last_error() const
{
if (ATHandler_stub::nsapi_error_ok_counter) {
ATHandler_stub::nsapi_error_ok_counter--;
return NSAPI_ERROR_OK;
}
return ATHandler_stub::nsapi_error_value;
}
void ATHandler::lock()
{
}
void ATHandler::unlock()
{
}
nsapi_error_t ATHandler::unlock_return_error()
{
return ATHandler_stub::nsapi_error_value;
}
void ATHandler::set_at_timeout(uint32_t timeout_milliseconds, bool default_timeout)
{
}
void ATHandler::restore_at_timeout()
{
}
void ATHandler::process_oob()
{
}
void ATHandler::clear_error()
{
}
void ATHandler::skip_param(uint32_t count)
{
}
void ATHandler::skip_param(ssize_t len, uint32_t count)
{
}
ssize_t ATHandler::read_bytes(uint8_t *buf, size_t len)
{
return ATHandler_stub::ssize_value;
}
ssize_t ATHandler::read_string(char *buf, size_t size, bool read_even_stop_tag)
{
if (ATHandler_stub::read_string_value && ATHandler_stub::ssize_value >= 0) {
memcpy(buf, ATHandler_stub::read_string_value, ATHandler_stub::ssize_value);
}
return ATHandler_stub::ssize_value;
}
int ATHandler::read_int()
{
return ATHandler_stub::int_value;
}
void ATHandler::set_delimiter(char delimiter)
{
}
void ATHandler::set_default_delimiter()
{
}
void ATHandler::set_stop_tag(const char *stop_tag_seq)
{
}
int ATHandler::get_3gpp_error()
{
return ATHandler_stub::int_value;
}
void ATHandler::resp_start(const char *prefix, bool stop)
{
}
bool ATHandler::info_resp()
{
if (ATHandler_stub::resp_info_true_counter) {
ATHandler_stub::resp_info_true_counter--;
return true;
}
return ATHandler_stub::bool_value;
}
bool ATHandler::info_elem(char start_tag)
{
return ATHandler_stub::bool_value;
}
bool ATHandler::consume_to_stop_tag()
{
return ATHandler_stub::bool_value;
}
void ATHandler::resp_stop()
{
}
void ATHandler::cmd_start(const char *cmd)
{
}
void ATHandler::write_int(int param)
{
}
void ATHandler::write_string(const char *param, bool useQuotations)
{
}
size_t ATHandler::write_bytes(const uint8_t *param, size_t len)
{
if (ATHandler_stub::return_given_size) {
return len;
}
return ATHandler_stub::size_value;
}
void ATHandler::cmd_stop()
{
}
device_err_t ATHandler::get_last_device_error() const
{
return ATHandler_stub::device_err_value;
}
void ATHandler::flush()
{
}

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 "stdint.h"
#include "stdbool.h"
#include <cstddef>
#include "nsapi_types.h"
#include "ATHandler.h"
#include "FileHandle_stub.h"
#include "Callback.h"
namespace ATHandler_stub
{
extern nsapi_error_t nsapi_error_value;
extern uint8_t nsapi_error_ok_counter;
extern int int_value;
extern ssize_t ssize_value;
extern char *read_string_value;
extern size_t size_value;
extern size_t return_given_size;
extern bool bool_value;
extern uint8_t resp_info_true_counter;
extern uint8_t uint8_value;
extern mbed::FileHandle_stub *fh_value;
extern mbed::device_err_t device_err_value;
extern mbed::Callback<void()> callback;
} // namespace ATHandler_stub

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 "rtos/EventFlags.h"
rtos::EventFlags::EventFlags() {}
rtos::EventFlags::~EventFlags() {}
uint32_t rtos::EventFlags::set(uint32_t flags)
{
return 0;
}
uint32_t rtos::EventFlags::clear(uint32_t flags)
{
return 0;
}
uint32_t rtos::EventFlags::get() const
{
return 0;
}
uint32_t rtos::EventFlags::wait_all(uint32_t flags, uint32_t timeout, bool clear)
{
return 0;
}
uint32_t rtos::EventFlags::wait_any(uint32_t flags, uint32_t timeout, bool clear)
{
return 0;
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 "EventQueue.h"
#include "Callback.h"
using namespace mbed;
namespace events {
EventQueue::EventQueue(unsigned event_size, unsigned char *event_pointer)
{
}
EventQueue::~EventQueue()
{
}
void EventQueue::dispatch(int ms)
{
}
void EventQueue::break_dispatch()
{
}
unsigned EventQueue::tick()
{
return 0;
}
void EventQueue::cancel(int id)
{
}
void EventQueue::background(Callback<void(int)> update)
{
}
void EventQueue::chain(EventQueue *target)
{
}
} // namespace events

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) , Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 "FileHandle_stub.h"
namespace mbed {
off_t FileHandle::size()
{
return 0;
}
std::FILE *fdopen(FileHandle *fh, const char *mode)
{
return NULL;
}
} // namespace mbed

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) , Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 __FILE_HANDLE_STUB_H__
#define __FILE_HANDLE_STUB_H__
#include "FileHandle.h"
namespace mbed
{
static uint8_t filehandle_stub_short_value_counter = 0;
static char *filehandle_stub_table = NULL;
static uint8_t filehandle_stub_table_pos = 0;
class FileHandle_stub : public FileHandle
{
public:
ssize_t size_value;
FileHandle_stub() { size_value = 0; }
virtual ssize_t read(void *buffer, size_t size)
{
if (filehandle_stub_table)
{
ssize_t ret = strlen(filehandle_stub_table) - filehandle_stub_table_pos;
if (size < ret)
{
ret = size;
}
memcpy(buffer, filehandle_stub_table, ret);
filehandle_stub_table_pos += ret;
return ret;
}
return 0;
}
virtual ssize_t write(const void *buffer, size_t size)
{
if (size_value > 0)
{
size_value--;
return size;
}
else if (size_value < 0)
{
return -1;
}
return 0;
}
virtual off_t seek(off_t offset, int whence = SEEK_SET) { return 0; }
virtual int close() {}
virtual short poll(short events) const
{
if (filehandle_stub_short_value_counter)
{
filehandle_stub_short_value_counter--;
return short_value;
}
return 0;
}
virtual void sigio(Callback<void()> func) { func(); }
short short_value;
};
} // namespace mbed
#endif

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 "rtos/Mutex.h"
rtos::Mutex::Mutex()
{
return;
}
rtos::Mutex::~Mutex()
{
return;
}
osStatus rtos::Mutex::lock(unsigned int)
{
return osOK;
}
osStatus rtos::Mutex::unlock()
{
return osOK;
}

View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 NETWORKSTACKSTUB_H
#define NETWORKSTACKSTUB_H
#include "netsocket/NetworkStack.h"
class NetworkStackstub : public NetworkStack {
public:
nsapi_error_t return_value = 0;
virtual const char *get_ip_address()
{
return "127.0.0.1";
}
virtual nsapi_error_t gethostbyname(const char *host,
SocketAddress *address, nsapi_version_t version)
{
return return_value;
}
virtual nsapi_value_or_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback,
nsapi_version_t version)
{
return return_value;
}
virtual nsapi_error_t gethostbyname_async_cancel(int id)
{
return return_value;
}
protected:
virtual nsapi_error_t socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto)
{
return return_value;
};
virtual nsapi_error_t socket_close(nsapi_socket_t handle)
{
return return_value;
};
virtual nsapi_error_t socket_bind(nsapi_socket_t handle, const SocketAddress &address)
{
return return_value;
};
virtual nsapi_error_t socket_listen(nsapi_socket_t handle, int backlog)
{
return return_value;
};
virtual nsapi_error_t socket_connect(nsapi_socket_t handle, const SocketAddress &address)
{
return return_value;
};
virtual nsapi_error_t socket_accept(nsapi_socket_t server,
nsapi_socket_t *handle, SocketAddress *address = 0)
{
return return_value;
};
virtual nsapi_size_or_error_t socket_send(nsapi_socket_t handle,
const void *data, nsapi_size_t size)
{
return return_value;
};
virtual nsapi_size_or_error_t socket_recv(nsapi_socket_t handle,
void *data, nsapi_size_t size)
{
return return_value;
};
virtual nsapi_size_or_error_t socket_sendto(nsapi_socket_t handle, const SocketAddress &address,
const void *data, nsapi_size_t size)
{
return return_value;
};
virtual nsapi_size_or_error_t socket_recvfrom(nsapi_socket_t handle, SocketAddress *address,
void *buffer, nsapi_size_t size)
{
return return_value;
};
virtual void socket_attach(nsapi_socket_t handle, void (*callback)(void *), void *data) {};
private:
virtual nsapi_error_t call_in(int delay, mbed::Callback<void()> func)
{
return return_value;
}
};
#endif // NETWORKSTACKSTUB_H

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 "equeue/equeue.h"
void *equeue_alloc(equeue_t *q, size_t size)
{
}
int equeue_post(equeue_t *q, void (*cb)(void *), void *p)
{
return 0;
}
void equeue_event_delay(void *p, int ms)
{
}
void equeue_event_period(void *p, int ms)
{
}
void equeue_event_dtor(void *p, void (*dtor)(void *))
{
}

View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 "platform/mbed_assert.h"
#include <stdio.h>
void mbed_assert_internal(const char *expr, const char *file, int line)
{
fprintf(stderr, "mbed assertation failed: %s, file: %s, line %d \n", expr, file, line);
}

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 "events/mbed_shared_queues.h"
using namespace events;
namespace mbed {
EventQueue *mbed_event_queue()
{
return 0;
}
} // namespace mbed

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 "netsocket/nsapi_dns.h"
nsapi_error_t nsapi_stub_return_value = NSAPI_ERROR_DNS_FAILURE;
nsapi_error_t nsapi_dns_query(NetworkStack *stack, const char *host,
SocketAddress *addr, nsapi_version_t version)
{
return nsapi_stub_return_value;
}
nsapi_error_t nsapi_dns_query_async(NetworkStack *stack, const char *host,
NetworkStack::hostbyname_cb_t callback, call_in_callback_cb_t call_in_cb,
nsapi_version_t version)
{
return nsapi_stub_return_value;
}
nsapi_error_t nsapi_dns_query_async_cancel(nsapi_error_t id)
{
return nsapi_stub_return_value;
}
extern "C" nsapi_error_t nsapi_dns_add_server(nsapi_addr_t addr)
{
return NSAPI_ERROR_OK;
}

View File

@ -0,0 +1,3 @@
#include "nvic_wrapper.h"
void NVIC_SystemReset(void) {}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2014-2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <limits.h>
#include "randLIB.h"
#include "platform/arm_hal_random.h"
#if ((RAND_MAX+1) & RAND_MAX) != 0
#error "RAND_MAX isn't 2^n-1 :("
#endif
int counter = 1;
void randLIB_seed_random(void)
{
}
uint8_t randLIB_get_8bit(void)
{
return 0;
}
uint16_t randLIB_get_16bit(void)
{
return 0;
}
uint32_t randLIB_get_32bit(void)
{
return 0;
}
void *randLIB_get_n_bytes_random(void *data_ptr, uint8_t count)
{
if (data_ptr && count > 0) {
*((int *)data_ptr) = counter++ % 255;
}
return data_ptr;
}
uint16_t randLIB_get_random_in_range(uint16_t min, uint16_t max)
{
return 0;
}
uint32_t randLIB_randomise_base(uint32_t base, uint16_t min_factor, uint16_t max_factor)
{
return 0;
}

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 MBED_PERIPHERALNAMES_H
#define MBED_PERIPHERALNAMES_H
#endif

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 MBED_PINNAMES_H
#define MBED_PINNAMES_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
PIN_INPUT,
PIN_OUTPUT
} PinDirection;
typedef enum {
NC = (int)0xFFFFFFFF
} PinName;
typedef enum {
} PinMode;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 MBED_DEVICE_H
#define MBED_DEVICE_H
#include "objects.h"
#endif

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 EQUEUE_PLATFORM_H
#define EQUEUE_PLATFORM_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
typedef unsigned equeue_mutex_t;
typedef struct equeue_sema {
} equeue_sema_t;
#ifdef __cplusplus
}
#endif
#endif //EQUEUE_PLATFORM_H

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 MBED_EVENTS_H
#define MBED_EVENTS_H
#include "EventQueue.h"
#include "events/mbed_shared_queues.h"
#endif

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 MBED_GPIO_OBJECT_H
#define MBED_GPIO_OBJECT_H
#include "mbed_assert.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
} gpio_t;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 IP6STRING_H
#define IP6STRING_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
uint_fast8_t ip6tos(const void *ip6addr, char *p)
{
return 0;
}
void stoip6(const char *ip6addr, size_t len, void *dest) {}
#ifdef __cplusplus
}
#endif
#endif

33
UNITTESTS/target_h/mbed.h Normal file
View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 MBED_H
#define MBED_H
#include <cstdio>
#include <cstring>
#include "events/mbed_events.h"
namespace mbed {
#include "platform/Callback.h"
};
using namespace mbed;
using namespace std;
#endif // MBED_H

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 MBED_RTOS1_TYPES_H
#define MBED_RTOS1_TYPES_H
#include "mbed_rtos_storage.h"
#endif // MBED_RTOS1_TYPES_H

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 MBED_RTOS_STORAGE_H
#define MBED_RTOS_STORAGE_H
#ifdef __cplusplus
extern "C" {
#endif
#include "cmsis_os2.h"
typedef osMutexId_t mbed_rtos_storage_mutex_t;
typedef osSemaphoreId_t mbed_rtos_storage_semaphore_t;
typedef osThreadId_t mbed_rtos_storage_thread_t;
typedef osThreadId_t osThreadId;
typedef osMemoryPoolId_t mbed_rtos_storage_mem_pool_t;
typedef osMessageQueueId_t mbed_rtos_storage_msg_queue_t;
typedef osEventFlagsId_t mbed_rtos_storage_event_flags_t;
typedef void *mbed_rtos_storage_message_t;
typedef osTimerId_t mbed_rtos_storage_timer_t;
typedef osStatus_t osStatus;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 NVIC_WRAPPER_H
#define NVIC_WRAPPER_H
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
void NVIC_SystemReset(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif //NVIC_WRAPPER_H

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 MBED_OBJECTS_H
#define MBED_OBJECTS_H
#include "PeripheralNames.h"
#include "PinNames.h"
#ifdef __cplusplus
extern "C" {
#endif
#include "gpio_object.h"
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,286 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 RETARGET_H
#define RETARGET_H
#include <sys/types.h>
#undef EPERM
#define EPERM 1 /* Operation not permitted */
#undef ENOENT
#define ENOENT 2 /* No such file or directory */
#undef ESRCH
#define ESRCH 3 /* No such process */
#undef EINTR
#define EINTR 4 /* Interrupted system call */
#undef EIO
#define EIO 5 /* I/O error */
#undef ENXIO
#define ENXIO 6 /* No such device or address */
#undef E2BIG
#define E2BIG 7 /* Argument list too long */
#undef ENOEXEC
#define ENOEXEC 8 /* Exec format error */
#undef EBADF
#define EBADF 9 /* Bad file number */
#undef ECHILD
#define ECHILD 10 /* No child processes */
#undef EAGAIN
#define EAGAIN 11 /* Try again */
#undef ENOMEM
#define ENOMEM 12 /* Out of memory */
#undef EACCES
#define EACCES 13 /* Permission denied */
#undef EFAULT
#define EFAULT 14 /* Bad address */
#undef ENOTBLK
#define ENOTBLK 15 /* Block device required */
#undef EBUSY
#define EBUSY 16 /* Device or resource busy */
#undef EEXIST
#define EEXIST 17 /* File exists */
#undef EXDEV
#define EXDEV 18 /* Cross-device link */
#undef ENODEV
#define ENODEV 19 /* No such device */
#undef ENOTDIR
#define ENOTDIR 20 /* Not a directory */
#undef EISDIR
#define EISDIR 21 /* Is a directory */
#undef EINVAL
#define EINVAL 22 /* Invalid argument */
#undef ENFILE
#define ENFILE 23 /* File table overflow */
#undef EMFILE
#define EMFILE 24 /* Too many open files */
#undef ENOTTY
#define ENOTTY 25 /* Not a typewriter */
#undef ETXTBSY
#define ETXTBSY 26 /* Text file busy */
#undef EFBIG
#define EFBIG 27 /* File too large */
#undef ENOSPC
#define ENOSPC 28 /* No space left on device */
#undef ESPIPE
#define ESPIPE 29 /* Illegal seek */
#undef EROFS
#define EROFS 30 /* Read-only file system */
#undef EMLINK
#define EMLINK 31 /* Too many links */
#undef EPIPE
#define EPIPE 32 /* Broken pipe */
#undef EDOM
#define EDOM 33 /* Math argument out of domain of func */
#undef ERANGE
#define ERANGE 34 /* Math result not representable */
#undef EDEADLK
#define EDEADLK 35 /* Resource deadlock would occur */
#undef ENAMETOOLONG
#define ENAMETOOLONG 36 /* File name too long */
#undef ENOLCK
#define ENOLCK 37 /* No record locks available */
#undef ENOSYS
#define ENOSYS 38 /* Function not implemented */
#undef ENOTEMPTY
#define ENOTEMPTY 39 /* Directory not empty */
#undef ELOOP
#define ELOOP 40 /* Too many symbolic links encountered */
#undef EWOULDBLOCK
#define EWOULDBLOCK EAGAIN /* Operation would block */
#undef ENOMSG
#define ENOMSG 42 /* No message of desired type */
#undef EIDRM
#define EIDRM 43 /* Identifier removed */
#undef ECHRNG
#define ECHRNG 44 /* Channel number out of range */
#undef EL2NSYNC
#define EL2NSYNC 45 /* Level 2 not synchronized */
#undef EL3HLT
#define EL3HLT 46 /* Level 3 halted */
#undef EL3RST
#define EL3RST 47 /* Level 3 reset */
#undef ELNRNG
#define ELNRNG 48 /* Link number out of range */
#undef EUNATCH
#define EUNATCH 49 /* Protocol driver not attached */
#undef ENOCSI
#define ENOCSI 50 /* No CSI structure available */
#undef EL2HLT
#define EL2HLT 51 /* Level 2 halted */
#undef EBADE
#define EBADE 52 /* Invalid exchange */
#undef EBADR
#define EBADR 53 /* Invalid request descriptor */
#undef EXFULL
#define EXFULL 54 /* Exchange full */
#undef ENOANO
#define ENOANO 55 /* No anode */
#undef EBADRQC
#define EBADRQC 56 /* Invalid request code */
#undef EBADSLT
#define EBADSLT 57 /* Invalid slot */
#undef EDEADLOCK
#define EDEADLOCK EDEADLK /* Resource deadlock would occur */
#undef EBFONT
#define EBFONT 59 /* Bad font file format */
#undef ENOSTR
#define ENOSTR 60 /* Device not a stream */
#undef ENODATA
#define ENODATA 61 /* No data available */
#undef ETIME
#define ETIME 62 /* Timer expired */
#undef ENOSR
#define ENOSR 63 /* Out of streams resources */
#undef ENONET
#define ENONET 64 /* Machine is not on the network */
#undef ENOPKG
#define ENOPKG 65 /* Package not installed */
#undef EREMOTE
#define EREMOTE 66 /* Object is remote */
#undef ENOLINK
#define ENOLINK 67 /* Link has been severed */
#undef EADV
#define EADV 68 /* Advertise error */
#undef ESRMNT
#define ESRMNT 69 /* Srmount error */
#undef ECOMM
#define ECOMM 70 /* Communication error on send */
#undef EPROTO
#define EPROTO 71 /* Protocol error */
#undef EMULTIHOP
#define EMULTIHOP 72 /* Multihop attempted */
#undef EDOTDOT
#define EDOTDOT 73 /* RFS specific error */
#undef EBADMSG
#define EBADMSG 74 /* Not a data message */
#undef EOVERFLOW
#define EOVERFLOW 75 /* Value too large for defined data type */
#undef ENOTUNIQ
#define ENOTUNIQ 76 /* Name not unique on network */
#undef EBADFD
#define EBADFD 77 /* File descriptor in bad state */
#undef EREMCHG
#define EREMCHG 78 /* Remote address changed */
#undef ELIBACC
#define ELIBACC 79 /* Can not access a needed shared library */
#undef ELIBBAD
#define ELIBBAD 80 /* Accessing a corrupted shared library */
#undef ELIBSCN
#define ELIBSCN 81 /* .lib section in a.out corrupted */
#undef ELIBMAX
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
#undef ELIBEXEC
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
#undef EILSEQ
#define EILSEQ 84 /* Illegal byte sequence */
#undef ERESTART
#define ERESTART 85 /* Interrupted system call should be restarted */
#undef ESTRPIPE
#define ESTRPIPE 86 /* Streams pipe error */
#undef EUSERS
#define EUSERS 87 /* Too many users */
#undef ENOTSOCK
#define ENOTSOCK 88 /* Socket operation on non-socket */
#undef EDESTADDRREQ
#define EDESTADDRREQ 89 /* Destination address required */
#undef EMSGSIZE
#define EMSGSIZE 90 /* Message too long */
#undef EPROTOTYPE
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
#undef ENOPROTOOPT
#define ENOPROTOOPT 92 /* Protocol not available */
#undef EPROTONOSUPPORT
#define EPROTONOSUPPORT 93 /* Protocol not supported */
#undef ESOCKTNOSUPPORT
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
#undef EOPNOTSUPP
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#undef EPFNOSUPPORT
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#undef EAFNOSUPPORT
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
#undef EADDRINUSE
#define EADDRINUSE 98 /* Address already in use */
#undef EADDRNOTAVAIL
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
#undef ENETDOWN
#define ENETDOWN 100 /* Network is down */
#undef ENETUNREACH
#define ENETUNREACH 101 /* Network is unreachable */
#undef ENETRESET
#define ENETRESET 102 /* Network dropped connection because of reset */
#undef ECONNABORTED
#define ECONNABORTED 103 /* Software caused connection abort */
#undef ECONNRESET
#define ECONNRESET 104 /* Connection reset by peer */
#undef ENOBUFS
#define ENOBUFS 105 /* No buffer space available */
#undef EISCONN
#define EISCONN 106 /* Transport endpoint is already connected */
#undef ENOTCONN
#define ENOTCONN 107 /* Transport endpoint is not connected */
#undef ESHUTDOWN
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
#undef ETOOMANYREFS
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
#undef ETIMEDOUT
#define ETIMEDOUT 110 /* Connection timed out */
#undef ECONNREFUSED
#define ECONNREFUSED 111 /* Connection refused */
#undef EHOSTDOWN
#define EHOSTDOWN 112 /* Host is down */
#undef EHOSTUNREACH
#define EHOSTUNREACH 113 /* No route to host */
#undef EALREADY
#define EALREADY 114 /* Operation already in progress */
#undef EINPROGRESS
#define EINPROGRESS 115 /* Operation now in progress */
#undef ESTALE
#define ESTALE 116 /* Stale NFS file handle */
#undef EUCLEAN
#define EUCLEAN 117 /* Structure needs cleaning */
#undef ENOTNAM
#define ENOTNAM 118 /* Not a XENIX named type file */
#undef ENAVAIL
#define ENAVAIL 119 /* No XENIX semaphores available */
#undef EISNAM
#define EISNAM 120 /* Is a named type file */
#undef EREMOTEIO
#define EREMOTEIO 121 /* Remote I/O error */
#undef EDQUOT
#define EDQUOT 122 /* Quota exceeded */
#undef ENOMEDIUM
#define ENOMEDIUM 123 /* No medium found */
#undef EMEDIUMTYPE
#define EMEDIUMTYPE 124 /* Wrong medium type */
#undef ECANCELED
#define ECANCELED 125 /* Operation Canceled */
#undef ENOKEY
#define ENOKEY 126 /* Required key not available */
#undef EKEYEXPIRED
#define EKEYEXPIRED 127 /* Key has expired */
#undef EKEYREVOKED
#define EKEYREVOKED 128 /* Key has been revoked */
#undef EKEYREJECTED
#define EKEYREJECTED 129 /* Key was rejected by service */
#undef EOWNERDEAD
#define EOWNERDEAD 130 /* Owner died */
#undef ENOTRECOVERABLE
#define ENOTRECOVERABLE 131 /* State not recoverable */
#endif //RETARGET_H

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2017, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* 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 MBED_PLATFORM_H
#define MBED_PLATFORM_H
#include <cstddef>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include "platform/mbed_retarget.h"
#include "nvic_wrapper.h"
#endif

View File

@ -0,0 +1,17 @@
#include "gtest/gtest.h"
#include "dirname/template.h"
class Testtemplate : public testing::Test {
virtual void SetUp()
{
}
virtual void TearDown()
{
}
};
TEST_F(Testtemplate, constructor)
{
EXPECT_TRUE(true);
}

View File

@ -0,0 +1,19 @@
####################
# UNIT TESTS
####################
# Unit test suite name
set(TEST_SUITE_NAME "suitename")
set(unittest-includes ${unittest-includes}
headerfile
)
set(unittest-sources
cppfile
)
set(unittest-test-sources
dirname/template/test_template.cpp
)

View File

@ -0,0 +1,16 @@
"""
Copyright (c) 2018, Arm Limited
SPDX-License-Identifier: Apache-2.0
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.
"""

View File

@ -0,0 +1,82 @@
"""
Copyright (c) 2018, Arm Limited
SPDX-License-Identifier: Apache-2.0
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.
GET UNIT TEST TOOLS
"""
import platform
from .utils import is_tool
from .settings import MAKE_PROGRAMS, \
CXX_COMPILERS, \
C_COMPILERS, \
GCOV_PROGRAMS
def _get_program(programs, default=None):
if programs is None:
programs = []
for program in programs:
if is_tool(program):
return program
return default
def get_make_tool():
"""
Get make program
"""
default_make = "mingw32-make" if (platform.system() == "Windows") \
else "make"
return _get_program(MAKE_PROGRAMS, default=default_make)
def get_cmake_tool():
"""
Get cmake program
"""
return _get_program(["cmake"])
def get_cxx_tool():
"""
Get C++ compiler
"""
return _get_program(CXX_COMPILERS, "g++")
def get_c_tool():
"""
Get C compiler
"""
return _get_program(C_COMPILERS, "gcc")
def get_gcov_program():
"""
Get gcov program
"""
return _get_program(GCOV_PROGRAMS, "gcov")
def get_gcovr_program():
"""
Get covr program
"""
return _get_program(["gcovr"])

145
UNITTESTS/unit_test/new.py Normal file
View File

@ -0,0 +1,145 @@
"""
Copyright (c) 2018, Arm Limited
SPDX-License-Identifier: Apache-2.0
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.
UNIT TEST GENERATE NEW UNIT TESTS
"""
from __future__ import print_function
import os
import re
import logging
class UnitTestGeneratorTool(object):
"""
Generator tool to create new unit tests from template
"""
def _replace_content(self, template_content, dirname, classname, suite_name, extension):
if extension == "h":
content = re.sub(r"cppfile",
"",
template_content)
elif extension == "cpp":
content = re.sub(r"cppfile",
"../dirname/template.cpp",
template_content)
content = re.sub(r"headerfile", "../dirname/template.h", content)
content = re.sub(r"dirname", dirname, content)
content = re.sub(r"template", classname, content)
content = re.sub(r"suitename", suite_name, content)
return content
def create(self, mbed_os_root=None, filepath=None):
"""
Generate a unit test for a file to be tested from templates
Keyword arguments:
mbed_os_root - Mbed OS root directory
filepath - Path to the file to be tested
"""
if filepath is None:
logging.error("No filepath given. Cannot create a new unit test.")
return
if mbed_os_root is None:
mbed_os_root = \
os.path.normpath(os.path.join(os.path.dirname(__file__),
"../.."))
if os.path.isabs(filepath):
filepath = os.path.join(
os.path.relpath(os.path.dirname(filepath), mbed_os_root),
os.path.basename(filepath))
if not re.match(r"((\w+\/)+)(\w+)\.(c|cpp|h|hpp)$", filepath):
logging.error(
"No proper path to source file given.")
return
if not os.path.isfile(os.path.join(mbed_os_root, filepath)):
logging.warning("Cannot find source file: %s from Mbed OS.",
filepath)
dir_name = re.sub(r"(\\|\/)(\w+)\.(cpp|h)$", "", filepath)
match = re.search(r"(\\|\/)(\w+)\.(cpp|h)$", filepath)
if match:
class_name = match.group(2)
file_extension = match.group(3)
# Create directory tree if not exist.
test_dir = os.path.join(mbed_os_root, "UNITTESTS", dir_name, class_name)
if not os.path.exists(test_dir):
os.makedirs(test_dir)
else:
logging.error("Unit tests exist already for this file.")
return
try:
suite_name = ("%s/%s" % (dir_name, class_name)).replace("/", "_")
# Test source file template
template_source_file = \
os.path.join(mbed_os_root,
"UNITTESTS/template/test_template.cpp")
with open(template_source_file, "r") as input_file:
template_content = input_file.read()
output_source_file = os.path.join(test_dir,
"test_%s.cpp" % class_name)
with open(output_source_file, "w") as output_file:
content = self._replace_content(template_content,
dir_name,
class_name,
suite_name,
file_extension)
output_file.writelines(content)
# Definition file template
template_source_file = \
os.path.join(mbed_os_root,
"UNITTESTS/template/unittest.cmake.template")
with open(template_source_file, "r") as input_file:
template_content = input_file.read()
output_source_file = os.path.join(test_dir, "unittest.cmake")
with open(output_source_file, "w") as output_file:
content = self._replace_content(template_content,
dir_name,
class_name,
suite_name,
file_extension)
output_file.writelines(content)
logging.info("""
Unit test %s created.
Generated files into %s directory.
""", suite_name, test_dir)
except IOError:
logging.error("Cannot create files for a unit test.")

View File

@ -0,0 +1,142 @@
"""
Copyright (c) 2018, Arm Limited
SPDX-License-Identifier: Apache-2.0
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.
UNIT TEST OPTIONS
"""
import argparse
import logging
from .settings import CMAKE_GENERATORS, MAKE_PROGRAMS, COVERAGE_TYPES
from .get_tools import get_make_tool
def get_options_parser():
"""
Create a unit test options parser.
Returns a parser object
"""
parser = argparse.ArgumentParser()
log_group = parser.add_mutually_exclusive_group()
log_group.add_argument("-v",
"--verbose",
help="Verbose output",
action="store_const",
const=logging.getLevelName(logging.DEBUG),
dest="log_level")
log_group.add_argument("--quiet",
help="Quiet output",
action="store_const",
const=logging.getLevelName(logging.ERROR),
dest="log_level")
parser.add_argument("--compile",
action="store_true",
help="Only compile unit tests",
dest="compile_only")
parser.add_argument("--run",
action="store_true",
help="Only run unit tests",
dest="run_only")
parser.add_argument("-c",
"--clean",
action="store_true",
help="Clean the build directory",
dest="clean")
parser.add_argument("-d",
"--debug",
action="store_true",
help="Enable debug build",
dest="debug_build")
parser.add_argument("--coverage",
choices=COVERAGE_TYPES,
help="Generate code coverage report",
dest="coverage")
parser.add_argument("-m",
"--make-program",
default=get_make_tool(),
choices=MAKE_PROGRAMS,
help="Which make program to use",
dest="make_program")
parser.add_argument("-g",
"--generator",
choices=CMAKE_GENERATORS,
help="Which CMake generator to use",
dest="cmake_generator")
parser.add_argument("-r",
"--regex",
help="Run tests matching a regular expression",
dest="test_regex")
parser.add_argument("--build",
default="build",
help="Build directory. Default: UNITTESTS/build/",
dest="build")
parser.add_argument("--new",
action="append",
help="Source file from which to generate test files. E.g. rtos/Semaphore.cpp",
metavar="FILEPATH",
dest="new_files")
return parser
def pretty_print_test_options(options=None):
"""
Pretty print test options
Keyword arguments:
options - options
"""
if options is None:
return
# Mode
logging.info("""
#####################
Mbed OS unit testing:
#####################
""")
logging.info("Steps:\n")
logging.info(" [%s] \tPrepare build directory", "AUTO")
logging.info(" \t\t - Clean: %s", options.clean)
logging.info(" \t\t - Directory: %s\n", options.build)
status = "SET" if options.compile_only else "UNSET"
logging.info(" [%s] \tBuild unit tests", status)
logging.info(" \t\t - Debug: %s", options.debug_build)
logging.info(" \t\t - CMake generator: %s", options.cmake_generator)
logging.info(" \t\t - Make program: %s\n", options.make_program)
status = "SET" if options.run_only else "UNSET"
logging.info(" [%s] \tRun unit tests", status)
logging.info(" \t\t - Filter: %s\n", options.test_regex)
if options.coverage:
logging.info(" [%s] \tGenerate coverage reports", "SET")
logging.info(" \t\t - Output: %s", options.coverage)

View File

@ -0,0 +1,40 @@
"""
Copyright (c) 2018, Arm Limited
SPDX-License-Identifier: Apache-2.0
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.
UNIT TEST SETTINGS
"""
CMAKE_GENERATORS = ["Unix Makefiles", "MinGW Makefiles", "Ninja"]
MAKE_PROGRAMS = ["gmake", "make", "mingw32-make", "ninja"]
DEFAULT_CMAKE_GENERATORS = {
"gmake": "Unix Makefiles",
"make": "Unix Makefiles",
"mingw32-make": "MinGW Makefiles",
"ninja": "Ninja"
}
COVERAGE_TYPES = ["html",
"xml",
"both"]
CXX_COMPILERS = ["g++-6", "g++-8", "g++-7", "g++-5", "g++-4.9", "g++"]
C_COMPILERS = ["gcc-6", "gcc-8", "gcc-7", "gcc-5", "gcc-4.9", "gcc"]
GCOV_PROGRAMS = ["gcov-6", "gcov-8", "gcov-7", "gcov-5", "gcov-4.9", "gcov"]

270
UNITTESTS/unit_test/test.py Normal file
View File

@ -0,0 +1,270 @@
"""
Copyright (c) 2018, Arm Limited
SPDX-License-Identifier: Apache-2.0
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.
UNIT TEST BUILD & RUN
"""
import os
import logging
import sys
from shutil import copy
from .utils import execute_program
from .get_tools import get_make_tool, \
get_cmake_tool, \
get_cxx_tool, \
get_c_tool, \
get_gcov_program, \
get_gcovr_program
from .settings import DEFAULT_CMAKE_GENERATORS
class UnitTestTool(object):
"""
Unit test tool to:
- prepare build directory
- create makefiles
- build unit tests
- run unit tests
- generate code coverage reports
"""
def __init__(self,
make_program=None):
"""
Constructor
Keyword arguments:
make_program - Make tool to use
"""
self.make_program = make_program
if self.make_program is None:
self.make_program = get_make_tool()
def create_makefiles(self,
path_to_src=None,
generator=None,
coverage_output_type=None,
debug=False):
"""
Create Makefiles and prepare targets with CMake.
Keyword arguments:
path_to_src - Path to source directory
generator - Type of Makefiles to generate
coverage_output_type - Generate HTML, XML or both reports
debug - Target debug or release build
"""
if generator is None:
generator = DEFAULT_CMAKE_GENERATORS.get(self.make_program,
"Unix Makefiles")
cmake = get_cmake_tool()
if cmake is None:
logging.error(
"No CMake found in Path. Install all the required tools.")
sys.exit(1)
args = [cmake,
"-G",
generator,
"-DCMAKE_MAKE_PROGRAM=%s" % self.make_program,
"-DCMAKE_CXX_COMPILER=%s" % get_cxx_tool(),
"-DCMAKE_C_COMPILER=%s" % get_c_tool()]
if debug:
args.append("-DCMAKE_BUILD_TYPE=Debug")
if coverage_output_type:
args.append("-DCOVERAGE:STRING=%s" % coverage_output_type)
if path_to_src is not None:
args.append(path_to_src)
execute_program(args,
"CMake failed to run successfully. See error message.")
def build_tests(self):
"""
Build unit tests and libraries to be tested.
"""
args = [self.make_program]
if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
args.append("VERBOSE=1")
execute_program(args,
"Building unit tests failed.",
"Unit tests built successfully.")
def _get_coverage_script(self, coverage_type, excludes):
args = [get_gcovr_program(),
"--gcov-executable",
get_gcov_program(),
"-r",
"../..",
"."]
if coverage_type == "html":
args.extend(["--html",
"--html-detail",
"-o",
"./coverage/index.html"])
elif coverage_type == "xml":
args.extend(["-x",
"-o",
"./coverage.xml"])
for path in excludes:
args.extend(["-e", path])
if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
args.append("-v")
return args
def generate_coverage_report(self,
coverage_output_type=None,
excludes=None,
build_path=None):
"""
Run tests to generate coverage data, and generate coverage reports.
"""
self.run_tests()
if get_gcovr_program() is None:
logging.error("No gcovr tool found in path. \
Cannot generate coverage report.")
return
if build_path is None:
build_path = os.getcwd()
if coverage_output_type is None:
logging.warning("No coverage output type give. \
Cannot generate coverage reports.")
return
if excludes is None:
excludes = []
if coverage_output_type == "html" or coverage_output_type == "both":
# Create build directory if not exist.
coverage_path = os.path.join(build_path, "coverage")
if not os.path.exists(coverage_path):
os.mkdir(coverage_path)
args = self._get_coverage_script("html", excludes)
execute_program(args,
"HTML code coverage report generation failed.",
"HTML code coverage report created.")
if coverage_output_type == "xml" or coverage_output_type == "both":
args = self._get_coverage_script("xml", excludes)
execute_program(args,
"XML code coverage report generation failed.",
"XML code coverage report created.")
def run_tests(self, filter_regex=None):
"""
Run unit tests.
Keyword arguments:
filter_regex - Regular expression to select which tests to run
"""
args = [self.make_program, "test"]
if filter_regex:
args.append("ARGS=-R %s -V -D ExperimentalTest" % filter_regex)
else:
args.append("ARGS=-V -D ExperimentalTest")
if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
args.append("VERBOSE=1")
execute_program(args, "Unit test run failed.")
def prepare_build_directory(self,
path_to_src=None,
build_path=None,
clean=False):
"""
Create build directory if not exist and
change current working directory to it
Keyword arguments:
path_to_src - Path to source directory
build_path - Path to build directory
clean - Clean build directory
"""
if build_path is None:
build_path = os.getcwd()
# Clean CMake data if exists.
if clean:
self._clean_build(build_path)
# Create build directory if not exist.
if not os.path.exists(build_path):
os.makedirs(build_path)
filename = ".mbedignore"
inputfile = os.path.join(path_to_src, filename)
outputfile = os.path.join(build_path, filename)
copy(inputfile, outputfile)
# Change current working directory to build directory.
os.chdir(build_path)
def _clean_build(self, build_path=None):
"""
Try clean build directory
Keyword arguments:
build_path - Path to build directory
"""
logging.info("Cleaning build directory...")
if os.path.exists(os.path.join(build_path, "CMakeCache.txt")):
args = [self.make_program,
"-C",
build_path,
"--no-print-directory",
"clean"]
# Remove coverage files
for root, _, files in os.walk(build_path):
for current_file in files:
if current_file.endswith((".gcno", ".gcda")):
os.remove(os.path.join(root, current_file))
execute_program(args,
"Clean step failed.",
"Clean done.")
else:
logging.warning("%s does not exist or \
does not contain previous build data.", build_path)

View File

@ -0,0 +1,66 @@
"""
Copyright (c) 2018, Arm Limited
SPDX-License-Identifier: Apache-2.0
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.
UNIT TEST UTILITIES
"""
import platform
import subprocess
import logging
import sys
def is_tool(name):
"""
Test if tool is found in PATH
@param name: executable name
@return: true if tool found, false otherwise
"""
cmd = "where" if platform.system() == "Windows" else "which"
try:
subprocess.check_output([cmd, name], stderr=subprocess.STDOUT)
return True
except subprocess.CalledProcessError:
return False
def execute_program(args, error_msg="An error occurred!", success_msg=None):
"""
Execute program in a subprocess with given arguments
@param args: program and its arguments in a list
@param success_msg: message to show in case of success
@param error_msg: message to show in case of failure
"""
try:
process = subprocess.Popen(args,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
while process.poll() is None:
logging.info(process.stdout.readline().decode("utf8"))
retcode = process.wait()
if retcode:
raise subprocess.CalledProcessError(retcode, args)
elif success_msg:
logging.info(success_msg)
except subprocess.CalledProcessError as error:
logging.error(error_msg)
sys.exit(error.returncode)

View File

@ -855,7 +855,8 @@ EXCLUDE_PATTERNS = */tools/* \
*/mbed-client-randlib/* \
*/nanostack/sal-stack-nanostack-eventloop/* \
*/ble/generic/* \
*/ble/pal/*
*/ble/pal/* \
*/UNITTESTS/*
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the