Add valgrind builders to auto_build.py 45/26845/2
authorMats Wichmann <mats@linux.com>
Wed, 29 Aug 2018 22:46:59 +0000 (16:46 -0600)
committerMats Wichmann <mats@linux.com>
Tue, 4 Sep 2018 19:26:15 +0000 (19:26 +0000)
For possible future CI use, and for developer use, add
build options which run a memory checker while executing
unit tests (this was recently disabled as the default).

Some script refactoring as well, and updating of the
help message.

Change-Id: I8ddb0729854af1fd9e98d5e22034d94e5d1c5f08
Signed-off-by: Mats Wichmann <mats@linux.com>
auto_build.py

index 95ce6b5..53a9fad 100755 (executable)
@@ -6,35 +6,61 @@ import platform
 import subprocess
 import multiprocessing
 
+
 # help message
 def helpmsg(script):
     helpstr = '''
 Usage:
-    build:
-        python %s <targetbuild>
-        Allowed values for <target_build>: all, linux_unsecured, linux_secured, linux_full, linux_unsecured_with_rd, linux_secured_with_rd,
-        android, android_unsecured, android_secured, tizen, tizen_unsecured, tizen_secured, simulator, darwin, windows, msys
-        Note: \"linux\" will build \"linux_unsecured\", \"linux_secured\", \"linux_secured_with_rd\", \"linux_unsecured_with_mq\", \"linux_secured_with_tcp\" & \"linux_unsecured_with_tcp\" & \"linux_unsecured_with_rd\".
-        Any selection will build both debug and release versions of all available targets in the scope you've selected.
-        To choose any specific command, please use the SCons commandline directly. Please refer to [IOTIVITY_REPO]/Readme.scons.txt.
-    clean:
-        python %s -c
+
+To build:
+    python %s <targetbuild>
+To clean:
+    python %s -c
+
+EXEC_MODE=True/False (default false) to suppress running the commands.
+VERBOSE=0/1 (default 1) to tell scons to print more information.
+
+Allowed values for <target_build>: 
+    all linux linux_unsecured linux_secured linux_full linux_unsecured_with_tcp
+    linux_unsecured_with_rd linux_secured_with_rd linux_unsecured_with_mq
+    linux_secured_with_tcp linux_unsecured_with_java linux_secured_with_java
+    android android_universal android_universal_unsecured
+    android_unsecured android_secured android_x86 android_x86_with_ip
+    android_x86_with_bt android_x86_with_ble android_x86_with_rm_and_ip
+    android_x86_with_rm_and_bt android_x86_with_rm_and_ble android_armeabi
+    android_armeabi_with_ip android_armeabi_with_bt android_armeabi_with_ble
+    android_armeabi_with_rm_and_ip android_armeabi_with_rm_and_bt
+    android_armeabi_with_rm_and_ble
+    windows msys simulator darwin tizen tizen_unsecured tizen_secured
+    unit_tests unit_tests_secured unit_tests_unsecured
+    unit_tests_memcheck_secured unit_tests_memcheck_unsecured
+
+    Note: nearly all of these are combination builds, which means they
+    are not useful to get a specific build to work on, rather they are
+    useful for "make sure all these build" tests as used by the Jenkins CI.
+    Any selection will build both debug and release versions of all available
+    targets in the scope you've selected except for unit tests, which by
+    their nature are debug only.
+    To choose any specific command, please use the SCons commandline directly.
+    Use \"EXEC_MODE=False %s <targetbuild>\"  to see commands to run.
     '''
-    print (helpstr % (script, script))
+    print (helpstr % (script, script, script))
     sys.exit(1)
 
-def call_scons(build_options, extra_option_str):
+
+def call_scons(build_options, scons_options):
     """
-    This function formats and runs a scons command
-    Arguments:
-    build_options    -- {Dictionary} build flags (keys) associated with values;
-    extra_option_str -- {String} extra options to append to scons command
+    Format and run a single scons command.
+
+    Args:
+        build_options (dict): build flags with values.
+        scons_options (str): additional flags to scons.
     """
     cmd_line = "scons VERBOSE=" + VERBOSE
     for key in build_options:
         cmd_line += " " + key + "=" + str(build_options[key])
 
-    cmd_line += " " + str(extra_option_str)
+    cmd_line += " " + str(scons_options)
 
     if not EXEC_MODE:
         print ("Would run : " + cmd_line)
@@ -45,171 +71,187 @@ def call_scons(build_options, extra_option_str):
         if exit_code != 0:
             sys.exit(exit_code)
 
