Add test application

Change-Id: I066cea19c6bfcc0019aa28d150e12b25c8da9c1b
Signed-off-by: Julian Hall <julian.hall@arm.com>
diff --git a/components/app/test-runner/component.cmake b/components/app/test-runner/component.cmake
new file mode 100644
index 0000000..8bb9a73
--- /dev/null
+++ b/components/app/test-runner/component.cmake
@@ -0,0 +1,14 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+	"${CMAKE_CURRENT_LIST_DIR}/main.cpp"
+	)
+
diff --git a/components/app/test-runner/main.cpp b/components/app/test-runner/main.cpp
new file mode 100644
index 0000000..ed48583
--- /dev/null
+++ b/components/app/test-runner/main.cpp
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <cstdio>
+#include <CppUTest/CommandLineTestRunner.h>
+
+/* These tests are intended to be compiled natively and run on a PC */
+int main(int argc, char *argv[]) {
+
+	return CommandLineTestRunner::RunAllTests(argc, argv);
+}
\ No newline at end of file
diff --git a/external/CppUTest/CppUTest.cmake b/external/CppUTest/CppUTest.cmake
new file mode 100644
index 0000000..c18f3e3
--- /dev/null
+++ b/external/CppUTest/CppUTest.cmake
@@ -0,0 +1,99 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+set(CPPUTEST_URL "https://github.com/cpputest/cpputest.git" CACHE STRING "CppUTest repository URL")
+set(CPPUTEST_REFSPEC "v3.8" CACHE STRING "CppUTest git refspec")
+set(CPPUTEST_INSTALL_PATH ${CMAKE_CURRENT_BINARY_DIR}/CppUTest_install CACHE PATH "CppUTest installation directory")
+
+include(FetchContent)
+
+# Checking git
+find_program(GIT_COMMAND "git")
+if (NOT GIT_COMMAND)
+	message(FATAL_ERROR "Please install git")
+endif()
+
+# Fetching CppUTest
+FetchContent_Declare(
+	cpputest
+	GIT_REPOSITORY ${CPPUTEST_URL}
+	GIT_TAG ${CPPUTEST_REFSPEC}
+	GIT_SHALLOW TRUE
+	PATCH_COMMAND git stash
+		COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/cpputest-cmake-fix.patch
+)
+
+# 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 configuration time. This makes us able to use CppUTest as a CMake package.
+# Memory leak detection is turned off to avoid conflict with memcheck.
+if(NOT CMAKE_CROSSCOMPILING)
+	execute_process(COMMAND
+		${CMAKE_COMMAND}
+			-DMEMORY_LEAK_DETECTION=OFF
+			-DLONGLONG=ON
+			-DC++11=ON
+			-DCMAKE_INSTALL_PREFIX=${CPPUTEST_INSTALL_PATH}
+			-DCMAKE_TOOLCHAIN_FILE=${TS_EXTERNAL_LIB_TOOLCHAIN_FILE}
+			-G${CMAKE_GENERATOR}
+			${cpputest_SOURCE_DIR}
+		WORKING_DIRECTORY
+			${cpputest_BINARY_DIR}
+			RESULT_VARIABLE
+				_exec_error
+	)
+else()
+	execute_process(COMMAND
+	${CMAKE_COMMAND}
+		-DMEMORY_LEAK_DETECTION=OFF
+		-DLONGLONG=ON
+		-DC++11=ON
+		-DCMAKE_INSTALL_PREFIX=${CPPUTEST_INSTALL_PATH}
+		-DCMAKE_TOOLCHAIN_FILE=${TS_EXTERNAL_LIB_TOOLCHAIN_FILE}
+		-DTESTS=OFF
+		-DEXTENSIONS=OFF
+		-DHAVE_FORK=OFF
+		-DCPP_PLATFORM=armcc
+		-DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY
+		-G${CMAKE_GENERATOR}
+		${cpputest_SOURCE_DIR}
+	WORKING_DIRECTORY
+		${cpputest_BINARY_DIR}
+	RESULT_VARIABLE
+		_exec_error
+	)
+endif()
+if (NOT _exec_error EQUAL 0)
+	message(FATAL_ERROR "Configuriong CppUTest build failed.")
+endif()
+execute_process(COMMAND
+	${CMAKE_COMMAND}
+		--build ${cpputest_BINARY_DIR}
+		-- install -j8
+	RESULT_VARIABLE
+		_exec_error
+	)
+if (NOT _exec_error EQUAL 0)
+	message(FATAL_ERROR "Building CppUTest failed.")
+endif()
+
+# Finding CppUTest package. CMake will check [package name]_DIR variable.
+set(CppUTest_DIR ${CPPUTEST_INSTALL_PATH}/lib/CppUTest/cmake CACHE PATH "CppUTest package location" FORCE)
+find_package(CppUTest CONFIG REQUIRED NO_DEFAULT_PATH PATHS ${CppUTest_DIR})
+# CppUTest package files do not set include path properties on the targets.
+# Fix this here.
+foreach(_cpputest_target IN LISTS CppUTest_LIBRARIES)
+	if (TARGET  ${_cpputest_target})
+		target_include_directories(${_cpputest_target} INTERFACE ${CppUTest_INCLUDE_DIRS})
+		target_compile_features(${_cpputest_target} INTERFACE cxx_std_11)
+	endif()
+endforeach()
diff --git a/external/CppUTest/cpputest-cmake-fix.patch b/external/CppUTest/cpputest-cmake-fix.patch
new file mode 100644
index 0000000..fb589b7
--- /dev/null
+++ b/external/CppUTest/cpputest-cmake-fix.patch
@@ -0,0 +1,59 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index b1900bb..d9ca865 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -116,8 +116,13 @@ if(PkgHelpers_AVAILABLE)
+     ${CMAKE_CURRENT_BINARY_DIR}/CppUTestConfig.cmake
+     INSTALL_DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
+     PATH_VARS INCLUDE_DIR CMAKE_CURRENT_BINARY_DIR)
+-  export(TARGETS CppUTest CppUTestExt
++  if(TARGET CppUTestExt)
++    export(TARGETS CppUTest
+     FILE "${CMAKE_CURRENT_BINARY_DIR}/CppUTestTargets.cmake")
++  else()
++    export(TARGETS CppUTest
++    FILE "${CMAKE_CURRENT_BINARY_DIR}/CppUTestTargets.cmake")
++  endif()
+   write_basic_package_version_file(
+     ${CMAKE_CURRENT_BINARY_DIR}/CppUTestConfigVersion.cmake
+     VERSION ${CppUTest_version_major}.${CppUTest_version_minor}
+diff --git a/cmake/Modules/CppUTestConfigurationOptions.cmake b/cmake/Modules/CppUTestConfigurationOptions.cmake
+index 634482c..a00b5eb 100644
+--- a/cmake/Modules/CppUTestConfigurationOptions.cmake
++++ b/cmake/Modules/CppUTestConfigurationOptions.cmake
+@@ -1,19 +1,19 @@
+ if (MSVC)
+-    set(CPP_PLATFORM VisualCpp)
++    set(CPP_PLATFORM VisualCpp CACHE STRING "CppUTest platform.")
+     include_directories(${CppUTestRootDirectory}/include/Platforms/${CPP_PLATFORM})
+     option(STDC_WANT_SECURE_LIB "Use MSVC safe functions" ON)
+     if(STDC_WANT_SECURE_LIB)
+       ADD_DEFINITIONS(-DSTDC_WANT_SECURE_LIB)
+     endif(STDC_WANT_SECURE_LIB)
+ elseif (STD_C)
+-    set(CPP_PLATFORM Gcc)
++    set(CPP_PLATFORM Gcc CACHE STRING "CppUTest platform.")
+ else (MSVC)
+     set(STD_CPP False)
+     set(MEMORY_LEAK_DETECTION False)
+     set(CPPUTEST_CXX_FLAGS "${CPPUTEST_CXX_FLAGS} -nostdinc")
+     set(CPPUTEST_LD_FLAGS "${CPPUTEST_LD_FLAGS} -nostdinc")
+     set(CPPUTEST_STD_C_LIB_DISABLED 1)
+-    set(CPP_PLATFORM GccNoStdC)
++    set(CPP_PLATFORM GccNoStdC CACHE STRING "CppUTest platform.")
+ endif (MSVC)
+ 
+ include("${CppUTestRootDirectory}/cmake/Modules/CppUTestWarningFlags.cmake")
+diff --git a/src/CppUTest/CMakeLists.txt b/src/CppUTest/CMakeLists.txt
+index 736777f..d9a592f 100644
+--- a/src/CppUTest/CMakeLists.txt
++++ b/src/CppUTest/CMakeLists.txt
+@@ -50,7 +50,7 @@ set(CppUTest_headers
+ 
+ add_library(CppUTest STATIC ${CppUTest_src} ${CppUTest_headers})
+ if (WIN32)
+-    target_link_libraries(CppUTest winmm.lib)
++    target_link_libraries(CppUTest winmm)
+ endif (WIN32)
+ install(FILES ${CppUTest_headers} DESTINATION include/CppUTest)
+ install(TARGETS CppUTest