aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorImre Kis <imre.kis@arm.com>2019-10-08 12:56:59 +0200
committerImre Kis <imre.kis@arm.com>2021-02-08 17:21:09 +0100
commita21712e50907702b82639b22bdd37f778d4ff87d (patch)
treef310178d08f5b61f002ddb3d54c155e8bb503f6f
parent2116e25a5c104b38852fb7c6b848a9ad5a2beb52 (diff)
downloadtrusted-services-a21712e50907702b82639b22bdd37f778d4ff87d.tar.gz
Add initial version of firmware-test-builder
Introduce the following features to firmware-test-builder: * Testing on the host machine (PC) * Provides CMake functions for building/running/evaluating tests * Checking prerequisites (git, c-picker, libclang, etc.) * Fetching and building CppUTest * Defining and building unit test suites (i.e. separate binaries) * Handling c-picker based extraction of code snippets * Registering test suites to CTest (CMake's test system) which runs all the test binaries * Generating coverage report * Documentation of the system Signed-off-by: Imre Kis <imre.kis@arm.com> Change-Id: Ic0a1af55bef07c6e76071193caa94a9a48f9041f
-rw-r--r--.editorconfig102
-rw-r--r--.gitignore20
-rw-r--r--cmake/Coverage.cmake286
-rw-r--r--cmake/FindLibClang.cmake90
-rw-r--r--cmake/UnitTest.cmake322
-rw-r--r--common/cpputest-cmake-fix.patch13
-rw-r--r--common/main.cpp12
-rw-r--r--dco.txt37
-rw-r--r--docs/Makefile25
-rw-r--r--docs/SphinxBuild.cmake18
-rw-r--r--docs/_static/TrustedFirmware-Logo_standard-white.pngbin0 -> 5826 bytes
-rw-r--r--docs/_templates/.keep_me0
-rw-r--r--docs/components/build_system.rst22
-rw-r--r--docs/components/c_picker.rst61
-rw-r--r--docs/components/code_coverage.rst27
-rw-r--r--docs/components/cppumock.rst197
-rw-r--r--docs/components/cpputest.rst281
-rw-r--r--docs/components/index.rst14
-rw-r--r--docs/conf.py109
-rw-r--r--docs/global_substitutions.txt26
-rw-r--r--docs/implementing_tests.rst331
-rw-r--r--docs/index.rst44
-rw-r--r--docs/project/change-log.rst29
-rw-r--r--docs/project/coding-guidelines.rst69
-rw-r--r--docs/project/contributing.rst83
-rw-r--r--docs/project/glossary.rst38
-rw-r--r--docs/project/index.rst22
-rw-r--r--docs/project/license.rst37
-rw-r--r--docs/project/maintainers.rst41
-rw-r--r--docs/project/versioning_policy.rst42
-rw-r--r--docs/project/writing-documentation.rst52
-rw-r--r--docs/resources/TrustedFirmware-Logo_standard-white.pngbin0 -> 5826 bytes
-rw-r--r--docs/resources/sequence_print_to_eeprom.puml46
-rw-r--r--docs/resources/sequence_print_to_eeprom_mock.puml48
-rw-r--r--docs/user_guide.rst201
-rw-r--r--license.rst7
-rw-r--r--readme.rst24
-rw-r--r--version.txt1
38 files changed, 2777 insertions, 0 deletions
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 000000000..fa1c6b58c
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,102 @@
+#
+# Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+# References:
+# [LCS] Linux Coding Style
+# (https://www.kernel.org/doc/html/v4.10/process/coding-style.html)
+# [PEP8] Style Guide for Python Code
+# (https://www.python.org/dev/peps/pep-0008)
+
+root = true
+
+################################
+# Default settings for all files
+[*]
+# Windows .bat files may have trouble with utf8 and will fail with lf line ends.
+# Currently no plans to add .bat files, but this can be an issue in the future.
+charset = uft-8
+end_of_line = lf
+trim_trailing_whitespace = true
+indent_size = 4
+indent_style = tab
+
+################################
+#C and C++, follow LCS
+[*.{c,h,cpp,hpp}]
+
+# [LCS] Chapter 1: Indentation
+# "Tabs are 8 characters"
+tab_width = 8
+
+# [LCS] Chapter 1: Indentation
+# "and thus indentations are also 8 characters"
+indent_size = 8
+
+# [LCS] Chapter 1: Indentation
+# "Outside of comments,...spaces are never used for indentation"
+indent_style = tab
+
+# [LCS] Chapter 2: Breaking long lines and strings
+# "Statements may be up to 100 columns when appropriate."
+# This is a "soft" requirement for Arm-TF, and should not be the sole
+# reason for changes.
+max_line_length = 100
+
+# [LCS] Chapter 1: Indentation
+# "Get a decent editor and don't leave whitespace at the end of lines."
+# [LCS] Chapter 3.1: Spaces
+# "Do not leave trailing whitespace at the ends of lines."
+trim_trailing_whitespace = true
+
+
+################################
+#CMake specific settings
+[{CMakeLists.txt,*.cmake}]
+charset = utf-8
+end_of_line = lf
+indent_size = 4
+indent_style = tab
+insert_final_newline = false
+max_line_length = 128
+trim_trailing_whitespace = true
+
+################################
+#Documentation
+[*.{rst,md}]
+charset = utf-8
+end_of_line = lf
+indent_size = 4
+indent_style = space
+insert_final_newline = false
+max_line_length = 128
+tab_width = 4
+trim_trailing_whitespace = true
+
+################################
+# Python code
+[*.py]
+# [PEP8] Indentation
+# "Use 4 spaces per indentation level."
+indent_size = 4
+indent_style = space
+# [PEP8] Maximum Line Length
+# "Limit all lines to a maximum of 79 characters."
+max_line_length = 79
+
+################################
+# Makefiles
+[{Makefile,*.mk}]
+indent_style = tab
+indent_size = 4
+
+################################
+# json,yaml and xml files
+[{*.json,*.yaml,*.xml}]
+indent_style = space
+indent_size = 4
+tab_width = 4
+trim_trailing_whitespace = true
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..af93826a3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2019-2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+#Ignore all build directoryes.
+*build*/
+
+##Python specific intermediate files
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+#Ignore Eclipse project files
+.project
+.cproject
+.settings
+.pydevproject
diff --git a/cmake/Coverage.cmake b/cmake/Coverage.cmake
new file mode 100644
index 000000000..b7a643931
--- /dev/null
+++ b/cmake/Coverage.cmake
@@ -0,0 +1,286 @@
+#
+# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+#[===[.rst:
+Coverage CMake module
+---------------------
+
+Control flow
+^^^^^^^^^^^^
+
+Using the code coverage feature of the system starts with including
+``Coverage`` module. This will implicitly check if all the requirements for
+generating coverage are fulfilled. This includes checking the following
+conditions.
+
+- Compiler is GCC
+- lcov executables exist
+- ``c-picker-coverage-mapper`` is available
+
+As the next step it sets the compiler flags to make GCC to generate binaries
+with coverage information.
+
+
+Variables
+^^^^^^^^^
+
+The module sets the following variables while it's checking its prerequisites.
+
+.. cmake:variable:: LCOV_COMMAND
+
+Path of lcov executable
+
+.. cmake:variable:: GENHTML_COMMAND
+
+Path of genhtml executable which is part of the lcov package.
+
+.. cmake:variable:: CPICKER_COVERAGE_MAPPER_COMMAND
+
+Path of ``c-picker-coverage-mapper`` executable which is provided by c-picker
+pip package.
+
+
+Functions
+^^^^^^^^^
+
+The module also contains functions for setting up the coverage feature.
+
+#]===]
+
+include_guard(DIRECTORY)
+
+# Checking GCC
+if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ message(FATAL_ERROR "Coverage measurement is only supported when using GCC")
+endif()
+
+# Checking lcov
+find_program(LCOV_COMMAND "lcov")
+if (NOT LCOV_COMMAND)
+ message(FATAL_ERROR "Please install lcov")
+endif()
+
+# Checking c-picker-coverage-mapper
+find_program(CPICKER_COVERAGE_MAPPER_COMMAND "c-picker-coverage-mapper")
+if (NOT CPICKER_COVERAGE_MAPPER_COMMAND)
+ message(FATAL_ERROR "Please install c-picker-coverage-mapper using pip (part of c-picker)")
+endif()
+
+# Checking genhtml
+find_program(GENHTML_COMMAND "genhtml")
+if (NOT GENHTML_COMMAND)
+ message(FATAL_ERROR "Please install genhtml with genhtml (part of lcov)")
+endif()
+
+# Including this file enables code coverage measurement by adding the necessary compiler and
+# linker flags.
+set(CMAKE_C_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
+set(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage -fno-exceptions")
+set(CMAKE_EXE_LINKER_FLAGS "-fprofile-arcs -ftest-coverage")
+
+# Adding custom targets
+add_custom_target(coverage)
+add_custom_target(coverage_report)
+
+# Adds a file to the dependency list of the target by inserting an accessory
+# custom target. The name of the custom target is properly escaped.
+function(add_coverage_dependency)
+ set(_OPTIONS_ARGS)
+ set(_ONE_VALUE_ARGS TARGET DEPENDS)
+ set(_MULTI_VALUE_ARGS)
+ cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+ set(TARGET ${_MY_PARAMS_TARGET})
+ set(DEPENDS ${_MY_PARAMS_DEPENDS})
+
+ string(REGEX REPLACE "\\/" "_" CUSTOM_TARGET_SUFFIX ${DEPENDS})
+
+ add_custom_target(${TARGET}_target_${CUSTOM_TARGET_SUFFIX} DEPENDS ${DEPENDS})
+ add_dependencies(${TARGET} ${TARGET}_target_${CUSTOM_TARGET_SUFFIX})
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: coverage_generate
+
+ .. code-block:: cmake
+
+ coverage_generate(
+ NAME test_name
+ SOURCE_DIR source_directory
+ BINARY_DIR binary_directory
+ OUTPUT_FILE output_file
+ )
+
+ The function outputs an lcov info file for further processing. It also handles
+ the remapping of the coverage of the c-picker generated files.
+
+ Control flow:
+
+ 1. Running the ``lcov`` command for collecting the coverage data from the
+ available ``.gcda`` and ``.gcno`` files in the ``BINARY_DIR``.
+
+ 2. The output of previous step is processed by ``c-picker-coverage-mapper``.
+ This will remap the coverage of files in ``CPICKER_CACHE_PATH`` to the
+ original source files.
+
+ 3. Adds the output file to the ``coverage`` target's dependency list.
+
+ Inputs:
+
+ ``NAME``
+ Test name included in lcov info file
+
+ ``SOURCE_DIR``
+ Directory of source files
+
+ ``BINARY_DIR``
+ Directory of the ``.gcda`` and ``.gcno`` files
+
+ ``OUTPUT_FILE``
+ Output lcov coverage info file
+
+ Global dependencies:
+
+ ``CPICKER_CACHE_PATH``
+ Root directory of the c-picker generated files
+
+
+#]===]
+function(coverage_generate)
+ set(_OPTIONS_ARGS)
+ set(_ONE_VALUE_ARGS NAME SOURCE_DIR BINARY_DIR OUTPUT_FILE)
+ set(_MULTI_VALUE_ARGS)
+ cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+ set(TEST_NAME ${_MY_PARAMS_NAME})
+ set(SOURCE_DIR ${_MY_PARAMS_SOURCE_DIR})
+ set(BINARY_DIR ${_MY_PARAMS_BINARY_DIR})
+ set(TEMP_FILE ${_MY_PARAMS_OUTPUT_FILE}_temp)
+ set(OUTPUT_FILE ${_MY_PARAMS_OUTPUT_FILE})
+
+ # Collecting information from .gcda and .gcno files into an lcov .info file
+ # Mapping c-picker generated files' coverage info to the original source lines
+ add_custom_command(
+ OUTPUT ${TEMP_FILE} ${OUTPUT_FILE}
+ COMMAND ${LCOV_COMMAND}
+ --capture
+ --test-name ${TEST_NAME}
+ --directory ${BINARY_DIR}
+ --base-directory ${SOURCE_DIR}
+ --output-file ${TEMP_FILE}
+ COMMAND ${CPICKER_COVERAGE_MAPPER_COMMAND}
+ --input ${TEMP_FILE}
+ --output ${OUTPUT_FILE}
+ --mapping-path ${CPICKER_CACHE_PATH}
+ )
+
+ add_coverage_dependency(
+ TARGET coverage
+ DEPENDS ${OUTPUT_FILE}
+ )
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: coverage_filter
+
+ .. code-block:: cmake
+
+ coverage_filter(
+ INPUT_FILE input_file
+ OUTPUT_FILE output_file
+ INCLUDE_DIRECTORY include_directory
+ )
+
+ The function filters the coverage data by including only the coverage of the
+ files of ``INCLUDE_DIRECTORY`` or its subdirectories. It adds the filtered
+ output file to the ``coverage`` target's dependency list.
+
+ Inputs:
+
+ ``INPUT_FILE``
+ Input lcov coverage info file
+
+ ``OUTPUT_FILE``
+ Output lcov coverage info file
+
+ ``INCLUDE_DIRECTORY``
+ Root directory of included files
+
+#]===]
+function(coverage_filter)
+ set(_OPTIONS_ARGS)
+ set(_ONE_VALUE_ARGS INPUT_FILE OUTPUT_FILE INCLUDE_DIRECTORY)
+ set(_MULTI_VALUE_ARGS)
+ cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+ set(INPUT_FILE ${_MY_PARAMS_INPUT_FILE})
+ set(OUTPUT_FILE ${_MY_PARAMS_OUTPUT_FILE})
+ set(INCLUDE_DIRECTORY ${_MY_PARAMS_INCLUDE_DIRECTORY})
+
+ # The pattern must be an absolute path ending with an asterisk
+ get_filename_component(INCLUDE_DIRECTORY_ABSPATH "${INCLUDE_DIRECTORY}" ABSOLUTE)
+ set(INCLUDE_DIRECTORY_ABSPATH "${INCLUDE_DIRECTORY_ABSPATH}/*")
+
+ add_custom_command(
+ OUTPUT ${OUTPUT_FILE}
+ COMMAND ${LCOV_COMMAND}
+ --extract ${INPUT_FILE} \"${INCLUDE_DIRECTORY_ABSPATH}\"
+ --output-file ${OUTPUT_FILE}
+ DEPENDS ${INPUT_FILE}
+ )
+
+ add_coverage_dependency(
+ TARGET coverage
+ DEPENDS ${OUTPUT_FILE}
+ )
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: coverage_generate_report
+
+ .. code-block:: cmake
+
+ coverage_generate_report(
+ INPUT_FILE input_file
+ OUTPUT_DIRECTORY output_directory
+ )
+
+ The function generates a HTML coverage report from the lcov info file into
+ the ``OUTPUT_DIRECTORY``. It adds the output directory to the
+ ``coverage_report`` target's dependency list.
+
+ Inputs:
+
+ ``INPUT_FILE``
+ Input lcov coverage info file
+
+ ``OUTPUT_DIRECTORY``
+ Output directory of the coverage report where the ``index.html`` is the
+ root file of the report.
+
+#]===]
+function(coverage_generate_report)
+ set(_OPTIONS_ARGS)
+ set(_ONE_VALUE_ARGS INPUT_FILE OUTPUT_DIRECTORY)
+ set(_MULTI_VALUE_ARGS)
+ cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+ set(INPUT_FILE ${_MY_PARAMS_INPUT_FILE})
+ set(OUTPUT_DIRECTORY ${_MY_PARAMS_OUTPUT_DIRECTORY})
+
+ add_custom_command(
+ OUTPUT ${OUTPUT_DIRECTORY}
+ COMMAND genhtml ${INPUT_FILE}
+ --show-details
+ --output-directory ${OUTPUT_DIRECTORY}
+ DEPENDS ${INPUT_FILE}
+ )
+
+ add_coverage_dependency(
+ TARGET coverage_report
+ DEPENDS ${OUTPUT_DIRECTORY}
+ )
+endfunction()
diff --git a/cmake/FindLibClang.cmake b/cmake/FindLibClang.cmake
new file mode 100644
index 000000000..c371449c6
--- /dev/null
+++ b/cmake/FindLibClang.cmake
@@ -0,0 +1,90 @@
+#
+# Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+#[=======================================================================[.rst:
+FindLibClang
+------------
+
+CMake module for finding the LibClang library.
+
+Control flow
+^^^^^^^^^^^^
+
+1. Running ``llvm-config`` if exists
+2. Searching for library at common places
+3. Searching in Windows registry if available
+
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+This module provides the following imported targets, if found:
+
+``LibClang``
+ The Clang library
+
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This will define the following variables:
+
+``LibClang_FOUND``
+ True if the system has the Clang library.
+``LibClang_LIBRARY_DIRS``
+ Libraries needed to link to Clang.
+
+#]=======================================================================]
+
+
+# 1. Use llvm-config
+find_program(_LLVM_CONFIG_COMMAND "llvm-config")
+
+if (_LLVM_CONFIG_COMMAND)
+ message(STATUS "Setting LibClang_LIBRARY_DIRS using ${_LLVM_CONFIG_COMMAND}")
+
+ execute_process(
+ COMMAND ${_LLVM_CONFIG_COMMAND} --libdir
+ OUTPUT_VARIABLE _LLVM_CONFIG_OUTPUT
+ )
+
+ # Stripping newline
+ string(STRIP ${_LLVM_CONFIG_OUTPUT} LibClang_LIBRARY_DIRS)
+endif()
+
+# 2. Try to find as library
+if (NOT LibClang_LIBRARY_DIRS)
+ message(STATUS "Setting LibClang_LIBRARY_DIRS based on common directories list")
+
+ set(LIBCLANG_COMMON_PATHS
+ /usr/lib/llvm-9/lib
+ /usr/lib/llvm-8/lib
+ /usr/lib/llvm-7/lib
+ /usr/lib/llvm-6.0/lib)
+
+ if (WIN32)
+ set(CMAKE_FIND_LIBRARY_PREFIXES "lib")
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll")
+
+ get_filename_component(LLVM_PATH_FROM_REGISTRY [HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\LLVM\\LLVM] ABSOLUTE)
+ list(APPEND LIBCLANG_COMMON_PATHS "${LLVM_PATH_FROM_REGISTRY}/bin")
+ endif()
+
+ find_library(_LIBCLANG_PATH
+ NAMES clang
+ HINTS ${LIBCLANG_COMMON_PATHS}
+ )
+
+ if (_LIBCLANG_PATH)
+ get_filename_component(LibClang_LIBRARY_DIRS ${_LIBCLANG_PATH} DIRECTORY)
+ endif()
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LibClang
+ "Please install llvm-config or set LibClang path manually"
+ LibClang_LIBRARY_DIRS
+)
diff --git a/cmake/UnitTest.cmake b/cmake/UnitTest.cmake
new file mode 100644
index 000000000..d61ed9aea
--- /dev/null
+++ b/cmake/UnitTest.cmake
@@ -0,0 +1,322 @@
+#
+# Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+#[===[.rst:
+UnitTest CMake module
+---------------------
+
+Control flow
+^^^^^^^^^^^^
+
+1. Setting :cmake:variable:`CLANG_LIBRARY_PATH`
+
+ 1. Using :cmake:variable:`CLANG_LIBRARY_PATH` CMake variable
+
+ 2. Using ``CLANG_LIBRARY_PATH`` environment variable
+
+ 3. Trying to find by ``find_package`` function which calls :cmake:module:`FindLibClang`.
+
+2. Checking if ``c-picker`` command is available
+
+
+Variables
+^^^^^^^^^
+
+The module sets the following variables while it's checking its prerequisites.
+
+.. cmake:variable:: GIT_COMMAND
+
+Path of git executable.
+
+.. cmake:variable:: CLANG_LIBRARY_PATH
+
+c-picker uses libclang to parse the source files. If defined this variable
+specifies the path of the library.
+
+.. cmake:variable:: CPICKER_COMMAND
+
+Path of c-picker executable which is part of the c-picker pip package.
+
+.. cmake:variable:: UNIT_TEST_PROJECT_PATH
+
+Path of the project source directory. **This needs to be specified
+by the developer** to point to a suitable working copy of project to be tested.
+
+.. cmake:variable:: CPPUTEST_URL
+
+URL of the CppUTest git repository. By default it points to the official Github
+repository of CppUTest. It can be used to specify a different CppUTest mirror.
+
+.. cmake:variable:: CPPUTEST_REFSPEC
+
+CppUTest git refspec. The default value selects the latest release.
+
+.. cmake:variable:: CPPUTEST_INSTALL_PATH
+
+Temporary directory used during CppUTest build
+
+.. cmake:variable:: CPPUTEST_PACKAGE_PATH
+
+Path of the CppUTest CMake package directory
+
+.. cmake:variable:: CPICKER_CACHE_PATH
+
+Directory of c-picker generated files. Subdirectories are added according to
+the path of the original source file's path.
+
+.. cmake:variable:: UNIT_TEST_COMMON_SOURCES
+
+Lists of source files that are included in all test builds.
+
+
+Functions
+^^^^^^^^^
+
+#]===]
+
+include_guard(DIRECTORY)
+
+include(FetchContent)
+
+set(CLANG_LIBRARY_PATH_HELP "libclang directory for c-picker")
+
+set(CPPUTEST_URL "https://github.com/cpputest/cpputest.git" CACHE STRING "CppUTest repository URL")
+set(CPPUTEST_REFSPEC "v4.0" CACHE STRING "CppUTest git refspec")
+set(CPPUTEST_INSTALL_PATH ${CMAKE_CURRENT_BINARY_DIR}/CppUTest_install CACHE PATH "CppUTest installation directory")
+set(CPPUTEST_PACKAGE_PATH ${CPPUTEST_INSTALL_PATH}/lib/CppUTest/cmake CACHE PATH "CppUTest CMake package directory")
+
+set(CPICKER_CACHE_PATH ${CMAKE_CURRENT_BINARY_DIR}/cpicker_cache CACHE PATH "Directory of c-picker generated file")
+
+set(UNIT_TEST_COMMON_SOURCES ${CMAKE_CURRENT_LIST_DIR}/../common/main.cpp CACHE STRING "List of common test source files")
+
+# Checking git
+find_program(GIT_COMMAND "git")
+if (NOT GIT_COMMAND)
+ message(FATAL_ERROR "Please install git")
+endif()
+
+if (DEFINED CLANG_LIBRARY_PATH)
+ message(STATUS "Using CLANG_LIBRARY_PATH from CMake variable (command line or cache)")
+
+ if (DEFINED ENV{CLANG_LIBRARY_PATH})
+ if (NOT (${CLANG_LIBRARY_PATH} STREQUAL $ENV{CLANG_LIBRARY_PATH}))
+ message(WARNING "Both CLANG_LIBRARY_PATH CMake and environment variables are set but have different values")
+ endif()
+ endif()
+else()
+ if (DEFINED ENV{CLANG_LIBRARY_PATH})
+ message(STATUS "Setting CLANG_LIBRARY_PATH based on environment variable")
+ set(CLANG_LIBRARY_PATH $ENV{CLANG_LIBRARY_PATH} CACHE PATH ${CLANG_LIBRARY_PATH_HELP})
+ else()
+ message(STATUS "Setting CLANG_LIBRARY_PATH based on find_package")
+ find_package(LibClang REQUIRED)
+ set(CLANG_LIBRARY_PATH ${LibClang_LIBRARY_DIRS} CACHE PATH ${CLANG_LIBRARY_PATH_HELP})
+ endif()
+endif()
+
+message(STATUS "CLANG_LIBRARY_PATH has been set to ${CLANG_LIBRARY_PATH}")
+
+# Checking c-picker
+find_program(CPICKER_COMMAND "c-picker")
+if (NOT CPICKER_COMMAND)
+ message(FATAL_ERROR "Please install c-picker using pip")
+endif()
+
+#[===[.rst:
+.. cmake:command:: unit_test_init_cpputest
+
+ .. code-block:: cmake
+
+ unit_test_init_cpputest()
+
+ The ``unit_test_init_cpputest`` CMake function fetches and build CppUTest unit testing framework.
+ It also enables linking the library to the test binaries.
+
+ Global dependencies:
+
+ ``CPPUTEST_URL``
+ Root directory of the c-picker generated files
+
+ ``CPPUTEST_REFSPEC``
+ Common source files for every test build
+
+#]===]
+function(unit_test_init_cpputest)
+ # Fetching CppUTest
+ FetchContent_Declare(
+ cpputest
+ GIT_REPOSITORY ${CPPUTEST_URL}
+ GIT_TAG ${CPPUTEST_REFSPEC}
+ GIT_SHALLOW TRUE
+ PATCH_COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/common/cpputest-cmake-fix.patch || true
+ )
+
+ # FetchContent_GetProperties exports cpputest_SOURCE_DIR and cpputest_BINARY_DIR variables
+ FetchContent_GetProperties(cpputest)
+ if(NOT cpputest_POPULATED)
+ message(STATUS "Fetching CppUTest")
+ FetchContent_Populate(cpputest)
+ endif()
+
+ # Build and install CppUTest in CMake time. This makes us able to use CppUTest as a CMake package later.
+ # Memory leak detection is turned off to avoid conflict with memcheck.
+ execute_process(COMMAND
+ ${CMAKE_COMMAND}
+ -DMEMORY_LEAK_DETECTION=OFF
+ -DLONGLONG=ON
+ -DC++11=ON
+ -DCMAKE_INSTALL_PREFIX=${CPPUTEST_INSTALL_PATH}
+ -GUnix\ Makefiles
+ ${cpputest_SOURCE_DIR}
+ WORKING_DIRECTORY
+ ${cpputest_BINARY_DIR}
+ )
+ execute_process(COMMAND ${CMAKE_COMMAND} --build ${cpputest_BINARY_DIR} -- install -j)
+
+ # Finding CppUTest package. CMake will check [package name]_DIR variable.
+ set(CppUTest_DIR ${CPPUTEST_PACKAGE_PATH} CACHE PATH "Path of CppUTestConfig.cmake")
+ find_package(CppUTest CONFIG REQUIRED)
+
+ # find_package sets the CppUTest_INCLUDE_DIRS and CppUTest_LIBRARIES variables
+ include_directories(${CppUTest_INCLUDE_DIRS})
+ link_libraries(${CppUTest_LIBRARIES})
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: unit_test_add_suite
+
+ .. code-block:: cmake
+
+ unit_test_add_suite(
+ NAME test_name
+ SOURCES source_files
+ INCLUDE_DIRECTORIES include_directories
+ COMPILE_DEFINITIONS defines
+ DEPENDS dependencies
+ )
+
+ The ``unit_test_add_suite`` CMake function provides a convenient interface for
+ defining unit test suites. Basically its input is the test source files, include
+ paths and macro definitions and it internally does all the necessary steps to
+ have the test binary registered in CTest as a result.
+
+ Control flow:
+
+ 1. Adding new executable named ``NAME``
+
+ 2. Iterating throught ``SOURCES``
+
+ 1. If it's a normal source file add to the executable's source list
+ 2. If it's a YAML file add as a c-picker custom command and add the generated
+ file to the executable's source list
+
+ 3. Setting include directories
+
+ 4. Setting defines
+
+ 5. Adding extra dependencies of the test build
+
+ 6. Adding executable to the system as a test
+
+ Inputs:
+
+ ``NAME``
+ Unique name of the test suite
+
+ ``SOURCES`` (multi, optional)
+ Source files
+
+ ``INCLUDE_DIRECTORIES`` (multi, optional)
+ Include directories
+
+ ``COMPILE_DEFINITIONS`` (multi, optional)
+ Defines
+
+ ``DEPENDS`` (multi, optional)
+ Extra targets as dependencies of the test build
+
+ Global dependencies:
+
+ ``UNIT_TEST_PROJECT_PATH``
+ Root directory of the project under test.
+
+ ``CPICKER_CACHE_PATH``
+ Root directory of the c-picker generated files
+
+ ``UNIT_TEST_COMMON_SOURCES``
+ Common source files for every test build
+
+ ``CTest``
+ Built-in testing module of CMake
+
+#]===]
+function(unit_test_add_suite)
+ set(_OPTIONS_ARGS)
+ set(_ONE_VALUE_ARGS NAME)
+ set(_MULTI_VALUE_ARGS SOURCES INCLUDE_DIRECTORIES COMPILE_DEFINITIONS DEPENDS)
+ cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+ if(NOT DEFINED BUILD_TESTING)
+ message(FATAL_ERROR
+ "unit_test_add_suite(): "
+ "CTest module should be included in the root CMakeLists.txt before calling this function.")
+ endif()
+
+ if (NOT UNIT_TEST_PROJECT_PATH)
+ message(FATAL_ERROR "UNIT_TEST_PROJECT_PATH is not set")
+ endif()
+
+ set(TEST_NAME ${_MY_PARAMS_NAME})
+ set(TEST_INCLUDE_DIRECTORIES ${_MY_PARAMS_INCLUDE_DIRECTORIES})
+ set(TEST_COMPILE_DEFINITIONS ${_MY_PARAMS_COMPILE_DEFINITIONS})
+ set(TEST_DEPENDS ${_MY_PARAMS_DEPENDS})
+
+ add_executable(${TEST_NAME} ${UNIT_TEST_COMMON_SOURCES})
+
+ foreach(TEST_SOURCE ${_MY_PARAMS_SOURCES})
+ get_filename_component(TEST_SOURCE_EXTENSION ${TEST_SOURCE} EXT)
+
+ if (${TEST_SOURCE_EXTENSION} STREQUAL ".yml")
+ # Building output file name: tests/a/b/test.yml -> ${CPICKER_CACHE_PATH}/a/b/test.c
+ get_filename_component(TEST_SOURCE_DIR ${TEST_SOURCE} DIRECTORY)
+ file(RELATIVE_PATH CPICKER_SOURCE_DIR ${UNIT_TEST_PROJECT_PATH} ${TEST_SOURCE_DIR})
+ get_filename_component(TEST_SOURCE_NAME ${TEST_SOURCE} NAME_WE)
+ set(CPICKER_OUTPUT ${CPICKER_CACHE_PATH}/${TEST_NAME}/${CPICKER_SOURCE_DIR}/${TEST_SOURCE_NAME}.c)
+
+ # Creating output directory
+ get_filename_component(OUTPUT_DIRECTORY ${CPICKER_OUTPUT} DIRECTORY)
+ file(MAKE_DIRECTORY ${OUTPUT_DIRECTORY})
+
+ # Fetching referenced source files as the dependencies of the generated file
+ execute_process(
+ COMMAND
+ ${CMAKE_COMMAND} -E env CLANG_LIBRARY_PATH=${CLANG_LIBRARY_PATH}
+ ${CPICKER_COMMAND} --config ${TEST_SOURCE} --root ${UNIT_TEST_PROJECT_PATH} --print-dependencies
+ OUTPUT_VARIABLE CPICKER_DEPENDENCIES
+ )
+
+ # Adding custom command for invoking c-picker
+ add_custom_command(
+ OUTPUT ${CPICKER_OUTPUT}
+ COMMAND
+ ${CMAKE_COMMAND} -E env CLANG_LIBRARY_PATH=${CLANG_LIBRARY_PATH}
+ ${CPICKER_COMMAND} --config ${TEST_SOURCE} --root ${UNIT_TEST_PROJECT_PATH} > ${CPICKER_OUTPUT}
+ DEPENDS ${TEST_SOURCE} ${CPICKER_DEPENDENCIES}
+ COMMENT "Generating c-picker output ${CPICKER_OUTPUT}"
+ )
+ set(TEST_SOURCE ${CPICKER_OUTPUT})
+ endif()
+
+ target_sources(${TEST_NAME} PRIVATE ${TEST_SOURCE})
+ endforeach()
+
+ target_include_directories(${TEST_NAME} PRIVATE ${TEST_INCLUDE_DIRECTORIES})
+ target_compile_definitions(${TEST_NAME} PRIVATE ${TEST_COMPILE_DEFINITIONS})
+ if (TEST_DEPENDS)
+ add_dependencies(${TEST_NAME} ${TEST_DEPENDS})
+ endif()
+ add_test(${TEST_NAME} ${TEST_NAME})
+endfunction()
diff --git a/common/cpputest-cmake-fix.patch b/common/cpputest-cmake-fix.patch
new file mode 100644
index 000000000..a46bde350
--- /dev/null
+++ b/common/cpputest-cmake-fix.patch
@@ -0,0 +1,13 @@
+diff --git a/src/CppUTest/CMakeLists.txt b/src/CppUTest/CMakeLists.txt
+index 81eda28..4f1db8a 100644
+--- a/src/CppUTest/CMakeLists.txt
++++ b/src/CppUTest/CMakeLists.txt
+@@ -69,7 +69,7 @@ set_target_properties(CppUTest PROPERTIES
+ PUBLIC_HEADER "${CppUTest_headers}")
+
+ if (WIN32)
+- target_link_libraries(CppUTest winmm.lib)
++ target_link_libraries(CppUTest winmm)
+ endif (WIN32)
+ install(TARGETS CppUTest
+ EXPORT CppUTestTargets
diff --git a/common/main.cpp b/common/main.cpp
new file mode 100644
index 000000000..732751f0f
--- /dev/null
+++ b/common/main.cpp
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "CppUTest/CommandLineTestRunner.h"
+
+int main(int argc, char *argv[])
+{
+ return RUN_ALL_TESTS(argc, argv);
+}
diff --git a/dco.txt b/dco.txt
new file mode 100644
index 000000000..8201f9921
--- /dev/null
+++ b/dco.txt
@@ -0,0 +1,37 @@
+Developer Certificate of Origin
+Version 1.1
+
+Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
+1 Letterman Drive
+Suite D4700
+San Francisco, CA, 94129
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+
+Developer's Certificate of Origin 1.1
+
+By making a contribution to this project, I certify that:
+
+(a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+(b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+(c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+(d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 000000000..04e3a70b8
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS ?=
+SPHINXBUILD ?= sphinx-build
+SOURCEDIR = .
+BUILDDIR = _build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/SphinxBuild.cmake b/docs/SphinxBuild.cmake
new file mode 100644
index 000000000..b364813e0
--- /dev/null
+++ b/docs/SphinxBuild.cmake
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Minimal cmake script for running sphinx. Use as:
+# cmake -P SphinxBuild.cmake
+
+# Inputs:
+# SPHINXOPTS : extra options for sphinx
+
+set(SPHINXBUILD "sphinx-build" CACHE PATH "Location of sphinx-build executable.")
+set(SPHNIX_BUILDDIR "_build" CACHE PATH "Directory to place sphinx outpot to.")
+
+exec_program(${SPHINXBUILD} ./
+ ARGS -M html ${CMAKE_CURRENT_LIST_DIR} ${SPHNIX_BUILDDIR} ${SPHINXOPTS}
+ )
diff --git a/docs/_static/TrustedFirmware-Logo_standard-white.png b/docs/_static/TrustedFirmware-Logo_standard-white.png
new file mode 100644
index 000000000..e7bff7128
--- /dev/null
+++ b/docs/_static/TrustedFirmware-Logo_standard-white.png
Binary files differ
diff --git a/docs/_templates/.keep_me b/docs/_templates/.keep_me
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/docs/_templates/.keep_me
diff --git a/docs/components/build_system.rst b/docs/components/build_system.rst
new file mode 100644
index 000000000..4c26b325d
--- /dev/null
+++ b/docs/components/build_system.rst
@@ -0,0 +1,22 @@
+Build system
+============
+
+.. cmake-module:: ../../cmake/UnitTest.cmake
+
+.. cmake-module:: ../../cmake/FindLibClang.cmake
+
+Generating documentation
+------------------------
+
+``sphinx-builder`` is used for building the documentation which is required to be installed on the machine. The documentation
+can be built by executing the following commands.
+
+::
+
+ cd docs
+ make html
+
+
+--------------
+
+*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
diff --git a/docs/components/c_picker.rst b/docs/components/c_picker.rst
new file mode 100644
index 000000000..da89520a3
--- /dev/null
+++ b/docs/components/c_picker.rst
@@ -0,0 +1,61 @@
+c-picker
+========
+
+c-picker uses ``libclang``'s Python interface for parsing source files.
+
+Command line options
+--------------------
+
+- ``-h, --help`` - Showing help message
+- ``--root ROOT`` - Root source directory
+- ``--config CONFIG`` - Configuration file (``.json|.yml``)
+- ``--output OUTPUT`` - Output file
+- ``--print-dependencies`` - Prints the dependencies
+- ``--version`` - Shows the program's version number and exit
+- ``--args ...`` - clang arguments
+
+
+Configuration file format
+-------------------------
+
+c-picker configuration can be described in ``JSON`` or ``YAML`` format using the same object structure.
+
+- ``elements`` - List of elements to pick from the original code
+
+ - ``name`` - Name of the element
+ - ``type`` - Type of the element: ``include``, ``function``, ``variable``
+ - ``args`` - Arguments for clang used during picking the element
+ - ``options`` - Currenly the only options is ``remove_static`` which removes
+ the ``static`` qualifier from the element's definition.
+
+- ``options`` - Global options for all elements
+- ``args`` - Global clang arguments for all elements
+
+YAML example
+------------
+
+YAML format is preferred because it can contain metadata like comments and licence information.
+
+.. code-block:: YAML
+
+ elements:
+ - file: bl1/bl1_fwu.c
+ type: variable
+ name: bl1_fwu_loaded_ids
+ options: [remove_static]
+ - file: bl1/bl1_fwu.c
+ type: function
+ name: bl1_fwu_add_loaded_id
+ options: [remove_static]
+ - file: bl1/bl1_fwu.c
+ type: function
+ name: bl1_fwu_remove_loaded_id
+ options: [remove_static]
+ args:
+ - -DFWU_MAX_SIMULTANEOUS_IMAGES=10
+ - -DINVALID_IMAGE_ID=0xffffffff
+
+
+--------------
+
+*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
diff --git a/docs/components/code_coverage.rst b/docs/components/code_coverage.rst
new file mode 100644
index 000000000..3936e4f03
--- /dev/null
+++ b/docs/components/code_coverage.rst
@@ -0,0 +1,27 @@
+Code coverage
+=============
+
+Coverage processing flow
+------------------------
+
+1. Prerequisites
+
+ 1. Building all or selected test binaries with coverage enabled
+
+ 2. Running all or selected test binaries
+
+2. Collecting coverage data from ``.gcda`` and ``.gcno`` file into ``lcov`` coverage info file
+
+3. Mapping c-picker generated files' coverage to the original source lines
+
+4. Filtering coverage data for separating the coverage of the code under tests and the coverage of the test code
+
+5. Generating HTML coverage report from the filtered lcov info files
+
+
+.. cmake-module:: ../../cmake/Coverage.cmake
+
+
+--------------
+
+*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
diff --git a/docs/components/cppumock.rst b/docs/components/cppumock.rst
new file mode 100644
index 000000000..fd82d95f2
--- /dev/null
+++ b/docs/components/cppumock.rst
@@ -0,0 +1,197 @@
+CppUMock
+========
+
+CppUMock is the built-in mocking system of CppUTest. This chapter describes the basic features of the system. For details please
+refer the `official CppUMock manual`_.
+
+System functions
+----------------
+
+Checking expectations
+^^^^^^^^^^^^^^^^^^^^^
+
+After defining expected calls an invoking actual call the test should check if all the expected calls have happened. This can be
+done by calling ``mock().checkExpectations()``. The common place to put this function call is the ``TEST_TEARDOWN`` function of
+the test group.
+
+
+Resetting mocking system
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+After the last interaction with the mocking system the developer should reset the state of the system by calling
+``mock().clear()``. The common place to put this function call is the ``TEST_TEARDOWN`` function of the test group after calling
+``mock().checkExpectations()``.
+
+
+Namespaces
+^^^^^^^^^^
+
+All interactions with the mocking system start by calling ``mock()``. This function has an option ``name`` string parameter
+which can be used for limiting the scope of the mocking operation.
+
+.. code-block:: C++
+
+ mock("bl1").expectOneCall("bl1_main");
+
+
+Enable/disable
+^^^^^^^^^^^^^^
+
+The mocking system can be enabled/disabled runtime using the functions below. This causes call expected and actual call to be
+ignored. Default settings are restored by ``mock().clear()``.
+
+- ``enable()``
+- ``disable()``
+
+.. code-block:: C++
+
+ mock().disable();
+ // All CppUMock calls are ignored after this point
+ mock().enable();
+ // CppUMock calls are working again
+
+ mock().disable();
+ // All CppUMock calls are ignored after this point
+ [...]
+
+ mock().clear();
+ // Default settings are restored
+
+
+String order
+^^^^^^^^^^^^
+
+After defining multiple expected function call the mocking system always The mocking system always uses the next matching
+function when an actual call happens but by default it doesn't check if different function calls happen in the order of
+definition. This behaviour can be turned on using the ``mock().strictOrder()`` function. This option is also set to default by
+the ``mock().clear()`` function.
+
+.. code-block:: C++
+
+ mock().expectOneCall("A");
+ mock().expectOneCall("B");
+
+ mock().actualCall("B");
+ mock().actualCall("A");
+ // No error
+
+ mock().strictOrder();
+ mock().expectOneCall("A");
+ mock().expectOneCall("B");
+
+ mock().actualCall("B"); // Error generated here
+ mock().actualCall("A");
+
+
+Ignoring unspecified calls
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If there are addition actual calls happening in the test case which are unrelated to the test case (i.e. log or other messages)
+the unspecified calls can be ignored by adding ``mock().ignoreOtherCalls()`` to the test case. This function should be used
+carefully because it can hide unexpected call which are indicating errors in the code. The affect of this call ends by calling
+``mock().clear()``.
+
+
+Specifying object
+-----------------
+
+In object oriented environment member function should validate if the function call happened on the suitable object. This is
+done by adding the following function to the mock specification.
+
+- ``onObject(objectPtr)``
+
+
+Validating parameters
+---------------------
+
+Each supported parameter type has a corresponding function. These are the same
+in the expected and actual calls.
+
+- ``withBoolParameter(name, bool value)``
+- ``withIntParameter(name, int value)``
+- ``withUnsignedIntParameter(name, unsigned int value)``
+- ``withLongIntParameter(name, long int value)``
+- ``withUnsignedLongIntParameter(name, unsigned long int value)``
+- ``withDoubleParameter(name, double value)``
+- ``withStringParameter(name, const char* value)``
+- ``withPointerParameter(name, void* value)``
+- ``withFunctionPointerParameter(name, void (*value)())``
+- ``withConstPointerParameter(name, const void* value)``
+- ``withMemoryBufferParameter(name, const unsigned char* value, size_t size)``
+
+If custum types are defined and copier/comparator objects were installed the following function can handle these parameters.
+
+- ``withParameterOfType(typeName, name, value)``
+
+There's an option to copying data from the test environment into the mock function. When setting expectations the following
+function can be used to set the pointer and the address of the data. **The mocking system will not create a copy of this data**
+so the original data should be kept intact until the actual call happens.
+
+- ``withOutputParameterReturning(name, value, size)``
+- ``withOutputParameterOfTypeReturning(typeName, name, value)``
+
+In the actual call the pair of these function are shown below.
+
+- ``withOutputParameter(name, output)``
+- ``withOutputParameterOfType(typeName, name, output)``
+
+
+Ignoring parameters
+^^^^^^^^^^^^^^^^^^^
+
+There are cases when the developer doesn't want to specify all parameters. The following function can set this behaviour in the
+expected call.
+
+- ``ignoreOtherParameters()``
+
+
+Specifying return values
+------------------------
+
+Using function name overloading the return values are specified by calling ``andReturnValue`` and the parameter type will
+determine the exact function.
+
+- ``andReturnValue(bool value)``
+- ``andReturnValue(int value)``
+- ``andReturnValue(unsigned int value)``
+- ``andReturnValue(long int value)``
+- ``andReturnValue(unsigned long int value)``
+- ``andReturnValue(double value)``
+- ``andReturnValue(const char* value)``
+- ``andReturnValue(void* value)``
+- ``andReturnValue(const void* value)``
+- ``andReturnValue(void (*value)())``
+
+
+Returning value in actual calls
+-------------------------------
+
+All of these function have version with ``OrDefault(type default_value)`` suffix. These version return a default value if the
+return value was not specified in the expected call.
+
+- ``bool returnBoolValue()``
+- ``int returnIntValue()``
+- ``unsigned int returnUnsignedIntValue()``
+- ``long int returnLongIntValue()``
+- ``unsigned long int returnUnsignedLongIntValue()``
+- ``double returnDoubleValue()``
+- ``const char * returnStringValue()``
+- ``void * returnPointerValue()``
+- ``const void * returnConstPointerValue()``
+- ``void (*returnFunctionPointerValue())()``
+
+
+Debugging CppUMock errors
+-------------------------
+
+Debugging CppUMock errors can be hard unlike assertion errors because a mocking failure can happen multiple layers of function
+calls under the test case. The mocking system has a very similar feature to CppUTest's ``UT_CRASH()`` which is
+``mock().crashOnFailure()``. By enabling this feature the code will crash on mocking errors and the developer could easily catch
+it with the debugger.
+
+
+--------------
+
+*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
+
+.. _`official CppUMock manual`: https://cpputest.github.io/mocking_manual.html
diff --git a/docs/components/cpputest.rst b/docs/components/cpputest.rst
new file mode 100644
index 000000000..e1c34a9e1
--- /dev/null
+++ b/docs/components/cpputest.rst
@@ -0,0 +1,281 @@
+CppUTest
+========
+
+This document is based on CppUTest v3.8. CppUtest is a unit testing framework for testing C and C++ code. This document
+introduces the basic features of the framework. For further information check the `official manual of CppUTest`_.
+
+
+Why CppUTest?
+-------------
+
+First of all it was not our goal to develop a new unit testing framework while plenty of open source solutions are already
+available. There were no special requirements agains the unit testing framework that would rule out all existing frameworks so
+we only had to choose a suitable one for our current and possible future needs.
+
+We ended up selecting CppUTest because of its small footprint and easy portability. It also goes along with the standard xUnit
+frameworks' principles and provides a standard interface to the outside world. Some details are listed below.
+
+- C/C++ support
+- Small footprint (compared to Google Test)
+- Easy to use on embedded systems
+- Built-in mocking system (CppUMock)
+- Implements four-phase testing pattern (setup, exercise, verify, teardown)
+- Selective run of test cases
+- Standard output format (JUnit, TeamCity)
+
+
+Assertions
+----------
+
+Generally is a good practice to use more specific assertions because it can output more informative error messages in case of a
+failure. The generic form or assertions is ``assert(expected, actual)``. Each assert type has a _TEXT variant for user defined
+error messages as last parameter.
+
+- Boolean
+
+ - ``CHECK(condition)`` - Same as ``CHECK_TRUE``
+ - ``CHECK_TRUE(condition)``
+ - ``CHECK_FALSE(condition)``
+
+- C string
+
+ - ``STRCMP_EQUAL(expected, actual)``
+ - ``STRNCMP_EQUAL(expected, actual, length)``
+ - ``STRCMP_NOCASE_EQUAL(expected, actual)``
+ - ``STRCMP_CONTAINS(expected, actual)``
+ - ``STRCMP_NOCASE_CONTAINS(expected, actual)``
+
+- Integer
+
+ - ``LONGS_EQUAL(expected, actual)``
+ - ``UNSIGNED_LONGS_EQUAL(expected, actual)``
+ - ``LONGLONGS_EQUAL(expected, actual)``
+ - ``UNSIGNED_LONGLONGS_EQUAL(expected, actual)``
+ - ``BYTES_EQUAL(expected, actual)``
+ - ``SIGNED_BYTES_EQUAL(expected, actual)``
+ - ``POINTERS_EQUAL(expected, actual)``
+ - ``FUNCTIONPOINTERS_EQUAL(expected, actual)``
+
+- Enums
+
+ - ``ENUMS_EQUAL_INT(expected, actual)``
+ - ``ENUMS_EQUAL_TYPE(underlying_type, expected, actual)``
+
+- Other assertions
+
+ - ``CHECK_EQUAL(expected, actual)`` - Requires ``operator=`` and ``StringFrom(type)`` to be implemented
+ - ``CHECK_COMPARE(first, relop, second)`` - Same as ``CHECK_EQUAL`` but with any type of compare
+ - ``DOUBLES_EQUAL(expected, actual, threshold)``
+ - ``MEMCMP_EQUAL(expected, actual, size)``
+ - ``BITS_EQUAL(expected, actual, mask)``
+ - ``FAIL()`` or ``FAIL_TEST()`` - Test case fails if called
+ - ``CHECK_THROWS(expected, expression)`` - Catching C++ exceptions
+
+- Miscellaneous macros
+
+ - ``IGNORE_TEST`` - Same as ``TEST`` but it’s not called
+ - ``TEST_EXIT`` - Exists test
+ - ``UT_CRASH()`` - Crashes the test which is easy to catch with debugger
+ - ``UT_PRINT(text)`` - Generic print function
+
+
+Test runner
+-----------
+
+Test cases are collected automatically. Under the hood the ``TEST`` macros are creating global instances of classes and their
+constructor registers the test cases into the test registry. This happens before entering the ``main`` function. In the ``main``
+function only the ``RUN_ALL_TESTS`` macro needs to be placed with the command line arguments passed to it. On executing the
+binary the command line arguments will control the behaviour of the test process.
+
+.. code-block:: C++
+
+ #include "CppUTest/CommandLineTestRunner.h"
+
+ int main(int argc, char* argv[]) {
+ return RUN_ALL_TESTS(argc, argv);
+ }
+
+The default ``main`` implementation is added to all unit test suites by the
+build system.
+
+
+Command line options
+--------------------
+
+Command line options are available mainly for configuring the output format of
+the test binary and for filtering test groups or cases.
+
+- Output
+
+ - ``-v`` - Prints each test name before running them
+ - ``-c`` - Colorized output
+ - ``-o{normal, junit, teamcity}`` - Output format, junit can be processed by
+ most CIs
+ - ``-k packageName`` - Package name for junit output
+ - ``-lg`` - List test groups
+ - ``-ln`` - List test cases
+
+- Other
+
+ - ``-p`` - Runs each test case in separate processes
+ - ``-ri`` - Runs ignored test cases
+ - ``-r#`` - Repeats testing ``#`` times
+ - ``-s seed`` - Shuffles tests
+
+- Filtering test cases
+
+ - ``"TEST(groupName, testName)"`` - Running single test
+ - ``"IGNORE_TEST(groupName, testName)"`` -- Running single ignored test
+ - ``-g text`` - Runing groups containing text
+ - ``-n text`` - Runing tests containing text
+ - ``-sg text`` - Runing groups matching text
+ - ``-sn text`` - Runing tests matching text
+ - ``-xg text`` - Excluding groups containing text
+ - ``-xn text`` - Excluding tests containing text
+ - ``-xsg text`` - Excluding groups matching text
+ - ``-xsn text`` - Excluding tests matching text
+
+
+Troubleshooting
+---------------
+
+Output messages
+^^^^^^^^^^^^^^^
+
+When one of tests fails the first step is to run it separately and check its
+output message. Usually it shows the exact line of the file where the error
+happened.
+
+::
+
+ test_memcmp.cpp:17: error: Failure in TEST(memcmp, empty)
+ expected <1 0x1>
+ but was <0 0x0>
+
+The executed tests can be followed by adding ``-v`` command line option.
+
+::
+
+ ./memcmp -v
+ TEST(memcmp, different) - 0 ms
+ TEST(memcmp, same) - 0 ms
+ TEST(memcmp, empty) - 0 ms
+
+ OK (3 tests, 3 ran, 1 checks, 0 ignored, 0 filtered out, 0 ms)
+
+
+Catching failure with debugger
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If a failure happens in a helper function or in a loop where the assertion
+is called multiple times it is harder to get the exact environment of a failure.
+In this case it's a good practice to put a ``UT_CRASH()`` call into a
+conditional block which hits when the failure happens. This way the debugger can
+stop on failure because the code emits a signal.
+
+.. code-block:: C++
+
+ TEST(magic, iterate) {
+ int result;
+
+ for(int i = 0; i < 1000; i++) {
+ result = magic_function(i);
+
+ // Debug code
+ if (result) {
+ UT_CRASH();
+ }
+
+ LONGS_EQUAL(0, result);
+ }
+ }
+
+
+Using ``FAIL`` macro
+^^^^^^^^^^^^^^^^^^^^
+
+It's recommended to use ``FAIL`` macro in conditions that should never occur in
+tests. For example if a test case loads test data from an external file but the
+file could not be opened the ``FAIL`` macro should be used with an informative
+message.
+
+.. code-block:: C++
+
+ fd = open("test.bin", O_RDONLY);
+ if (fd < 0) {
+ FAIL("test.bin open failed");
+ }
+
+
+Interference between test cases
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Test cases can interfere if there's a global resource which was not restored to
+its original state after leaving a test case. This can be hard to find but at
+least the it's easy to make sure that this is root case of an error. Let's
+assume there's a global variable which is set during the test case but it
+original value is not restore at the end. CppUTest has an command line option
+for running each test case in separate process. This makes the global variable
+to have its original value at the beginning of the test cases. Basically if the
+test works by passing argument ``-p`` when running but fails without it, there's
+a good chance for having an interference between test cases.
+
+.. code-block:: C++
+
+ int x = 0;
+
+ TEST_GROUP(crosstalk) {
+ };
+
+ TEST(crosstalk, a) {
+ LONGS_EQUAL(0, x);
+ x = 1;
+ }
+
+ TEST(crosstalk, b) {
+ LONGS_EQUAL(0, x);
+ x = 1;
+ }
+
+ TEST(crosstalk, c) {
+ LONGS_EQUAL(0, x);
+ x = 1;
+ }
+
+By running the test executable with different command line arguments it produces
+a different result.
+
+.. code-block::
+
+ ./crosstalk -v
+
+ TEST(crosstalk, c) - 0 ms
+ TEST(crosstalk, b)
+ test_crosstalk.cpp:37: error:
+ Failure in TEST(crosstalk, b)
+ expected <0 0x0>
+ but was <1 0x1>
+
+ - 0 ms
+ TEST(crosstalk, a)
+ test_crosstalk.cpp:32: error: Failure in TEST(crosstalk, a)
+ expected <0 0x0>
+ but was <1 0x1>
+
+ - 0 ms
+
+ Errors (2 failures, 3 tests, 3 ran, 3 checks, 0 ignored, 0 filtered out, 0 ms)
+
+ ./crosstalk -v -p
+ TEST(crosstalk, c) - 1 ms
+ TEST(crosstalk, b) - 0 ms
+ TEST(crosstalk, a) - 0 ms
+
+ OK (3 tests, 0 ran, 0 checks, 0 ignored, 0 filtered out, 2 ms)
+
+
+--------------
+
+*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
+
+.. _`official manual of CppUTest`: https://cpputest.github.io/
diff --git a/docs/components/index.rst b/docs/components/index.rst
new file mode 100644
index 000000000..301cf9f99
--- /dev/null
+++ b/docs/components/index.rst
@@ -0,0 +1,14 @@
+Component user manuals
+======================
+
+.. toctree::
+ cpputest
+ cppumock
+ c_picker
+ build_system
+ code_coverage
+
+
+--------------
+
+*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 000000000..283be8674
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,109 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2019-2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+# Configuration file for the Sphinx documentation builder.
+#
+# See the options documentation at http://www.sphinx-doc.org/en/master/config
+
+# -- Metadata about this file ------------------------------------------------
+__copyright__ = "Copyright (c) 2019-2021 Arm Limited"
+__license__ = "SPDX-License-Identifier: BSD-3-Clause"
+
+# Configuration file for the Sphinx documentation builder.
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+# import os
+# import sys
+# sys.path.insert(0, os.path.abspath('.'))
+
+# -- Project information -----------------------------------------------------
+project = 'Firmware Test Builder'
+copyright = 'Copyright (c) 2019-2021 Arm Limited'
+author = 'Arm Limited'
+
+# The full version, including alpha/beta/rc tags
+with open('../version.txt', 'r') as f:
+ release = f.read()
+ f.close()
+version = release
+
+
+# -- General configuration ---------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = ['sphinx.ext.autosectionlabel', 'sphinxcontrib.plantuml',
+ 'sphinxcontrib.moderncmakedomain']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix(es) of source filenames.
+source_suffix = '.rst'
+
+# The master toctree document.
+master_doc = 'index'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = None
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# Load the contents of the global substitutions file into the 'rst_prolog'
+# variable. This ensures that the substitutions are all inserted into each page.
+with open('global_substitutions.txt', 'r') as subs:
+ rst_prolog = subs.read()
+rst_prolog += "\n .. |RELEASE_NUMBER| replace:: %s" % (version)
+# Minimum version of sphinx required
+needs_sphinx = '2.0'
+
+# -- Options for HTML output -------------------------------------------------
+
+# Don't show the "Built with Sphinx" footer
+html_show_sphinx = False
+
+# Don't show copyright info in the footer (we have this content in the page)
+html_show_copyright = False
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = "sphinx_rtd_theme"
+
+# The logo to display in the sidebar
+html_logo = 'resources/TrustedFirmware-Logo_standard-white.png'
+
+# Options for the "sphinx-rtd-theme" theme
+html_theme_options = {
+ 'collapse_navigation': False, # Can expand and collapse sidebar entries
+ 'prev_next_buttons_location': 'both', # Top and bottom of the page
+ 'style_external_links': True # Display an icon next to external links
+}
+
+# -- Options for autosectionlabel --------------------------------------------
+
+# Only generate automatic section labels for document titles
+autosectionlabel_maxdepth = 1
+
+# -- Options for plantuml ----------------------------------------------------
+
+plantuml_output_format = 'svg_img'
diff --git a/docs/global_substitutions.txt b/docs/global_substitutions.txt
new file mode 100644
index 000000000..095c68c25
--- /dev/null
+++ b/docs/global_substitutions.txt
@@ -0,0 +1,26 @@
+.. |FTB| replace:: :term:`FTB`
+.. |CppUMock| replace:: :term:`CppUMock`
+.. |CppUTest| replace:: :term:`CppUTest`
+.. |Test case| replace:: :term:`Test case`
+.. |Test group| replace:: :term:`Test group`
+.. |Test suite| replace:: :term:`Test suite`
+.. |TFA_MAIL_LIST| replace:: `TF-A development`_
+.. |TS_MAIL_LIST| replace:: `TS Mailing List`_
+.. |TS_REPO| replace:: `TS repository`_
+.. |LCS| replace:: :term:`LCS`
+.. |FTB_REPO| replace:: `FTB repository`_
+.. |REST| replace:: reST
+.. |SEMVER| replace:: `Semantic Versioning`_
+
+.. _`TF-A development`: https://lists.trustedfirmware.org/pipermail/tf-a/
+.. _`TS Mailing List`: https://lists.trustedfirmware.org/mailman/listinfo/trusted-services
+.. _`FTB repository`: https://review.trustedfirmware.org/admin/repos/shared/firmware-test-builder
+.. _`TS repository`: https://review.trustedfirmware.org/admin/repos/TS/trusted-services
+.. _`Semantic Versioning`: https://semver.org/spec/v2.0.0.html
+
+..
+ --------------
+
+ *Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
+
+ SPDX-License-Identifier: BSD-3-Clause
diff --git a/docs/implementing_tests.rst b/docs/implementing_tests.rst
new file mode 100644
index 000000000..fe3cb4a3e
--- /dev/null
+++ b/docs/implementing_tests.rst
@@ -0,0 +1,331 @@
+Implementing tests
+==================
+
+Concept of unit testing
+-----------------------
+
+First of all unit tests exercise the C code on a function level. The tests should call functions directly from the code under
+tests and verify if their return values are matching the expected ones and the functions are behaving according to the
+specification.
+
+Because of the function level testing the dependencies of the tested functions should be detached. This is done by mocking the
+underlying layer. This provides an additional advantage of controlling and verifying all the call to the lower layer.
+
+
+Adding new unit test suite
+--------------------------
+
+The first step is to define a new unit test suite. If a completely new module is being test the test suite definition should be
+created in a separate ``.cmake`` file which is placed in the test files' directory. Otherwise the test definition can be added
+to an existing ``.cmake`` file. These files should be included in the root ``CMakeLists.txt``.
+
+The ``UnitTest`` CMake module defines the ``unit_test_add_suite`` function so before using this function the module must be
+included in the ``.cmake`` file. The function first requires a unique test name which will be test binary's name. The test
+sources, include directories and macro definition are passed to the function in the matching arguments. CMake variables can be
+used to reference files relative to common directories:
+
+- ``CMAKE_CURRENT_LIST_DIR`` - Relative to the ``.cmake`` file
+- :cmake:variable:`UNIT_TEST_PROJECT_PATH` - Relative to the project's root directory
+
+.. code-block:: cmake
+
+ # tests/new_module/new_test_suite.cmake
+ include(UnitTest)
+
+ unit_test_add_suite(
+ NAME [unique test name]
+ SOURCES
+ [source files]
+ INCLUDE_DIRECTORIES
+ [include directories]
+ COMPILE_DEFINITIONS
+ [defines]
+ )
+
+.. code-block:: cmake
+
+ # Root CMakeLists.txt
+ include(tests/new_module/new_test_suite.cmake)
+
+Example test definition
+^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: cmake
+
+ unit_test_add_suite(
+ NAME memcmp
+ SOURCES
+ ${CMAKE_CURRENT_LIST_DIR}/test_memcmp.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/memcmp.yml
+ INCLUDE_DIRECTORIES
+ ${UNIT_TEST_PROJECT_PATH}/include
+ ${UNIT_TEST_PROJECT_PATH}/include/lib/libc/aarch64/
+ )
+
+
+Using c-picker
+--------------
+
+c-picker is a simple tool used for detaching dependencies of the code under test. It can copy elements (i.e. functions,
+variables, etc.) from the original source code into generated files. This way the developer can pick functions from compilation
+units and surround them with a mocked environment.
+
+If a ``.yml`` file listed among source files the build system invokes c-picker and the generated ``.c`` file is implicitly added
+to the source file list.
+
+Example .yml file
+^^^^^^^^^^^^^^^^^
+
+In this simple example c-picker is instructed to copy the include directives and the ``memcmp`` function from the
+``lib/libc/memcmp.c`` file. The root directory of the source files referenced by c-picker is the project's root directory.
+
+.. code-block:: yaml
+
+ elements:
+ - file: lib/libc/memcmp.c
+ type: include
+ - file: lib/libc/memcmp.c
+ type: function
+ name: memcmp
+
+
+Writing unit tests
+------------------
+
+Unit test code should be placed in ``.cpp`` files.
+
+Four-phase test pattern
+^^^^^^^^^^^^^^^^^^^^^^^
+
+All tests cases should follow the four-phase test pattern. This consists of four simple steps that altogether ensure the
+isolation between test cases. These steps follows below.
+
+- Setup
+- Exercise
+- Verify
+- Teardown
+
+After the teardown step all global states should be the same as they were at the beginning of the setup step.
+
+CppUTest
+^^^^^^^^
+
+CppUTest is an open source unit testing framework for C/C++. It is written in C++ so all the useful features of the language is
+available while testing. It automatically collects and runs the defined ``TEST_GROUPS`` and provides an interface for
+implementing the four-phase test pattern. Furthermore the framework has assertion macros for many variable types and test
+scenarios.
+
+Include
+'''''''
+
+The unit test source files should include the CppUTest header after all other headers to avoid conflicts.
+
+.. code-block:: C++
+
+ // Other headers
+ // [...]
+
+ #include "CppUTest/TestHarness.h"
+
+Test group
+''''''''''
+
+The next step is to define a test group. When multiple tests cases are written around testing the same function or couple
+related functions these tests cases should be part of the same test group. Basically test cases in a test group share have same
+setup/teardown sequence. In CppUTest the ``TEST_GROUP`` macro defines a new class which can contain member variables and
+functions. Special setup/teardown function are defined using ``TEST_SETUP`` and ``TEST_TEARDOWN`` macros. These functions are
+called before/after running each test case of the group so all the common initilization and cleanup code should go into these
+functions.
+
+.. code-block:: C++
+
+ TEST_GROUP(List) {
+ TEST_SETUP() {
+ list = list_alloc();
+ }
+
+ TEST_TEARDOWN() {
+ list_cleanup(list);
+ }
+
+ bool has_element(int value) {
+ for (int i = 0; i < list_count (list); i++) {
+ if (list_get(i) == value) { return true; }
+ }
+ return false;
+ }
+
+ List* list;
+ };
+
+
+Test case
+'''''''''
+
+Test cases are defined by the ``TEST`` macro. This macro defines a child class of the test group's class so it can access the
+member functions and variables of the test group. The test case's block itself is the body of the function of the child class.
+
+.. code-block:: C++
+
+ TEST(List, add_one) {
+ // Exercise
+ const int test_value = 5;
+ list_add(list, test_value);
+
+ // Verify using CHECK_TRUE assertion and TEST_GROUP member function
+ CHECK_TRUE(has_element(test_value));
+ }
+
+ TEST(List, add_two) {
+ // Exercise
+ const int test_value1 = 5;
+ const int test_value2 = 6;
+ list_add(list, test_value1);
+ list_add(list, test_value2);
+
+ // Verify
+ CHECK_TRUE(has_element(test_value1));
+ CHECK_TRUE(has_element(test_value2));
+ }
+
+CppUMock
+^^^^^^^^
+
+During unit testing the dependencies of the tested functions should be replaced by stubs or mocks. When using mocks the
+developer would usually like to check if the function was called with corrent parameters and would like to return controlled
+values from the function. When a mocked function is called multiple times from the tested function maybe it should check or
+return different values on each call. This is where CppUMock comes handy.
+
+All CppUMock interactions start with calling the ``mock()`` function. This returs a reference to the mocking system. At this
+point the developer either wants to define expected or actual calls. This is achiveable by calling
+``expectOneCall(functionName)`` or ``expectNCalls(amount, functionName)`` or ``actualCall(functionName)`` member functions of
+``mock()`` call's return value. Registering expected calls are done in the test case before exercising the code and actual calls
+happen from the mocked functions.
+
+After this point the following functions can be chained:
+
+- ``onObject(object)`` - In C++ it is usually the ``this`` pointer but it can be
+ useful in C too.
+- ``with[type]Parameter(name, value)`` - Specifying and checking call parameters
+- ``andReturnValue(result)`` - Specifying return value when defining expected
+ call
+- ``return[type]Value()`` - Returning value from function
+
+The mocking system has two important functions. ``mock().checkExpectation()`` checks if all the expected calls have been
+fulfilled and and the ``mock().clear()`` removes all the expected calls from CppUMock's registry. These two functions are
+usually called from the ``TEST_TEARDOWN`` function because there should not be any crosstalk between test cases through the
+mocking system.
+
+CppUMock's typical use-case is shown below by a simple example of the ``print_to_eeprom`` function.
+
+.. code-block:: C++
+
+ int eeprom_write(const char* str); /* From eeprom.h */
+
+ int printf_to_eeprom(const char* format, ...) {
+ char buffer[256];
+ int length, written_bytes = 0, eeprom_write_result;
+ va_list args;
+
+ va_start(args, format);
+ length = vsnprintf(buffer, sizeof(buffer), format, args);
+ va_end(args);
+
+ if (length < 0) {
+ return length;
+ }
+
+ while(written_bytes < length) {
+ eeprom_write_result = eeprom_write(&buffer[written_bytes]);
+ if (eeprom_write_result < 0) {
+ return eeprom_write_result;
+ }
+ written_bytes += eeprom_write_result;
+ }
+
+ return written_bytes;
+ }
+
+Having the code snipped above a real life usage of the function would look like something shown in the following sequence
+diagram.
+
+.. uml:: resources/sequence_print_to_eeprom.puml
+
+It would be really hard to test unit this whole system so all the lower layers should be separated and mock on the first
+possible level. In the following example the ``print_to_eeprom`` function is being tested and the ``eeprom_write`` function is
+mocked. In test cases where ``eeprom_write`` function is expected to be called the test case should first call the
+``expect_write`` function. This registers an expected call to CppUMocks internal database and when the call actually happens it
+matches the call parameters with the entry in the database. It also returns the previously specified value.
+
+.. code-block:: C++
+
+ TEST_GROUP(printf_to_eeprom) {
+ TEST_TEARDOWN() {
+ mock().checkExpectations();
+ mock().clear();
+ }
+
+ void expect_write(const char* str, int result) {
+ mock().expectOneCall("eeprom_write").withStringParameter("str", str).
+ andReturnValue(result);
+ }
+ };
+
+ /* Mocked function */
+ int eeprom_write(const char* str) {
+ return mock().actualCall("eeprom_write").withStringParameter("str", str).
+ returnIntValue();
+ }
+
+ TEST(printf_to_eeprom, empty) {
+ LONGS_EQUAL(0, printf_to_eeprom(""))
+ }
+
+ TEST(printf_to_eeprom, two_writes) {
+ expect_write("hello1hello2", 6);
+ expect_write("hello2", 6);
+ LONGS_EQUAL(12, printf_to_eeprom("hello%dhello%d", 1, 2))
+ }
+
+ TEST(printf_to_eeprom, error) {
+ expect_write("hello", -1);
+ LONGS_EQUAL(-1, printf_to_eeprom("hello"))
+ }
+
+This how the ``printf_to_eeprom/two_writes`` test case's sequence diagram looks like after mocking ``eeprom_write``. The test
+case became able to check the parameters of multiple calls and it could return controlled values.
+
+.. uml:: resources/sequence_print_to_eeprom_mock.puml
+
+
+Analyzing code coverage
+-----------------------
+
+The code coverage reports can be easily used for finding untested parts of the code. The two main parts of the coverage report
+are the line coverage and the branch coverage. Line coverage shows that how many times the tests ran the given line of the
+source code. It is beneficial to increase the line coverage however 100% line coverage is still not enough to consider the code
+fully tested.
+
+Let's have a look on the following example.
+
+.. code-block:: C++
+
+ void set_pointer_value(unsigned int id, unsigned int value) {
+ unsigned int *pointer;
+
+ if (id < MAX_ID) {
+ pointer = get_pointer(id);
+ }
+
+ *pointer = value;
+ }
+
+The 100% line coverage is achievable by testing the function with an ``id`` value smaller than ``MAX_ID``. However if an ``id``
+larger than or equal to ``MAX_ID`` is used as a parameter of this function it will try to write to a memory address pointed by
+an uninitialized variable. To catch untested conditions like this the branch coverage comes handy. It will show that only one
+branch of the ``if`` statement has been tested as the condition was always true in the tests.
+
+
+--------------
+
+*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 000000000..32b066a1d
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,44 @@
+Welcome to the Firmware Test Builds's documentation!
+====================================================
+
+.. toctree::
+ :maxdepth: 1
+ :hidden:
+ :numbered:
+
+ Home<self>
+ user_guide
+ implementing_tests
+ components/index
+ project/index
+
+This repository contains the unit testing framework.
+
+These tests are meant to run on host machine and used to cover platform independent code on the unit test level. In this case a
+unit is considered to be a C function or couple related functions. Each unit test suite compiles into a binary which can be run
+and debugged as any ordinary executable.
+
+The system uses CppUTest as unit testing framework. The tests are written in C++ in order to be able to use CppUTests' all
+useful features like the automatic collection of test cases and the CppUMock mocking system.
+
+Separating dependencies apart from the code under test is a crutial step in unit testing systems. In many cases this can be
+easily done by linking mocked functions to the tested code but sometimes it's difficult like when the code under test and its
+dependencies are in the same compilation unit. For separating the code under test from its dependencies a tool called c-picker
+can be used. It can pick pieces of code (functions, variables, etc.) based on descriptor files.
+
+The build system is based on CMake. The repository contains CMake modules for defining unit test suites. It also invokes
+c-picker if a descriptor file is listed among the test sources. CMake has a built in test driver system called ctest. It runs
+all the test binaries and produces an well structured output. Test filtering and parallel test run is also available.
+
+For measuring unit test coverage lcov is utilized. The coverage of c-picker generated sources is mapped to the original sources
+files. Coverage currently only works with GCC.
+
+As a next step start with reading the :ref:`User guide` and the :ref:`Implementing tests` section of this manual. For detailed
+description of the components check the :ref:`Component user manuals` section.
+
+
+--------------
+
+*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/docs/project/change-log.rst b/docs/project/change-log.rst
new file mode 100644
index 000000000..037f6dace
--- /dev/null
+++ b/docs/project/change-log.rst
@@ -0,0 +1,29 @@
+Change Log & Release Notes
+==========================
+
+This document contains a summary of the new features, changes, fixes and known issues in each release of Trusted Services.
+
+Version 1.0.0
+-------------
+
+New Features
+^^^^^^^^^^^^
+First release.
+
+Changes
+^^^^^^^
+None.
+
+Resolved Issues
+^^^^^^^^^^^^^^^
+None.
+
+Deprecations
+^^^^^^^^^^^^
+None.
+
+--------------
+
+*Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/docs/project/coding-guidelines.rst b/docs/project/coding-guidelines.rst
new file mode 100644
index 000000000..1f96c5731
--- /dev/null
+++ b/docs/project/coding-guidelines.rst
@@ -0,0 +1,69 @@
+Coding Style & Guidelines
+=========================
+
+The following sections contain |FTB| coding guidelines. They are continually evolving and should not be considered "set
+in stone". Feel free to question them and provide feedback.
+
+The |FTB| project uses multiple "domains" (textual content types, like programming languages) and each defines its own
+rules.
+
+To help configuring text editors the project comes with "`EditorConfig`_" file(s). (:download:`../../.editorconfig`).
+
+Shared rules
+------------
+
+The following rules are common for all domains, except where noted otherwise:
+
+#. Files shall be **UTF-8** encoded.
+#. Use **Unix** style line endings (``LF`` character)
+#. The primary language of the project is English. All comments and documentation must be in this language.
+#. Trailing whitespace is not welcome, please trim these.
+
+C/C++ Domain
+------------
+
+C source code rules are base on the *Linux Coding Style* (See: |LCS|). The following deviations apply:
+
+5. C code in |FTB| follows *ISO/IEC 9899:1999* standard.
+#. C++ code in |FTB| follows *ISO/IEC 14882:2011* standard (C++ 11)
+#. Line length shall not exceed 100 characters.
+#. Use `snake_case`_ for function, variable and file names.
+#. Each file shall be "self contained" and include header files with external dependencies. No file shall depend on
+ headers included by other files.
+#. Include ordering: please include project specific headers first and then system includes. Please order the files
+ alphabetically in the above two groups.
+#. All variables must be initialized.
+
+CMake domain
+------------
+
+11. CMake file names use `CamelCase`_ style.
+#. Indent with tabs and otherwise use spaces. Use 4 spaces for tab size.
+#. Use LF as line end in CMake files.
+#. Remove trailing whitespace.
+#. Maximum line length is 128 characters.
+#. When complicated functionality is needed prefer CMake scripting over other languages.
+#. Prefix local variables with `_`.
+#. Use functions to prevent global name-space pollution.
+#. Use `snake_case`_ for function and variable names.
+#. Use the ``include_guard()`` CMake function when creating new modules, to prevent multiple inclusion.
+#. Use self contained modules, i.e. include direct dependencies of the module.
+#. Use the Sphinx CMake domain for in-line documentation of CMake scripts. For details please refer to the
+ `CMake Documentation`_.
+
+Restructured Text Domain
+------------------------
+
+Please refer to :ref:`Writing documentation`.
+
+--------------
+
+.. _`CamelCase`: https://hu.wikipedia.org/wiki/CamelCase
+.. _`snake_case`: https://en.wikipedia.org/wiki/Snake_case
+.. _`CMake Documentation`: https://github.com/Kitware/CMake/blob/master/Help/dev/documentation.rst
+.. _`EditorConfig`: https://editorconfig.org/
+.. _`Uncrustify`: https://github.com/uncrustify/uncrustify
+
+*Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/docs/project/contributing.rst b/docs/project/contributing.rst
new file mode 100644
index 000000000..7eefb2e85
--- /dev/null
+++ b/docs/project/contributing.rst
@@ -0,0 +1,83 @@
+Contributing
+============
+
+
+Getting Started
+---------------
+
+- Make sure you have a GitHub account and you are logged on `developer.trustedfirmware.org`_.
+- Send an email to the |TS_MAIL_LIST| about your work. This gives everyone visibility of whether others are working on something
+ similar.
+- Clone the |FTB_REPO| on your own machine.
+- Create a local topic branch based on ``main`` branch of the |FTB_REPO|.
+
+Making Changes
+--------------
+
+- Make commits of logical units. See these general `Git guidelines`_ for contributing to a project.
+- Follow the :ref:`Coding Style & Guidelines`.
+- Keep the commits on topic. If you need to fix another bug or make another enhancement, please create a separate change.
+- Avoid long commit series. If you do have a long series, consider whether some commits should be squashed together or
+ addressed in a separate topic.
+- Make sure your commit messages are in the proper format. Please keel the 50/72 rule (for details see `Tim Popes blog entry`_.)
+- Where appropriate, please update the documentation.
+
+ - Consider whether the this document or other in-source documentation needs updating.
+
+ - Ensure that each changed file has the correct copyright and license information. Files that entirely consist of
+ contributions to this project should have a copyright notice and BSD-3-Clause SPDX license identifier of the form as shown
+ in :ref:`license`. Files that contain changes to imported Third Party IP files should retain their original copyright and
+ license notices. For significant contributions you may add your own copyright notice in following format::
+
+ Portions copyright (c) [XXXX-]YYYY, <OWNER>. All rights reserved.
+
+ where XXXX is the year of first contribution (if different to YYYY) and YYYY is the year of most recent contribution.
+ *<OWNER>* is your name or your company name.
+ - If you are submitting new files that you intend to be the technical sub-maintainer for (for example, a new platform port),
+ then also update the :ref:`maintainers` file.
+ - For topics with multiple commits, you should make all documentation changes (and nothing else) in the last commit of the
+ series. Otherwise, include the documentation changes within the single commit.
+
+- Please test your changes.
+
+Submitting Changes
+------------------
+
+- Ensure that each commit in the series has at least one ``Signed-off-by:``line, using your real name and email address. The
+ names in the ``Signed-off-by:`` and ``Author:`` lines must match. If anyone else contributes to the commit, they must also add
+ their own ``Signed-off-by:`` line. By adding this line the contributor certifies the contribution is made under the terms of
+ the :download:`Developer Certificate of Origin <../../dco.txt>`.
+
+ More details may be found in the `Gerrit Signed-off-by Lines guidelines`_.
+
+- Ensure that each commit also has a unique ``Change-Id:`` line. If you have cloned the repository with the
+ "`Clone with commit-msg hook`" clone method, this should already be the case.
+
+ More details may be found in the `Gerrit Change-Ids documentation`_.
+
+- Submit your changes for review at https://review.trustedfirmware.org targeting the ``main`` branch.
+
+- The changes will then undergo further review and testing by the :ref:`maintainers`. Any review comments will be made
+ directly on your patch. This may require you to do some rework.
+
+ Refer to the `Gerrit Uploading Changes documentation`_ for more details.
+
+- When the changes are accepted, the :ref:`maintainers` will integrate them.
+
+ - Typically, the :ref:`maintainers` will merge the changes into the ``main`` branch.
+ - If the changes are not based on a sufficiently-recent commit, or if they cannot be automatically rebased, then the
+ :ref:`maintainers` may rebase it on the ``main`` branch or ask you to do so.
+
+--------------
+
+.. _developer.trustedfirmware.org: https://developer.trustedfirmware.org
+.. _Git guidelines: http://git-scm.com/book/ch5-2.html
+.. _Gerrit Uploading Changes documentation: https://review.trustedfirmware.org/Documentation/user-upload.html
+.. _Gerrit Signed-off-by Lines guidelines: https://review.trustedfirmware.org/Documentation/user-signedoffby.html
+.. _Gerrit Change-Ids documentation: https://review.trustedfirmware.org/Documentation/user-changeid.html
+.. _`Tim Popes blog entry`: https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
+
+
+*Copyright (c) 2019-2021, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/docs/project/glossary.rst b/docs/project/glossary.rst
new file mode 100644
index 000000000..7f9c4020e
--- /dev/null
+++ b/docs/project/glossary.rst
@@ -0,0 +1,38 @@
+Glossary
+========
+
+This glossary provides definitions for terms and abbreviations used in the unit testing framework's documentation.
+
+You can find additional definitions in the `Arm Glossary`_.
+
+.. glossary::
+ :sorted:
+
+ CppUMock
+ Built-in mocking system of CppUTest.
+
+ CppUTest
+ Open source C/C++ unit testing framework.
+
+ FTB
+ Firmware Test Builder
+
+ LCS
+ `Linux Coding Style`_
+
+ Test case
+ Single use case tested. Defined by ``TEST`` macro of CppUTest.
+
+ Test group
+ Multiple test cases with common setup/teardown steps and helper functions and variables. Defined by ``TEST_GROUP`` macro
+ of CppUTest.
+
+ Test suite
+ Test binary which contains one or more test groups. Defined by :cmake:command:`unit_test_add_suite` CMake function.
+
+--------------
+
+*Copyright (c) 2020-2021, Arm Limited. All rights reserved.*
+
+.. _`Arm Glossary`: https://developer.arm.com/support/arm-glossary
+.. _`Linux Coding Style`: https://www.kernel.org/doc/html/v4.10/process/coding-style.html
diff --git a/docs/project/index.rst b/docs/project/index.rst
new file mode 100644
index 000000000..9934ff69f
--- /dev/null
+++ b/docs/project/index.rst
@@ -0,0 +1,22 @@
+About the project
+=================
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Contents:
+
+ change-log
+ coding-guidelines
+ contributing
+ glossary
+ license
+ maintainers
+ versioning_policy
+ writing-documentation
+
+
+--------------
+
+*Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause \ No newline at end of file
diff --git a/docs/project/license.rst b/docs/project/license.rst
new file mode 100644
index 000000000..ac98f00eb
--- /dev/null
+++ b/docs/project/license.rst
@@ -0,0 +1,37 @@
+License
+=======
+
+Copyright (c) 2019-2021, Arm Limited and Contributors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+- Neither the name of Arm nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior
+ written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+--------------
+
+*Note*:
+Individual files contain the following tag instead of the full license text.
+
+ SPDX-License-Identifier: BSD-3-Clause
+
+This enables machine processing of license information based on the SPDX
+License Identifiers that are here available: http://spdx.org/licenses/
diff --git a/docs/project/maintainers.rst b/docs/project/maintainers.rst
new file mode 100644
index 000000000..9cd0f4ada
--- /dev/null
+++ b/docs/project/maintainers.rst
@@ -0,0 +1,41 @@
+Maintainers
+===========
+
+|FTB| is a trustedfirmware.org maintained component used by multiple trustedfirmware.org projects. All contributions are
+ultimately merged by the maintainers listed below. Technical ownership of some parts of the code-base is delegated to the code
+owners listed below. An acknowledgment from these code maintainers may be required before the maintainers merge a contribution.
+
+More details may be found in the `Project Maintenance Process`_ document.
+
+This file follows the format of the Linux Maintainers file. For details on the meaning of tags below please refer to the
+`Linux Maintainers file`_.
+
+Main maintainers
+----------------
+:M: György Szing <gyorgy.szing@arm.com>
+:G: `gyuri-szing`_
+:L: |TS_MAIL_LIST|
+:M: Imre Kis <imre.kis@arm.com>
+:G: `imre-kis-arm`_
+:M: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
+:G: `laurenw-arm`_
+:L: |TFA_MAIL_LIST|
+
+Code owners
+--------------------
+
+Cyrrently there are no code owners.
+
+--------------
+
+.. _danh-arm: https://github.com/danh-arm
+.. _gyuri-szing: https://github.com/gyuri-szing
+.. _imre-kis-arm: https://github.com/imre-kis-arm
+.. _laurenw-arm: https://github.com/laurenw-arm
+
+.. _`Linux Maintainers file`: https://github.com/torvalds/linux/blob/master/MAINTAINERS#L80
+.. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/
+
+*Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/docs/project/versioning_policy.rst b/docs/project/versioning_policy.rst
new file mode 100644
index 000000000..90d54f097
--- /dev/null
+++ b/docs/project/versioning_policy.rst
@@ -0,0 +1,42 @@
+Versioning policy
+==================
+
+This document captures information about the version identifier used by the project. It tells the meaning of each part, where
+the version information is captured and how it is managed.
+
+Summary
+-------
+
+The version identifier identifies the feature set supported by a specific release, and captures compatibility information to
+other releases.
+
+This project uses "Semantic Versioning", for details please refer to |SEMVER|.
+
+In general the version number is constructed from three numbers. The `MAJOR` number is changed when incompatible API changes are
+introduced, the `MINOR` version when you functionality is added in a backward compatible manner, and the `PATCH` version when
+backwards compatible bug fixes are added.
+
+Each release will get a unique release id assigned. When a release is made, the version number will get incremented in
+accordance with the compatibility rules mentioned above.
+
+This project is only using the core version and will not use pre-release or build specific metadata extension.
+
+Storage and format
+------------------
+
+The version number of each release will be stored at two locations:
+ #. In a tag of the version control system in the form of "vX.Y.Z" where X Y and Z are the major, minor and patch version
+ numbers.
+ #. In a file called version.txt. This file uses ASCII encoding and will contain the version number as "X.Y.Z" where X Y and
+ Z are the major, minor and patch version numbers.
+
+.. note:: The version id is independent from version identifiers of the
+ versioning system used to store the |FTB| (i.e. git).
+
+--------------
+
+.. _`Semantic Versioning`: https://semver.org/spec/v2.0.0.html
+
+*Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/docs/project/writing-documentation.rst b/docs/project/writing-documentation.rst
new file mode 100644
index 000000000..ca55b3219
--- /dev/null
+++ b/docs/project/writing-documentation.rst
@@ -0,0 +1,52 @@
+Writing documentation
+=====================
+
+|FTB| is documented using `Sphinx`_, which in turn uses Docutils and `Restructured Text`_ (|REST| hereafter).
+
+The source files for the documents are in the *docs* directory of the |FTB_REPO|.
+
+The preferred output format is *HTML*, and other formats may or may not work.
+
+
+Section Headings
+----------------
+
+In order to avoid problems if documents include each other, it is important to follow a consistent section heading
+style. Please use at most five heading levels. Please use the following style::
+
+ First-Level Title
+ =================
+
+ Second-Level Title
+ ------------------
+
+ Third-Level Title
+ '''''''''''''''''
+
+ Forth-level Title
+ """""""""""""""""
+
+ Fifth-level Title
+ ~~~~~~~~~~~~~~~~~
+
+
+Inline documentation
+--------------------
+
+To get all information integrated into a single document the project uses Sphinx extensions to allow capturing inline
+documentation into this manual.
+
+
+CMake
+'''''
+
+Apologies, this section is not ready yet. Please check existing cmake and |REST| files to see how documentation can be added.
+
+--------------
+
+.. _`Restructured Text`: https://docutils.sourceforge.io/rst.html
+.. _`Sphinx`: https://www.sphinx-doc.org
+
+*Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/docs/resources/TrustedFirmware-Logo_standard-white.png b/docs/resources/TrustedFirmware-Logo_standard-white.png
new file mode 100644
index 000000000..e7bff7128
--- /dev/null
+++ b/docs/resources/TrustedFirmware-Logo_standard-white.png
Binary files differ
diff --git a/docs/resources/sequence_print_to_eeprom.puml b/docs/resources/sequence_print_to_eeprom.puml
new file mode 100644
index 000000000..8ba719063
--- /dev/null
+++ b/docs/resources/sequence_print_to_eeprom.puml
@@ -0,0 +1,46 @@
+'-------------------------------------------------------------------------------
+' Copyright (c) 2019-2021, Arm Limited and Contributors. All rights reserved.
+'
+' SPDX-License-Identifier: BSD-3-Clause
+'
+'-------------------------------------------------------------------------------
+
+@startuml
+participant Application as APP
+
+activate APP
+APP -> Print: print_to_eeprom(fmt, ...)
+activate Print
+
+ Print -> EEPROM: eeprom_write(buffer)
+ activate EEPROM
+
+ EEPROM -> I2C: i2c_write(address, buffer)
+ activate I2C
+
+ I2C -> Hardware: I2C transaction
+ activate Hardware
+ Hardware --> I2C: ack/nack
+ deactivate Hardware
+
+ I2C --> EEPROM: result
+ deactivate I2C
+
+ EEPROM -> I2C: i2c_write(address, buffer+ result)
+ activate I2C
+
+ I2C -> Hardware: I2C transaction
+ activate Hardware
+ Hardware --> I2C: ack/nack
+ deactivate Hardware
+
+ I2C --> EEPROM: result
+ deactivate I2C
+
+ EEPROM --> Print: result
+ deactivate EEPROM
+
+Print -> APP: result
+deactivate Print
+
+@enduml \ No newline at end of file
diff --git a/docs/resources/sequence_print_to_eeprom_mock.puml b/docs/resources/sequence_print_to_eeprom_mock.puml
new file mode 100644
index 000000000..ce394d465
--- /dev/null
+++ b/docs/resources/sequence_print_to_eeprom_mock.puml
@@ -0,0 +1,48 @@
+'-------------------------------------------------------------------------------
+' Copyright (c) 2019-2021, Arm Limited and Contributors. All rights reserved.
+'
+' SPDX-License-Identifier: BSD-3-Clause
+'
+'-------------------------------------------------------------------------------
+
+@startuml
+participant "Test case" as TC
+participant "Code under test" as CUT
+
+group Setting expectations
+ activate TC
+ TC -> Mock: expect_write("hello1hello2", 6)
+ activate Mock
+ deactivate Mock
+ TC -> Mock: expect_write("hello2", 6)
+ activate Mock
+ deactivate Mock
+end
+
+TC -> CUT: print_to_eeprom("hello%dhello%d", 1, 2)
+activate CUT
+
+ group Using mocked interface
+ CUT -> Mock: eeprom_write("hello1hello2")
+ activate Mock
+ Mock --> CUT: 6
+ deactivate Mock
+
+ CUT -> Mock: eeprom_write("hello2")
+ activate Mock
+ Mock --> CUT: 6
+ deactivate Mock
+ end
+
+CUT --> TC: 6 + 6 = 12
+deactivate CUT
+
+TC -> Mock: mock().checkExpectation()
+activate Mock
+deactivate Mock
+
+TC -> Mock: mock().clear()
+activate Mock
+deactivate Mock
+
+@enduml \ No newline at end of file
diff --git a/docs/user_guide.rst b/docs/user_guide.rst
new file mode 100644
index 000000000..4c214f43c
--- /dev/null
+++ b/docs/user_guide.rst
@@ -0,0 +1,201 @@
+User guide
+==========
+
+This page describes how to get started with compiling and running unit tests on the host machine.
+
+Host machine requirements
+-------------------------
+
+The system has been successfully tested on the following platforms:
+
+- Ubuntu 19.04
+- Ubuntu 18.04
+- Arch Linux
+- MSYS2 MinGW64
+
+Tools
+-----
+
+The following applications are expected to be installed in the build machine:
+
+- CMake >=3.11
+
+- Python >=3.4
+
+- c-picker
+
+ - pyyaml
+
+ - clang (pip package if not included in libclang)
+
+ - libclang
+
+- git
+
+- Toolchain
+
+- Native build system
+
+Ubuntu 19.04
+^^^^^^^^^^^^
+
+On Ubuntu 19.04 use the following commands to install the required tools:
+
+::
+
+ sudo apt-get install cmake git python3 python3-pip libclang-dev build-essential
+ sudo pip3 install git+[TBD]
+
+Ubuntu 18.04
+^^^^^^^^^^^^
+
+The official Ubuntu 18.04 package repository only contains CMake 3.10 which not satisfies the requirements for building unit
+tests. Fortunately there's an official CMake APT repository provided by Kitware: https://apt.kitware.com/ By adding this server
+to the repository list an up-to-date version of CMake can be installed on Ubuntu 18.04.
+
+::
+
+ wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc \
+ 2>/dev/null | sudo apt-key add -
+ sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ bionic main'
+
+ sudo apt-get install cmake git python3 python3-pip libclang-dev build-essential
+ sudo pip3 install git+[TBD]
+
+Arch Linux
+^^^^^^^^^^
+
+On Arch Linux use the following commands to install the required tools:
+
+::
+
+ sudo pacman -Sy cmake git python python-pip python-yaml make gcc clang
+ sudo pip install git+[TBD]
+
+MSYS2 MinGW64
+^^^^^^^^^^^^^
+
+::
+
+ pacman -Sy mingw-w64-x86_64-cmake git mingw-w64-x86_64-python3 \
+ mingw-w64-x86_64-python3-pip make mingw-w64-x86_64-gcc mingw-w64-x86_64-clang
+ pip install git+[TBD]]
+
+
+Integrating firmware test builder into a project
+------------------------------------------------
+
+The firmware test builder can be simply integrated into a CMake based project by adding the lines below to its CMakeLists.txt.
+This example shows how to fetch the firmware test builder files on demand using CMake's FetchContent module.
+
+::
+
+ FetchContent_Declare(
+ firmware_test_builder
+ GIT_REPOSITORY ${FIRMWARE_TEST_BUILDER_URL}
+ GIT_TAG ${FIRMWARE_TEST_BUILDER_REFSPEC}
+ GIT_SHALLOW TRUE
+ )
+
+ FetchContent_GetProperties(firmware_test_builder)
+ if(NOT firmware_test_builder_POPULATED)
+ message(STATUS "Fetching Firmware Test Builder")
+ FetchContent_Populate(firmware_test_builder)
+ endif()
+
+ # Appending Firmware Test Builder's cmake directory to CMake module path
+ list(APPEND CMAKE_MODULE_PATH ${firmware_test_builder_SOURCE_DIR}/cmake)
+
+For more details on adding tests see :ref:`Implementing tests` chapter.
+
+
+Building unit tests
+-------------------
+
+Building unit tests start with running CMake which will check all the prerequisites and generate the native build system's input
+files. This example uses Unix Makefiles. Unit tests exercise the code directly by compiling it into the same binary as the test
+code.
+
+::
+
+ cd project
+ mkdir build
+ cd build
+ cmake -G"Unix Makefiles" ..
+
+After running the previous steps the makefiles are generated into the build directory so make can build unit tests. During unit
+test development if only the source files have changed it's not necessary to re-run cmake it's only needed to run make as shown
+below.
+
+::
+
+ make -j
+
+For building single unit test suites the test's name can be used as a makefile target. Let's assume there's a test suite called
+best_unit_tests.
+
+::
+
+ make best_unit_tests
+
+
+Running unit tests
+------------------
+
+CMake provides a built-in tool called ctest for running all the tests using a single command. It is also able to filter tests or
+run them in parallel for speeding up the tests process. Run all the tests using the following command:
+
+::
+
+ ctest
+
+Each unit test suite has its own executable. The easiest way of running single test suite is running it as a simple executable.
+
+::
+
+ ./best_unit_tests
+
+
+Debugging unit tests
+--------------------
+
+As it was mentioned in the previous section test suites are basically separate executables so they can be debugged as any other
+native applications on the host machine. In a Linux environment gdb or IDE's built-in debugger can be utilized for debugging.
+
+::
+
+ gdb ./best_unit_tests
+
+
+Measuring code coverage
+-----------------------
+
+Inspecting code coverage is a useful method for detecting parts of the code which is not exercised by tests. The build system
+includes an option for generating code coverage report of the unit tests. The coverage is processed by ``lcov`` which needs to
+be installed for this feature. Also the coverage measurement in only available when GCC is used as a compiler.
+
+The methods for enabling coverage measurement is project dependent.
+
+Before collecting coverage info and generating reports the tests must be run as the coverage is a runtime measurement. See
+section `Running unit tests`_ for more information about running unit tests.
+
+In case of enabled coverage report the system adds two new build targets called ``coverage`` and ``coverage_report``. They can
+be used simply by running the following commands if ``make`` is used as a build system.
+
+::
+
+ make coverage
+ make coverage_report
+
+The ``coverage`` target generates lcov info files for further processing. If there are coverage files available from different
+sources (i.e. coverages of other tests) they can be merged with the unit test coverage file and evaluated together.
+
+The ``coverage_report`` target generates a HTML report from the coverage info files. The coverage reports can be found in the
+build directory. The report shows the directory structure of the code and each file can be inspected individually. Line,
+function and branch coverage is included.
+
+
+--------------
+
+*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/license.rst b/license.rst
new file mode 100644
index 000000000..3c59fe94e
--- /dev/null
+++ b/license.rst
@@ -0,0 +1,7 @@
+See `license.rst <./docs/project/license.rst>`_
+
+--------------
+
+*Copyright (c) 2019-2021, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/readme.rst b/readme.rst
new file mode 100644
index 000000000..eaffb56ca
--- /dev/null
+++ b/readme.rst
@@ -0,0 +1,24 @@
+Firmware Test Builder
+=====================
+
+This repository holds the unit testing framework for testing C code.
+
+The full documentation of this project is `Sphinx`_ based, lives in the *docs*
+sub-directory and is captured in reStructuredText_ format.
+
+For licensing information please refer to `license.rst`_
+
+Contributed content is accepted under the `Developer Certificate of Origin (DCO)`_
+and commit messages shall follow specific formatting rules (for details
+please refer to the *Contributing* sections of the full documentation).
+
+.. _reStructuredText: http://docutils.sourceforge.net/rst.html
+.. _Sphinx: http://www.sphinx-doc.org/en/master/
+.. _`license.rst`: ./license.rst
+.. _`Developer Certificate of Origin (DCO)`: ./dco.txt
+
+--------------
+
+*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/version.txt b/version.txt
new file mode 100644
index 000000000..afaf360d3
--- /dev/null
+++ b/version.txt
@@ -0,0 +1 @@
+1.0.0 \ No newline at end of file