-def build_all(flag, extra_option_str):
-    if platform.system() == "Linux":
-        build_linux_unsecured(flag, extra_option_str)
-        build_linux_secured(flag, extra_option_str)
-        build_linux_unsecured_with_rm(flag, extra_option_str)
-        build_linux_unsecured_with_rd(flag, extra_option_str)
-        build_linux_secured_with_rd(flag, extra_option_str)
-        build_linux_unsecured_with_mq(flag, extra_option_str)
-        build_linux_unsecured_with_tcp(flag, extra_option_str)
-        build_linux_secured_with_tcp(flag, extra_option_str)
-        build_linux_unsecured_with_java(flag, extra_option_str)
-        build_linux_secured_with_java(flag, extra_option_str)
-        build_simulator(flag, extra_option_str)
-
-        build_android_unsecured(flag, extra_option_str)
-        build_android_secured(flag, extra_option_str)
-        build_tizen(flag, extra_option_str)
 
+def build_all(flag, scons_options):
+    """
+    Build all the variants appropriate for the host platform.
+
+    Args:
+        flag (bool): if True, build in Release mode.
+        scons_options (dict): additional flags to scons.
+    """
+    if platform.system() == "Linux":
+        build_linux_unsecured(flag, scons_options)
+        build_linux_secured(flag, scons_options)
+        build_linux_unsecured_with_rm(flag, scons_options)
+        build_linux_unsecured_with_rd(flag, scons_options)
+        build_linux_secured_with_rd(flag, scons_options)
+        build_linux_unsecured_with_mq(flag, scons_options)
+        build_linux_unsecured_with_tcp(flag, scons_options)
+        build_linux_secured_with_tcp(flag, scons_options)
+        build_linux_unsecured_with_java(flag, scons_options)
+        build_linux_secured_with_java(flag, scons_options)
+        build_simulator(flag, scons_options)
+
+        build_android_unsecured(flag, scons_options)
+        build_android_secured(flag, scons_options)
+        build_tizen(flag, scons_options)
+
+    # Note: supported Windows mode is to use run.bat instead
     if platform.system() == "Windows":
-        build_windows(flag, extra_option_str)
+        build_windows(flag, scons_options)
 
     if platform.system() == "Darwin":
-        build_darwin(flag, extra_option_str)
+        build_darwin(flag, scons_options)
+
+
+def build_linux(flag, scons_options):
+    build_linux_unsecured(flag, scons_options)
+    build_linux_secured(flag, scons_options)
 
-def build_linux(flag, extra_option_str):
-    build_linux_unsecured(flag, extra_option_str)
-    build_linux_secured(flag, extra_option_str)
 
-def build_linux_unsecured(flag, extra_option_str):
+def build_linux_secured(flag, scons_options):
+    print ("*********** Build for linux with Security *************")
+    build_options = {
+        'RELEASE': flag,
+        'ERROR_ON_WARN': 1,
+    }
+    call_scons(build_options, scons_options)
+
+
+def build_linux_unsecured(flag, scons_options):
     print ("*********** Build for linux ************")
     build_options = {
-                        'RELEASE':flag,
-                        'SECURED':0,
-                        'ERROR_ON_WARN':1,
-                    }
-    call_scons(build_options, extra_option_str)
+        'RELEASE': flag,
+        'SECURED': 0,
+        'ERROR_ON_WARN': 1,
+    }
+    call_scons(build_options, scons_options)
+
 
-def build_linux_secured_with_tcp(flag, extra_option_str):
+def build_linux_secured_with_tcp(flag, scons_options):
     print ("*********** Build for linux with Secured TCP ************")
     build_options = {
-                        'RELEASE':flag,
-                        'WITH_TCP': 1,
-                        'WITH_CLOUD':1,
-                        'ERROR_ON_WARN':1,
-                    }
-    call_scons(build_options, extra_option_str)
+        'RELEASE': flag,
+        'WITH_TCP': 1,
+        'WITH_CLOUD': 1,
+        'ERROR_ON_WARN': 1,
+    }
+    call_scons(build_options, scons_options)
+
 
-def build_linux_unsecured_with_java(flag, extra_option_str):
+def build_linux_unsecured_with_tcp(flag, scons_options):
+    print ("*********** Build for linux with TCP ************")
+    build_options = {
+        'RELEASE': flag,
+        'WITH_TCP': 1,
+        'TARGET_TRANSPORT': 'IP',
+        'SECURED': 0,
+        'ERROR_ON_WARN': 1,
+    }
+    call_scons(build_options, scons_options)
+
+
+def build_linux_unsecured_with_java(flag, scons_options):
     print ("*********** Build for linux with Java support ************")
     build_options = {
-                        'RELEASE':flag,
-                        'BUILD_JAVA': 1,
-                        'TARGET_TRANSPORT': 'IP',
-                        'ERROR_ON_WARN':1,
-                    }
-    call_scons(build_options, extra_option_str)
+        'RELEASE': flag,
+        'BUILD_JAVA': 1,
+        'TARGET_TRANSPORT': 'IP',
+        'ERROR_ON_WARN': 1,
+    }
+    call_scons(build_options, scons_options)
+
 
-def build_linux_secured_with_java(flag, extra_option_str):
+def build_linux_secured_with_java(flag, scons_options):
     print ("*********** Build for linux with Java support and secured ************")
     build_options = {
-                        'RELEASE':flag,
-                        'BUILD_JAVA': 1,
-                        'TARGET_TRANSPORT': 'IP',
-                        'SECURED': 1,
-                        'ERROR_ON_WARN':1,
-                    }
-    call_scons(build_options, extra_option_str)
+        'RELEASE': flag,
+        'BUILD_JAVA': 1,
+        'TARGET_TRANSPORT': 'IP',
+        'SECURED': 1,
+        'ERROR_ON_WARN': 1,
+    }
+    call_scons(build_options, scons_options)
 
-def build_linux_unsecured_with_tcp(flag, extra_option_str):
-    print ("*********** Build for linux with TCP ************")
-    build_options = {
-                        'RELEASE':flag,
-                        'WITH_TCP': 1,
-                        'TARGET_TRANSPORT': 'IP',
-                        'SECURED':0,
-                        'ERROR_ON_WARN':1,
-                    }
-    call_scons(build_options, extra_option_str)
 
-def build_linux_unsecured_with_rm(flag, extra_option_str):
+def build_linux_unsecured_with_rm(flag, scons_options):
     print ("*********** Build for linux with RoutingManager************")
     build_options = {
-                        'ROUTING':'GW',
-                        'RELEASE':flag,
-                        'SECURED':0,
-                        'ERROR_ON_WARN':1,
-                    }
-    call_scons(build_options, extra_option_str)
+        'ROUTING': 'GW',
+        'RELEASE': flag,
+        'SECURED': 0,
+        'ERROR_ON_WARN': 1,
+    }
+    call_scons(build_options, scons_options)
 
-def build_linux_secured(flag, extra_option_str):
-    print ("*********** Build for linux with Security *************")
-    build_options = {
-                        'RELEASE':flag,
-                        'ERROR_ON_WARN':1,
-                    }
-    call_scons(build_options, extra_option_str)
 
-def build_linux_full(flag, extra_option_str):
+def build_linux_full(flag, scons_options):
+    """
+    Secured build with as many options selected as possible.
+    """
     print ("*********** Build for linux with full features *************")
     build_options = {
-                        'BUILD_JAVA':1,
-                        'MULTIPLE_OWNER':1,
-                        'RELEASE':flag,
-                        'SECURED':1,
-                        'WITH_CLOUD':1,
-                        'WITH_PROXY':1,
-                        'WITH_RA':1,
-                        'WITH_RA_IBB':1,
-                        'WITH_TCP':1,
-                        'ERROR_ON_WARN':1,
-                    }
-    call_scons(build_options, extra_option_str)
-
-def build_linux_unsecured_with_rd(flag, extra_option_str):
+        'BUILD_JAVA': 1,
+        'MULTIPLE_OWNER': 1,
+        'RELEASE': flag,
+        'SECURED': 1,
+        'WITH_CLOUD': 1,
+        'WITH_PROXY': 1,
+        'WITH_RA': 1,
+        'WITH_RA_IBB': 1,
+        'WITH_TCP': 1,
+        'ERROR_ON_WARN': 1,
+    }
+    call_scons(build_options, scons_options)
+
+
+def build_linux_unsecured_with_rd(flag, scons_options):
     print ("*********** Build for linux With Resource Directory *************")
     build_options = {
-                        'RELEASE':flag,
-                        'RD_MODE':'all',
-                        'SECURED':0,
-                        'ERROR_ON_WARN':1,
-                    }
-    call_scons(build_options, extra_option_str)
+        'RELEASE': flag,
+        'RD_MODE': 'all',
+        'SECURED': 0,
+        'ERROR_ON_WARN': 1,
+    }
+    call_scons(build_options, scons_options)
 
-def build_linux_secured_with_rd(flag, extra_option_str):
+
+def build_linux_secured_with_rd(flag, scons_options):
     print ("*********** Build for linux With Resource Directory & Security ************")
     build_options = {
-                        'RELEASE':flag,
-                        'RD_MODE':'all',
-                        'ERROR_ON_WARN':1,
-                    }
-    call_scons(build_options, extra_option_str)
+        'RELEASE': flag,
+        'RD_MODE': 'all',
+        'ERROR_ON_WARN': 1,
+    }
+    call_scons(build_options, scons_options)
+
 
-def build_linux_unsecured_with_mq(flag, extra_option_str):
+def build_linux_unsecured_with_mq(flag, scons_options):
     print ("*********** Build for linux With Message Queue ************")
     build_options = {
-                        'RELEASE':flag,
-                        'WITH_MQ':'PUB,SUB,BROKER',
-                        'SECURED':0,
-                        'ERROR_ON_WARN':1,
-                    }
-    call_scons(build_options, extra_option_str)
+        'RELEASE': flag,
+        'WITH_MQ': 'PUB,SUB,BROKER',
+        'SECURED': 0,
+        'ERROR_ON_WARN': 1,
+    }
+    call_scons(build_options, scons_options)
 
-def build_linux_unsecured_with_tcp(flag, extra_option_str):
-    print ("*********** Build for linux With tcp ************")
-    build_options = {
-                        'RELEASE':flag,
-                        'WITH_TCP':'1',
-                        'SECURED':0,
-                        'ERROR_ON_WARN':1,
-                    }
-    call_scons(build_options, extra_option_str)
 
-def build_android(flag, extra_option_str):
+def build_android(flag, scons_options):
     # Note: for android, as oic-resource uses C++11 feature stoi and to_string,
     # it requires gcc-4.9, currently only android-ndk-r10(for linux)
     # and windows android-ndk-r10(64bit target version) support these features.
     print ("*********** Build for android armeabi *************")
     build_options = {
-                        'TARGET_OS':'android',
-                        'TARGET_ARCH':'armeabi',
-                        'RELEASE':flag,
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'android',
+        'TARGET_ARCH': 'armeabi',
+        'RELEASE': flag,
+    }
+    call_scons(build_options, scons_options)
 
-def build_android_universal(flag, extra_option_str):
+
+def build_android_universal(flag, scons_options):
     print('''
 *******************************************************************************
     Starting Android Universal build
@@ -226,200 +268,219 @@ def build_android_universal(flag, extra_option_str):
 ''')
     print ("*********** Build for android armeabi *************")
     build_options = {
-                        'TARGET_OS':'android',
-                        'TARGET_ARCH':'armeabi',
-                        'RELEASE':flag,
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'android',
+        'TARGET_ARCH': 'armeabi',
+        'RELEASE': flag,
+    }
+    call_scons(build_options, scons_options)
     print ("*********** Build for android x86 *************")
     build_options = {
-                        'TARGET_OS':'android',
-                        'TARGET_ARCH':'x86',
-                        'RELEASE':flag,
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'android',
+        'TARGET_ARCH': 'x86',
+        'RELEASE': flag,
+    }
+    call_scons(build_options, scons_options)
     print ("*********** Build for android armeabi-v7a *************")
     build_options = {
-                        'TARGET_OS':'android',
-                        'TARGET_ARCH':'armeabi-v7a',
-                        'RELEASE':flag,
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'android',
+        'TARGET_ARCH': 'armeabi-v7a',
+        'RELEASE': flag,
+    }
+    call_scons(build_options, scons_options)
     print ("*********** Build for android x86_64 *************")
     build_options = {
-                        'TARGET_OS':'android',
-                        'TARGET_ARCH':'x86_64',
-                        'RELEASE':flag,
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'android',
+        'TARGET_ARCH': 'x86_64',
+        'RELEASE': flag,
+    }
+    call_scons(build_options, scons_options)
     print ("*********** Build for android arm64-v8a *************")
     build_options = {
-                        'TARGET_OS':'android',
-                        'TARGET_ARCH':'arm64-v8a',
-                        'RELEASE':flag,
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'android',
+        'TARGET_ARCH': 'arm64-v8a',
+        'RELEASE': flag,
+    }
+    call_scons(build_options, scons_options)
     print ("*********** Finishing Android universal build *************")
 
-def build_android_secured(flag, extra_option_str):
-    build_android(flag, extra_option_str + " SECURED=1")
 
-def build_android_unsecured(flag, extra_option_str):
-    build_android(flag, extra_option_str + " SECURED=0")
+def build_android_secured(flag, scons_options):
+    build_android(flag, scons_options + " SECURED=1")
+
 
-def build_android_x86(flag, extra_option_str):
+def build_android_unsecured(flag, scons_options):
+    build_android(flag, scons_options + " SECURED=0")
+
+
+def build_android_x86(flag, scons_options):
     """ Build Android x86 Suite """
-    build_android_x86_with_ip(flag, extra_option_str)
-    build_android_x86_with_bt(flag, extra_option_str)
-    build_android_x86_with_ble(flag, extra_option_str)
+    build_android_x86_with_ip(flag, scons_options)
+    build_android_x86_with_bt(flag, scons_options)
+    build_android_x86_with_ble(flag, scons_options)
+
 
-def build_android_x86_with_ip(flag, extra_option_str):
+def build_android_x86_with_ip(flag, scons_options):
     print ("*********** Build for android x86 *************")
     build_options = {
-                        'TARGET_OS':'android',
-                        'TARGET_ARCH':'x86',
-                        'RELEASE':flag,
-                        'TARGET_TRANSPORT':'IP',
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'android',
+        'TARGET_ARCH': 'x86',
+        'RELEASE': flag,
+        'TARGET_TRANSPORT': 'IP',
+    }
+    call_scons(build_options, scons_options)
 
-def build_android_x86_with_bt(flag, extra_option_str):
+
+def build_android_x86_with_bt(flag, scons_options):
     print ("*********** Build for android x86 with Bluetooth *************")
     build_options = {
-                        'TARGET_OS':'android',
-                        'TARGET_ARCH':'x86',
-                        'RELEASE':flag,
-                        'TARGET_TRANSPORT':'BT',
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'android',
+        'TARGET_ARCH': 'x86',
+        'RELEASE': flag,
+        'TARGET_TRANSPORT': 'BT',
+    }
+    call_scons(build_options, scons_options)
+
 
-def build_android_x86_with_ble(flag, extra_option_str):
+def build_android_x86_with_ble(flag, scons_options):
     print ("*********** Build for android x86 with Bluetooth Low Energy *************")
     build_options = {
-                        'TARGET_OS':'android',
-                        'TARGET_ARCH':'x86',
-                        'RELEASE':flag,
-                        'TARGET_TRANSPORT':'BLE',
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'android',
+        'TARGET_ARCH': 'x86',
+        'RELEASE': flag,
+        'TARGET_TRANSPORT': 'BLE',
+    }
+    call_scons(build_options, scons_options)
 
-def build_android_x86_with_rm(flag, extra_option_str):
+
+def build_android_x86_with_rm(flag, scons_options):
     """ Build Android x86 Routing Manager Suite """
-    build_android_x86_with_rm_and_ip(flag, extra_option_str)
-    build_android_x86_with_rm_and_bt(flag, extra_option_str)
-    build_android_x86_with_rm_and_ble(flag, extra_option_str)
+    build_android_x86_with_rm_and_ip(flag, scons_options)
+    build_android_x86_with_rm_and_bt(flag, scons_options)
+    build_android_x86_with_rm_and_ble(flag, scons_options)
+
 
-def build_android_x86_with_rm_and_ip(flag, extra_option_str):
+def build_android_x86_with_rm_and_ip(flag, scons_options):
     print ("*********** Build for android x86 with Routing Manager *************")
     build_options = {
-                        'TARGET_OS':'android',
-                        'TARGET_ARCH':'x86',
-                        'ROUTING':'GW',
-                        'RELEASE':flag,
-                        'TARGET_TRANSPORT':'IP',
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'android',
+        'TARGET_ARCH': 'x86',
+        'ROUTING': 'GW',
+        'RELEASE': flag,
+        'TARGET_TRANSPORT': 'IP',
+    }
+    call_scons(build_options, scons_options)
+
 
-def build_android_x86_with_rm_and_bt(flag, extra_option_str):
+def build_android_x86_with_rm_and_bt(flag, scons_options):
     print ("*********** Build for android x86 with Routing Manager and Bluetooth *************")
     build_options = {
-                        'TARGET_OS':'android',
-                        'TARGET_ARCH':'x86',
-                        'ROUTING':'GW',
-                        'RELEASE':flag,
-                        'TARGET_TRANSPORT':'BT',
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'android',
+        'TARGET_ARCH': 'x86',
+        'ROUTING': 'GW',
+        'RELEASE': flag,
+        'TARGET_TRANSPORT': 'BT',
+    }
+    call_scons(build_options, scons_options)
 
-def build_android_x86_with_rm_and_ble(flag, extra_option_str):
+
+def build_android_x86_with_rm_and_ble(flag, scons_options):
     print ("*********** Build for android x86 with Routing Manager and Bluetooth Low Energy *************")
     build_options = {
-                        'TARGET_OS':'android',
-                        'TARGET_ARCH':'x86',
-                        'ROUTING':'GW',
-                        'RELEASE':flag,
-                        'TARGET_TRANSPORT':'BLE',
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'android',
+        'TARGET_ARCH': 'x86',
+        'ROUTING': 'GW',
+        'RELEASE': flag,
+        'TARGET_TRANSPORT': 'BLE',
+    }
+    call_scons(build_options, scons_options)
+
 
-def build_android_armeabi(flag, extra_option_str):
+def build_android_armeabi(flag, scons_options):
     """ Build Android Armeabi Suite """
-    build_android_armeabi_with_ip(flag, extra_option_str)
-    build_android_armeabi_with_bt(flag, extra_option_str)
-    build_android_armeabi_with_ble(flag, extra_option_str)
+    build_android_armeabi_with_ip(flag, scons_options)
+    build_android_armeabi_with_bt(flag, scons_options)
+    build_android_armeabi_with_ble(flag, scons_options)
 
-def build_android_armeabi_with_ip(flag, extra_option_str):
+
+def build_android_armeabi_with_ip(flag, scons_options):
     print ("*********** Build for android armeabi *************")
     build_options = {
-                        'TARGET_OS':'android',
-                        'TARGET_ARCH':'armeabi',
-                        'RELEASE':flag,
-                        'TARGET_TRANSPORT':'IP',
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'android',
+        'TARGET_ARCH': 'armeabi',
+        'RELEASE': flag,
+        'TARGET_TRANSPORT': 'IP',
+    }
+    call_scons(build_options, scons_options)
+
 
-def build_android_armeabi_with_bt(flag, extra_option_str):
+def build_android_armeabi_with_bt(flag, scons_options):
     print ("*********** Build for android armeabi with Bluetooth *************")
     build_options = {
-                        'TARGET_OS':'android',
-                        'TARGET_ARCH':'armeabi',
-                        'RELEASE':flag,
-                        'TARGET_TRANSPORT':'BT',
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'android',
+        'TARGET_ARCH': 'armeabi',
+        'RELEASE': flag,
+        'TARGET_TRANSPORT': 'BT',
+    }
+    call_scons(build_options, scons_options)
+
 
-def build_android_armeabi_with_ble(flag, extra_option_str):
+def build_android_armeabi_with_ble(flag, scons_options):
     print ("*********** Build for android armeabi with Bluetooth Low Energy *************")
     build_options = {
-                        'TARGET_OS':'android',
-                        'TARGET_ARCH':'armeabi',
-                        'RELEASE':flag,
-                        'TARGET_TRANSPORT':'BLE',
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'android',
+        'TARGET_ARCH': 'armeabi',
+        'RELEASE': flag,
+        'TARGET_TRANSPORT': 'BLE',
+    }
+    call_scons(build_options, scons_options)
 
-def build_android_armeabi_with_rm(flag, extra_option_str):
+
+def build_android_armeabi_with_rm(flag, scons_options):
     """ Build Android Armeabi Routing Manager Suite """
-    build_android_armeabi_with_rm_and_ip(flag, extra_option_str)
-    build_android_armeabi_with_rm_and_bt(flag, extra_option_str)
-    build_android_armeabi_with_rm_and_ble(flag, extra_option_str)
+    build_android_armeabi_with_rm_and_ip(flag, scons_options)
+    build_android_armeabi_with_rm_and_bt(flag, scons_options)
+    build_android_armeabi_with_rm_and_ble(flag, scons_options)
+
 
-def build_android_armeabi_with_rm_and_ip(flag, extra_option_str):
+def build_android_armeabi_with_rm_and_ip(flag, scons_options):
     print ("*********** Build for android armeabi with Routing Manager *************")
     build_options = {
-                        'TARGET_OS':'android',
-                        'TARGET_ARCH':'armeabi',
-                        'ROUTING':'GW',
-                        'RELEASE':flag,
-                        'TARGET_TRANSPORT':'IP',
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'android',
+        'TARGET_ARCH': 'armeabi',
+        'ROUTING': 'GW',
+        'RELEASE': flag,
+        'TARGET_TRANSPORT': 'IP',
+    }
+    call_scons(build_options, scons_options)
+
 
-def build_android_armeabi_with_rm_and_bt(flag, extra_option_str):
+def build_android_armeabi_with_rm_and_bt(flag, scons_options):
     print ("*********** Build for android armeabi with Routing Manager and Bluetooth *************")
     build_options = {
-                        'TARGET_OS':'android',
-                        'TARGET_ARCH':'armeabi',
-                        'ROUTING':'GW',
-                        'RELEASE':flag,
-                        'TARGET_TRANSPORT':'BT',
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'android',
+        'TARGET_ARCH': 'armeabi',
+        'ROUTING': 'GW',
+        'RELEASE': flag,
+        'TARGET_TRANSPORT': 'BT',
+    }
+    call_scons(build_options, scons_options)
 
-def build_android_armeabi_with_rm_and_ble(flag, extra_option_str):
+
+def build_android_armeabi_with_rm_and_ble(flag, scons_options):
     print ("*********** Build for android armeabi with Routing Manager and Bluetooth Low Energy *************")
     build_options = {
-                        'TARGET_OS':'android',
-                        'TARGET_ARCH':'armeabi',
-                        'ROUTING':'GW',
-                        'RELEASE':flag,
-                        'TARGET_TRANSPORT':'BLE',
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'android',
+        'TARGET_ARCH': 'armeabi',
+        'ROUTING': 'GW',
+        'RELEASE': flag,
+        'TARGET_TRANSPORT': 'BLE',
+    }
+    call_scons(build_options, scons_options)
+
 
-def build_tizen(flag, extra_option_str):
+def build_tizen(flag, scons_options):
     print ("*********** Build for Tizen with options *************")
-    cmd_line = os.getcwd() + "/gbsbuild.sh" + " " + extra_option_str
+    cmd_line = os.getcwd() + "/gbsbuild.sh" + " " + scons_options
     if not EXEC_MODE:
         print ("Would run : " + cmd_line)
     else:
@@ -429,13 +490,13 @@ def build_tizen(flag, extra_option_str):
             sys.exit(exit_code)
 
     print ("*********** Build for Tizen octbstack lib and sample *************")
-    build_extra_options = "-f resource/csdk/stack/samples/tizen/build/SConscript " + extra_option_str
+    build_extra_options = "-f resource/csdk/stack/samples/tizen/build/SConscript " + scons_options
     build_options = {
-                        'TARGET_OS':'tizen',
-                        'TARGET_TRANSPORT':'IP',
-                        'LOGGING':'true',
-                        'RELEASE':flag,
-                    }
+        'TARGET_OS': 'tizen',
+        'TARGET_TRANSPORT': 'IP',
+        'LOGGING': 'true',
+        'RELEASE': flag,
+    }
     call_scons(build_options, build_extra_options)
 
     print ("*********** Build for Tizen octbstack lib and sample with Routing Manager*************")
@@ -445,131 +506,153 @@ def build_tizen(flag, extra_option_str):
     print ("*********** Build for Tizen Easy-Setup  sample *************")
     build_options['ROUTING'] = 'EP'
     build_options['ES_TARGET_ENROLLEE'] = 'tizen'
-    build_extra_options = "-f service/easy-setup/sampleapp/enrollee/tizen-sdb/EnrolleeSample/build/tizen/SConscript " + extra_option_str
+    build_extra_options = "-f service/easy-setup/sampleapp/enrollee/tizen-sdb/EnrolleeSample/build/tizen/SConscript " + scons_options
     call_scons(build_options, build_extra_options)
 
-def build_tizen_secured(flag, extra_option_str):
-    build_tizen(flag, extra_option_str + " SECURED=1")
 
-def build_tizen_unsecured(flag, extra_option_str):
-    build_tizen(flag, extra_option_str + " SECURED=0")
+def build_tizen_secured(flag, scons_options):
+    build_tizen(flag, scons_options + " SECURED=1")
+
+
+def build_tizen_unsecured(flag, scons_options):
+    build_tizen(flag, scons_options + " SECURED=0")
+
 
 # Mac OS and iOS
-def build_darwin(flag, extra_option_str):
+def build_darwin(flag, scons_options):
     print ("*********** Build for OSX *************")
     build_options = {
-                        'TARGET_OS':'darwin',
-                        'SYS_VERSION':'10.9',
-                        'RELEASE':flag,
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'darwin',
+        'SYS_VERSION': '10.9',
+        'RELEASE': flag,
+    }
+    call_scons(build_options, scons_options)
 
     print ("*********** Build for IOS i386 *************")
     build_options = {
-                        'TARGET_OS':'ios',
-                        'TARGET_ARCH':'i386',
-                        'SYS_VERSION':'7.0',
-                        'RELEASE':flag,
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'ios',
+        'TARGET_ARCH': 'i386',
+        'SYS_VERSION': '7.0',
+        'RELEASE': flag,
+    }
+    call_scons(build_options, scons_options)
 
     print ("*********** Build for IOS x86_64 *************")
     build_options['TARGET_ARCH'] = 'x86_64'
-    call_scons(build_options, extra_option_str)
+    call_scons(build_options, scons_options)
 
     print ("*********** Build for IOS armv7 *************")
     build_options['TARGET_ARCH'] = 'armv7'
-    call_scons(build_options, extra_option_str)
+    call_scons(build_options, scons_options)
 
     print ("*********** Build for IOS armv7s *************")
     build_options['TARGET_ARCH'] = 'armv7s'
-    call_scons(build_options, extra_option_str)
+    call_scons(build_options, scons_options)
 
     print ("*********** Build for IOS arm64 *************")
     build_options['TARGET_ARCH'] = 'arm64'
-    call_scons(build_options, extra_option_str)
+    call_scons(build_options, scons_options)
+
 
 # Windows
-def build_windows(flag, extra_option_str):
+def build_windows(flag, scons_options):
     print ("*********** Build for Windows *************")
     os.environ["SCONSFLAGS"] = ""
     build_options = {
-                        'TARGET_OS':'windows',
-                        'TARGET_ARCH':'amd64',
-                        'RELEASE':flag,
-                        'TARGET_TRANSPORT':'IP',
-                        'WITH_TCP':0,
-                        'BUILD_SAMPLE':'ON',
-                        'LOGGING':'off',
-                        'TEST':1,
-                        'RD_MODE':'all',
-                    }
-    call_scons(build_options, extra_option_str)
+        'TARGET_OS': 'windows',
+        'TARGET_ARCH': 'amd64',
+        'RELEASE': flag,
+        'TARGET_TRANSPORT': 'IP',
+        'WITH_TCP': 0,
+        'BUILD_SAMPLE': 'ON',
+        'LOGGING': 'off',
+        'TEST': 1,
+        'RD_MODE': 'all',
+    }
+    call_scons(build_options, scons_options)
+
 
 # Windows msys
-def build_msys(flag, extra_option_str):
+def build_msys(flag, scons_options):
     print ("*********** Build for msys_nt *************")
     os.environ["SCONSFLAGS"] = ""
     build_options = {
-                        'TARGET_OS':'msys_nt',
-                        'TARGET_ARCH':'x86_64',
-                        'RELEASE':flag,
-                        'TARGET_TRANSPORT':'IP',
-                        'WITH_TCP':0,
-                        'BUILD_SAMPLE':'ON',
-                        'LOGGING':'off',
-                        'TEST':1,
-                        'RD_MODE':'all',
-                    }
-    call_scons(build_options, extra_option_str)
-
-def build_simulator(flag, extra_option_str):
+        'TARGET_OS': 'msys_nt',
+        'TARGET_ARCH': 'x86_64',
+        'RELEASE': flag,
+        'TARGET_TRANSPORT': 'IP',
+        'WITH_TCP': 0,
+        'BUILD_SAMPLE': 'ON',
+        'LOGGING': 'off',
+        'TEST': 1,
+        'RD_MODE': 'all',
+    }
+    call_scons(build_options, scons_options)
+
+
+def build_simulator(flag, scons_options):
     print ("*********** Build for simulator plugin *************")
     build_options = {
-                        'SIMULATOR':1,
-                        'RELEASE':flag,
-                        'SECURED':0,
-                        'TARGET_TRANSPORT':'IP',
-                    }
-    call_scons(build_options, extra_option_str)
+        'SIMULATOR': 1,
+        'RELEASE': flag,
+        'SECURED': 0,
+        'TARGET_TRANSPORT': 'IP',
+    }
+    call_scons(build_options, scons_options)
 
-def unit_tests():
-    ''' build unsecured and secured, running unit tests for both.
+
+def do_unit_tests(secured=True, memcheck=False):
+    """ build full stack and run unit tests in selected mode.
+
+    All the unit test builders have to run in test (non-release) mode.
     This option is used by the CI system, which is a virtual machine -
     thus it should be built with only the IP transport to avoid timeouts
-    setting up infrastructure that is not present (i.e. BT and NFC)
-    '''
-    print ("*********** Unit test Start *************")
-    build_options = {
-                        'RELEASE':'false',
-                    }
-    extra_option_str = "-c ."
-    call_scons(build_options, extra_option_str)
+    setting up infrastructure that is not present (i.e. BT and NFC).
 
-    build_options = {
-                        'TEST':1,
-                        'RELEASE':'false',
-                        'SECURED':0,
-                        'TARGET_TRANSPORT':'IP',
-                    }
-    extra_option_str = ""
-    call_scons(build_options, extra_option_str)
+    Args:
+        secured (bool): build in secured mode.
+        memcheck (bool): run tests under control of memory checker.
+    """
 
     build_options = {
-                        'TEST':1,
-                        'RELEASE':'false',
-                        'SECURED':1,
-                        'TARGET_TRANSPORT':'IP',
-                    }
-    call_scons(build_options, extra_option_str)
-
+        'TEST': 1,
+        'RELEASE': 'false',
+        'TARGET_TRANSPORT': 'IP',
+        'SECURED': secured,
+        'VALGRIND_CHECKS': memcheck,
+    }
+    print ("*********** Unit test Start *************")
+    call_scons(build_options, "-c")  # clean first
+    call_scons(build_options, "")
     print ("*********** Unit test Stop *************")
 
+
+def unit_tests_secured():
+    do_unit_tests(secured=1)
+
+
+def unit_tests_unsecured():
+    do_unit_tests(secured=0)
+
+
+def unit_tests_memcheck_secured():
+    do_unit_tests(secured=1, memcheck=True)
+
+
+def unit_tests_memcheck_unsecured():
+    do_unit_tests(secured=0, memcheck=True)
+
+
+def unit_tests():
+    unit_tests_secured()
+    unit_tests_unsecured()
+
+
 # Main module starts here
 if os.getenv("SCONSFLAGS", "") == "":
     os.environ["SCONSFLAGS"] = "-Q -j " + str(multiprocessing.cpu_count())
 
-arg_num     = len(sys.argv)
+arg_num = len(sys.argv)
 script_name = sys.argv[0]
 
 # May be overridden in user's shell
@@ -747,12 +830,24 @@ elif arg_num == 2:
         build_darwin("true", "")
         build_darwin("false", "")
 
+    elif str(sys.argv[1]) == "unit_tests_secured":
+        unit_tests_secured()
+
+    elif str(sys.argv[1]) == "unit_tests_unsecured":
+        unit_tests_unsecured()
+
+    elif str(sys.argv[1]) == "unit_tests_memcheck_secured":
+        unit_tests_memcheck_secured()
+
+    elif str(sys.argv[1]) == "unit_tests_memcheck_unsecured":
+        unit_tests_memcheck_unsecured()
+
     elif str(sys.argv[1]) == "unit_tests":
         unit_tests()
 
     else:
         helpmsg(script_name)
 else:
-        helpmsg(script_name)
+    helpmsg(script_name)
 
 print ("===================== done =====================")