Exemple #1
0
def create_system_yaml(name):
    """ create YAML configuration for binary test for system package """
    BUILDTEST_CONFIGS_REPO = config_opts['BUILDTEST_CONFIGS_REPO']

    destdir = os.path.join(BUILDTEST_CONFIGS_REPO, "system", name)
    yamlfile = os.path.join(destdir, "command.yaml")

    # if yaml file exists then exit out
    if os.path.isfile(yamlfile):
        print "YAML file already exists, please check: ", yamlfile
        sys.exit(0)

    # if directory is not present then create it
    create_dir(destdir)

    # if package is not installed
    if check_system_package_installed(name) == False:
        print "Please install system package:", name, " before creating YAML file"
        sys.exit(0)

    # get binary from system package
    binary = get_binaries_from_systempackage(name)

    # no test, then stop immediately
    if len(binary) == 0:
        print "There are no binaries found in package: ", name
        sys.exit(0)

    fd = open(yamlfile, "w")
    binarydict = {"binaries": binary}
    with open(yamlfile, 'a') as outfile:
        yaml.dump(binarydict, outfile, default_flow_style=False)

    print "Please check YAML file", yamlfile, " and fix test accordingly"
    sys.exit(0)
Exemple #2
0
def setup_system_cmake(pkg):
        BUILDTEST_TESTDIR = config_opts['BUILDTEST_TESTDIR']
	 # top level system directory and system package directory
        test_system_dir=os.path.join(BUILDTEST_TESTDIR,"system")
        test_destdir=os.path.join(BUILDTEST_TESTDIR,"system",pkg)

        # top level CMakeLists.txt in testing directory
        test_cmakelist = os.path.join(BUILDTEST_TESTDIR,"CMakeLists.txt")

        # CMakeLists.txt that contains all system package directories to process
        test_cmakelist_pkg = os.path.join(BUILDTEST_TESTDIR,"system","CMakeLists.txt")

        # CMakeLists.txt that contais the actual tests (add_test)
        test_cmakelist_destdir=os.path.join(test_destdir,"CMakeLists.txt")

	logger = logging.getLogger(logID)

        logger.debug("Variables Assignments")
        logger.debug("----------------------------------")
        logger.debug("SYSTEM Test Directory: %s ", test_system_dir)
        logger.debug("Testscript Destination Directory: %s", test_destdir)
        logger.debug("CMakeList for BUILDTEST_TESTDIR: %s ", test_cmakelist)
        logger.debug("CMakeList for $BUILDTEST_TESTDIR/system: %s",  test_cmakelist_pkg)
        logger.debug("CMakeList for $BUILDTEST_TESTDIR/system/%s: %s" , pkg, test_cmakelist_destdir)

        # if testdirectory exist, delete and recreate it inorder for reproducible test builds
        if os.path.isdir(test_destdir):
                shutil.rmtree(test_destdir)
                logger.debug("Removing directory: %s before creating tests ", test_destdir)

        # create the directories if they don't exist
        create_dir(test_system_dir)
        create_dir(test_destdir)

        # create CMakeLists.txt files if they are not present
        create_file(test_cmakelist)
        create_file(test_cmakelist_pkg)
        create_file(test_cmakelist_destdir)

        # update the CMakeLists.txt with the tag add_subdirectory(system)
        update_CMakeLists(test_cmakelist,"system")

        logger.debug("Updating %s with add_subdirectory(system)", test_cmakelist)
        logger.debug("Updating %s with add_subdirectory(%s)", test_cmakelist_pkg,pkg)
        # update CMakeLists.txt with the tag add_subdirectory(pkg) where pkg is the application name
        update_CMakeLists(test_cmakelist_pkg,pkg)

	return test_destdir,test_cmakelist_destdir
Exemple #3
0
def setup_software_cmake():

    logger = logging.getLogger(logID)
    BUILDTEST_TESTDIR = config_opts['BUILDTEST_TESTDIR']

    name = get_appname()
    version = get_appversion()
    toolchain_name = get_toolchain_name()
    toolchain_version = get_toolchain_version()

    # if top level software directory is not present, create it
    test_ebapp_dir=os.path.join(BUILDTEST_TESTDIR,"ebapp")

    # variables to reference each subdirectory in <software>/<version>/<toolchain-name>/<toolchain-version>
    test_name_dir=os.path.join(test_ebapp_dir,name)
    test_version_dir=os.path.join(test_name_dir,version)
    test_toolchain_name_dir=os.path.join(test_version_dir,toolchain_name)
    test_toolchain_version_dir=os.path.join(test_toolchain_name_dir,toolchain_version)

    # BUILDTEST_TESTDIR/CMakeLists.txt
    test_cmakelist = os.path.join(BUILDTEST_TESTDIR,"CMakeLists.txt")

    # BUILDTEST_TESTDIR/ebapps/CMakeLists.txt
    test_ebapp_cmakelist = os.path.join(test_ebapp_dir,"CMakeLists.txt")

    # CMakeLists.txt files in <software>/<version>/<toolchain-name>/<toolchain-version>
    test_name_cmakelist = os.path.join(test_name_dir,"CMakeLists.txt")
    test_version_cmakelist = os.path.join(test_version_dir,"CMakeLists.txt")
    test_toolchain_name_cmakelist = os.path.join(test_toolchain_name_dir,"CMakeLists.txt")
    test_toolchain_version_cmakelist = os.path.join(test_toolchain_version_dir,"CMakeLists.txt")

    test_destdir=test_toolchain_version_dir


    logger.debug("----------------------------------------")
    logger.debug("EB Directory Assignments")
    logger.debug("----------------------------------------")

    logger.debug("EB Directory in $BUILDTEST_TESTDIR: %s ", test_ebapp_dir)
    logger.debug("EB Application Directory: %s", test_name_dir)
    logger.debug("EB Application Version Directory: %s", test_version_dir)
    logger.debug("EB Toolchain Name Directory: %s", test_toolchain_name_dir)
    logger.debug("EB Toolchain Version Directory: %s", test_toolchain_version_dir)

    logger.debug("\n")
    logger.debug("Test Directory for EB Application: %s ", test_destdir)

    logger.debug("\n\n")

    logger.debug("----------------------------------------")
    logger.debug("EB CMakeList Assignments")
    logger.debug("----------------------------------------")

    logger.debug("$BUILDTEST_TESTDIR CMakeList Path: %s ", test_cmakelist)
    logger.debug("EB Application CMakeList Path: %s ", test_name_cmakelist)
    logger.debug("EB Application Version CMakeList Path: %s", test_version_cmakelist)
    logger.debug("EB Toolchain Name CMakeList Path: %s", test_toolchain_name_cmakelist)
    logger.debug("EB Toolchain Version CMakeList Path: %s", test_toolchain_version_cmakelist)


    # if test directory exist, delete and recreate it inorder for reproducible test builds
    if os.path.isdir(test_destdir):
        shutil.rmtree(test_destdir)
        logger.debug("Removing test directory before creating test: %s", test_destdir)

    # create directories if they don't exist
    # Directory Format: <software>/<version>/toolchain-name>/<toolchain-version>
    create_dir(test_ebapp_dir)
    create_dir(test_name_dir)
    create_dir(test_version_dir)



    if len(toolchain_name) != 0:
        create_dir(test_toolchain_name_dir)
        create_dir(test_toolchain_version_dir)

    # create CMakeList.txt file in each directory of <software>/<version>/<toolchain-name>/<toolchain-version> if it doesn't exist
    create_file(test_ebapp_cmakelist)

    create_file(test_name_cmakelist)
    create_file(test_version_cmakelist)


    if len(toolchain_name) != 0:
        create_file(test_toolchain_name_cmakelist)
        create_file(test_toolchain_version_cmakelist)


    # update CMakeLists.txt with tags add_subdirectory(ebapp)
    update_CMakeLists(test_cmakelist,"ebapp")

    # update CMakeLists.txt with tags add_subdirectory(X) where X=name|version|toolchain-name|toolchain-version
    update_CMakeLists(test_ebapp_cmakelist,name)
    update_CMakeLists(test_name_cmakelist,version)

    if len(toolchain_name) != 0:
        update_CMakeLists(test_version_cmakelist,toolchain_name)
        update_CMakeLists(test_toolchain_name_cmakelist,toolchain_version)

    return test_destdir,test_toolchain_version_cmakelist
Exemple #4
0
def main():
    """ entry point to buildtest """

    IGNORE_EASYBUILD = False

    override_configuration()
    check_configuration()

    BUILDTEST_CONFIGS_REPO = config_opts['BUILDTEST_CONFIGS_REPO']
    print BUILDTEST_CONFIGS_REPO
    parser = buildtest_menu()
    bt_opts = parser.parse_options()

    if config_opts.get('BUILDTEST_IGNORE_EASYBUILD'):
        IGNORE_EASYBUILD = config_opts['BUILDTEST_IGNORE_EASYBUILD']

    if bt_opts.version:
        buildtest_version()
        sys.exit(0)

    if bt_opts.show:
        show_configuration()

    if bt_opts.logdir:
        config_opts['BUILDTEST_LOGDIR'] = bt_opts.logdir

    if bt_opts.testdir:
        config_opts['BUILDTEST_TESTDIR'] = bt_opts.testdir

    if bt_opts.ignore_easybuild:
        IGNORE_EASYBUILD = True

    if bt_opts.enable_job:
        config_opts['BUILDTEST_ENABLE_JOB'] = True

    if bt_opts.clean_logs:
        clean_logs()

    if bt_opts.clean_tests:
        clean_tests()

    if bt_opts.module_naming_scheme:
        config_opts[
            'BUILDTEST_MODULE_NAMING_SCHEME'] = bt_opts.module_naming_scheme

    if bt_opts.runtest:
        runtest_menu()

    if bt_opts.scantest:
        scantest()

    if bt_opts.list_toolchain is True:
        toolchain_set = list_toolchain()
        print_toolchain(toolchain_set)
        sys.exit(0)

    if bt_opts.list_unique_software:
        software_set = get_unique_software()
        print_software(software_set)
        sys.exit(0)

    if bt_opts.software_version_relation:
        software_dict = software_version_relation()
        print_software_version_relation(software_dict)
        sys.exit(0)

    if bt_opts.easyconfigs_in_moduletrees:
        find_easyconfigs()
        sys.exit(0)

    if bt_opts.diff_trees:
        args_trees = bt_opts.diff_trees
        diff_trees(args_trees)
        sys.exit(0)

    # when no argument is specified to -fc then output all yaml files
    if bt_opts.findconfig == "all":
        find_all_yaml_configs()
        sys.exit(0)
    # find yaml configs by argument instead of reporting all yaml files
    elif bt_opts.findconfig is not None:
        find_yaml_configs_by_arg(bt_opts.findconfig)
        sys.exit(0)
        # report all buildtest generated test scripts
        if bt_opts.findtest == "all":
            find_all_tests()
            sys.exit(0)
# find test by argument instead of all tests
        elif bt_opts.findtest is not None:
            find_tests_by_arg(bt_opts.findtest)
            sys.exit(0)

    if bt_opts.shell:
        config_opts['BUILDTEST_SHELL'] = bt_opts.shell

    if bt_opts.job_template is not None:
        update_job_template(bt_opts.job_template)

    if bt_opts.submitjob is not None:
        submit_job_to_scheduler(bt_opts.submitjob)
        sys.exit(0)

    if bt_opts.sysyaml is not None:
        create_system_yaml(bt_opts.sysyaml)

    if bt_opts.ebyaml != None:
        raise NotImplementedError

    logger, logpath, logfile = init_log()
    BUILDTEST_LOGDIR = config_opts['BUILDTEST_LOGDIR']
    BUILDTEST_TESTDIR = config_opts['BUILDTEST_TESTDIR']

    create_dir(BUILDTEST_LOGDIR)
    create_dir(BUILDTEST_TESTDIR)

    cmd = "env | grep BUILDTEST"
    ret = subprocess.Popen(cmd,
                           shell=True,
                           stdin=subprocess.PIPE,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)
    output = ret.communicate()[0]
    output = output.split("\n")

    for line in output:
        logger.debug(line)

    # generate system pkg test
    if bt_opts.system is not None:
        if bt_opts.system == "all":
            systempkg = bt_opts.system
            logger.info(
                "Generating all system package tests from YAML files in %s",
                os.path.join(BUILDTEST_CONFIGS_REPO, "system"))

            BUILDTEST_LOGDIR = os.path.join(BUILDTEST_LOGDIR, "system", "all")
            systempkg_list = os.listdir(
                os.path.join(BUILDTEST_CONFIGS_REPO, "system"))

            logger.info("List of system packages to test: %s ", systempkg_list)

            for pkg in systempkg_list:
                generate_binary_test(bt_opts, pkg)
        else:

            systempkg = bt_opts.system
            BUILDTEST_LOGDIR = os.path.join(BUILDTEST_LOGDIR, "system",
                                            systempkg)
            generate_binary_test(bt_opts, systempkg)

        create_dir(BUILDTEST_LOGDIR)
        logger.warning("Creating directory %s, to write log file",
                       BUILDTEST_LOGDIR)

        destpath = os.path.join(BUILDTEST_LOGDIR, logfile)
        os.rename(logpath, destpath)
        logger.info("Moving log file from %s to %s", logpath, destpath)

        print "Writing Log file to:", destpath
        sys.exit(0)

# when -s is specified
    if bt_opts.software is not None:
        software = bt_opts.software.split("/")

        if bt_opts.toolchain is None:
            toolchain = "dummy/dummy".split("/")
        else:
            toolchain = bt_opts.toolchain.split("/")

        appname = get_appname()
        appversion = get_appversion()
        tcname = get_toolchain_name()
        tcversion = get_toolchain_version()

        print "Detecting Software: ", os.path.join(appname, appversion)

        logger.debug("Generating Test from EB Application")

        logger.debug("Software: %s", appname)
        logger.debug("Software Version: %s", appversion)
        logger.debug("Toolchain: %s", tcname)
        logger.debug("Toolchain Version: %s", tcversion)

        logger.debug("Checking if software: %s/%s exists", appname, appversion)

        # check if software is an easybuild applicationa
        if IGNORE_EASYBUILD == False:
            is_easybuild_app()

        source_app_dir = os.path.join(BUILDTEST_CONFIGS_REPO, "ebapps",
                                      appname.lower())
        configdir = os.path.join(source_app_dir, "config")
        codedir = os.path.join(source_app_dir, "code")
        BUILDTEST_LOGDIR = os.path.join(BUILDTEST_LOGDIR, appname, appversion,
                                        tcname, tcversion)

        # if directory tree for software log is not present, create the directory
        create_dir(BUILDTEST_LOGDIR)

        logger.debug("Source App Directory: %s", source_app_dir)
        logger.debug("Config Directory: %s ", configdir)
        logger.debug("Code Directory: %s", codedir)

        generate_binary_test(bt_opts, None)

        # this generates all the compilation tests found in application directory ($BUILDTEST_CONFIGS_REPO/ebapps/<software>)
        recursive_gen_test(configdir, codedir)

        # if flag --testset is set, then
        if bt_opts.testset is not None:
            run_testset(bt_opts)

        # moving log file from $BUILDTEST_LOGDIR/buildtest_%H_%M_%d_%m_%Y.log to $BUILDTEST_LOGDIR/app/appver/tcname/tcver/buildtest_%H_%M_%d_%m_%Y.log
        os.rename(logpath, os.path.join(BUILDTEST_LOGDIR, logfile))
        logger.debug("Writing Log file to %s",
                     os.path.join(BUILDTEST_LOGDIR, logfile))

        print "Writing Log file: ", os.path.join(BUILDTEST_LOGDIR, logfile)
def generate_source_test(configmap, codedir, subdir):
    """
    This function generates the tests that requires compilation for EB apps. The
    tests are written <software>/<version>/<toolchain-name>/<toolchain-version>.
    The test script is named according to "name" key tag with the shell extension
    CMakeLists.txt has an entry for each test that executes the shell-script. Most
    test requires a compilation step, while every test requires a execution stage.
    This is done via buildcmd and runcmd tags in YAML for explicit builds. buildtest
    will try to generate this automatically if nothing is provided.
    """

    appname = get_appname()
    appver = get_appversion()
    tcname = get_toolchain_name()
    tcver = get_toolchain_version()

    logger = logging.getLogger(logID)
    BUILDTEST_TESTDIR = config_opts['BUILDTEST_TESTDIR']

    testname = ""
    testpath = ""
    sourcefilepath = ""
    executable = ""
    buildopts = ""
    envvars = ""
    env_msg = []
    # app_destdir is root of test directory
    app_destdir = os.path.join(BUILDTEST_TESTDIR, "ebapp", appname, appver,
                               tcname, tcver)

    # destdir is where test script and CMakeLists.txt will be generated.
    # If there is a subdirectory then testscript will reside in subdir
    destdir = os.path.join(app_destdir, subdir)
    cmakelist = os.path.join(destdir, "CMakeLists.txt")

    # if subdirectory exists, create subdirectory in destdir so we can write test script
    #if subdir != "":
    # if sub directory does not exist, then create all directories and its parents directories
    create_dir(destdir)

    shell_type = config_opts['BUILDTEST_SHELL']
    BUILDTEST_JOB_TEMPLATE = config_opts['BUILDTEST_JOB_TEMPLATE']
    BUILDTEST_ENABLE_JOB = config_opts['BUILDTEST_ENABLE_JOB']

    # testname is key value "name" with .sh extension
    testname = configmap["name"] + "." + shell_type
    testpath = os.path.join(destdir, testname)
    sourcefilepath = os.path.join(codedir, configmap["source"])
    # name of the executable is the value of source tag with ".exe" extension
    executable = configmap["source"] + ".exe"

    flags = ""
    # if buildopts key exists in dictionary, then add flags to compilation step (buildcmd)
    if "buildopts" in configmap:
        flags = configmap["buildopts"]

    if "envvars" in configmap:
        envvars = configmap["envvars"]
        for key in envvars.keys():
            # append value from function openmp_env_string into env_msg that sets OpenMP environment variable according to shell
            env_msg.append(openmp_env_string(shell_type, envvars[key]))

    if "procrange" in configmap:
        procrange = configmap["procrange"]
        startproc = int(procrange.split(",")[0])
        endproc = int(procrange.split(",")[1])
        procinterval = int(procrange.split(",")[2])
        testname = configmap["name"] + "_nproc_" + str(
            startproc) + "." + shell_type
        testpath = os.path.join(destdir, testname)
        mpi_proc_list = range(startproc, endproc + 1, procinterval)

    if "threadrange" in configmap:
        threadrange = configmap["threadrange"]
        startthread = int(threadrange.split(",")[0])
        endthread = int(threadrange.split(",")[1])
        threadinterval = int(threadrange.split(",")[2])
        testname = configmap["name"] + "_nthread_" + str(
            startthread) + "." + shell_type
        testpath = os.path.join(destdir, testname)
        thread_list = range(startthread, endthread + 1, threadinterval)
        openmp_env_str = openmp_env_string(shell_type, startthread)

    logger.debug("Test Name: %s", testname)
    logger.debug("Test Path: %s", testpath)
    logger.debug("Source File: %s", sourcefilepath)
    logger.debug("Executable Name: %s", executable)
    logger.debug("Build Flags: %s", flags)

    # write the preamble to test-script to initialize app environment using module cmds
    fd = open(testpath, 'w')
    header = load_modules(shell_type)
    fd.write(header)

    # string used for generating the compilation step
    buildcmd = ""
    # string used for running the executable and used for injecting commands at pre/post test
    runcmd = ""
    # string to decide the compiler wrapper to use based on application and file extension
    compiler = ""
    # used for parallel processing to specify # of procs with mpirun -np
    nproc = ""

    logger.debug("""Checking for YAML key "buildcmd" and "runcmd" """)

    # if there is a buildcmd & runcmd in yaml file, place this directly in test script
    if "buildcmd" in configmap and "runcmd" in configmap:

        logger.debug("YAML file found buildcmd and runcmd.")
        logger.debug(
            "buildtest will generate explicit build/run commands from buildcmd and runcmd field"
        )

        # only process buildcmd if there is a value specified for buildcmd key
        if configmap["buildcmd"] != None:
            # for each element from dictionary configmap["buildcmd"], write
            # each instruction in buildcmd separated by newline
            for cmd in configmap["buildcmd"]:
                buildcmd += cmd + "\n"
        else:
            msg = "buildcmd is declared but value is not specified \n"
            logger.debug("%s", msg)

        if configmap["runcmd"] != None:
            # process the runcmd tag similar same as buildcmd and store in variable
            # runcmd except if no value is specified for runcmd in YAML then throw
            # an error
            for cmd in configmap["runcmd"]:
                runcmd += cmd + "\n"
        else:
            msg = "runcmd is declared but value is not specified. Need runcmd to run executable \n"
            print msg
            logger.debug.append("%s", msg)
            logging.warning(
                "Unable to create test from YAML config, skipping test generation"
            )
            return

        fd.write(buildcmd)
        fd.write(runcmd)

    # otherwise generate the buildcmd and runcmd automatically
    else:

        # checking if either buildcmd or runcmd specified but not both, then report an error.
        if "buildcmd" in configmap and "runcmd" not in configmap or "buildcmd" not in configmap and "runcmd" in configmap:
            print "Need to specify both key: buildcmd and runcmd"

            logger.warning(
                "Need to declare both key: buildcmd and runcmd. Skipping to next YAML config \n"
            )
            return

        # get the compiler tag and type based on application and toolchain
        compiler, compiler_type = get_compiler(configmap, appname, tcname)

        logger.debug("buildtest will auto-generate buildcmd & runcmd")
        logger.debug("Compiler: %s", compiler)
        logger.debug("Compiler Type: %s", compiler_type)

        # set buildcmd based on compiler_type. compiler is either nvcc,gcc,icc,mpicc, or mpiicc for intel
        if compiler_type == "gnu" or compiler_type == "intel" or compiler_type == "cuda":

            buildcmd = compiler + " -o " + executable + " " + sourcefilepath + " " + flags + "\n"
            #print buildcmd
            # set runcmd for mpi tags using mpirun otherwise just run executable
            if compiler in [
                    "mpicc", "mpic++", "mpifort", "mpiicc", "mpiic++",
                    "mpiifort"
            ]:

                # if nproc is defined in yaml, store value in nproc which will use it in mpirun command
                if "nproc" in configmap:
                    nproc = str(configmap["nproc"])
                    logger.debug("nproc key found in YAML config file")
                    logger.debug("nproc: %s", nproc)

                # check for procrange in case nproc is not defined
                elif "procrange" in configmap:
                    nproc = str(startproc)

                # if nproc is not specified set it to 1 when building mpi apps
                else:
                    nproc = "1"

                    logger.debug(
                        "nproc key not found in YAML config file, will set nproc = 1"
                    )
                    # add argument to runcmd in MPI jobs
                    if "args" in configmap:
                        arglist = configmap["args"]
                        runcmd = "mpirun -np " + nproc + " ./" + executable
                        runcmd = add_arg_to_runcmd(runcmd, arglist)
                    else:
                        runcmd = "mpirun -np " + nproc + " ./" + executable
            else:
                # add argument to runcmd in general jobs
                if "args" in configmap:
                    arglist = configmap["args"]
                    runcmd = "./" + executable
                    runcmd = add_arg_to_runcmd(runcmd, arglist)
                else:
                    runcmd = "./" + executable

        # Scripting languages like Python, R, Perl no compilation stage, just run script. So we just need to update runcmd string
        elif compiler_type == "python" or compiler_type == "perl" or compiler_type == "R":
            if "args" in configmap:
                arglist = configmap["args"]
                runcmd = compiler + " " + sourcefilepath
                runcmd = add_arg_to_runcmd(runcmd, arglist)

            else:
                runcmd = compiler + " " + sourcefilepath

        # java programs need "javac" to compile and "java" to run program. This works best if you are
        # in current directory where source file exists.
        elif compiler_type == "java":
            buildcmd = compiler + " " + sourcefilepath + "\n"
            java_codedir = os.path.dirname(sourcefilepath)
            filename = os.path.basename(os.path.splitext(sourcefilepath)[0])
            # need to be directory where java files reside
            runcmd = "cd " + java_codedir + "\n"
            runcmd += "java " + filename + "\n"
            # would like to remove .class files that are generated due to javac
            runcmd += "rm -v " + filename + ".class"

        # if inputfile key is found, add this as part of runcmd
        if "inputfile" in configmap:
            runcmd += " < " + os.path.join(codedir, configmap["inputfile"])
        # if output of program needs to be written to file instead of STDOUT
        if "outputfile" in configmap:
            runcmd += " > " + configmap["outputfile"]

        if "envvars" in configmap:
            for key in env_msg:
                fd.write(key)

        if "threadrange" in configmap:
            fd.write(openmp_env_str)

        fd.write(buildcmd)
        fd.write(runcmd)

        # runextracmd is used when you want buildtest to generate compilation and execution step
        # automatically but need to add extra commands after execution.
        if "runextracmd" in configmap:
            for cmd in configmap["runextracmd"]:
                fd.write(cmd + "\n")

            logger.debug("runextracmd found in YAML config file")
            logger.debug("runextracmd: %s", str(configmap["runextracmd"]))

        fd.close()

    if BUILDTEST_ENABLE_JOB:
        if "scheduler" in configmap:
            generate_job_by_config(testpath, shell_type, configmap)
        else:
            # generate job script based on template, if "scheduler" found in
            # then module below will do nothing and taken care off by
            # generate_job_by_config
            generate_job(testpath, shell_type, BUILDTEST_JOB_TEMPLATE,
                         configmap)

        # by default run the commands below which will add the test to CMakeLists.txt and update the logfile
        if "iter" not in configmap:
            add_test_to_CMakeLists(app_destdir, subdir, cmakelist, testname)

            # print "Creating Test: " + testpath

            logger.debug("Creating Test: %s ", testpath)
            logger.debug("[TEST START-BLOCK]")

            fd = open(testpath, 'r')
            content = fd.read().splitlines()
            for line in content:
                logger.debug(line)

            fd.close()

            logger.debug("[TEST END-BLOCK]")

    if "procrange" in configmap:
        create_procrange_test(testpath, startproc, mpi_proc_list, subdir)
    if "threadrange" in configmap:
        create_threadrange_test(testpath, startthread, thread_list, subdir)

    # if keyword iter is found in YAML, lets try to recreate N tests by renaming test such as
    # hello.sh to hello_1.sh and create N-1 copies with file names hello_2.sh, hello_3.sh, ...
    if "iter" in configmap:
        filename = os.path.basename(os.path.splitext(sourcefilepath)[0])
        testname = filename + "_1." + shell_type
        testpath_testname = os.path.join(destdir, testname).replace("\n", '')
        os.rename(testpath, testpath_testname)
        out = "Rename Iteration Test: " + testpath + " -> " + testpath_testname
        logger.debug("%s", out)
        # writing test to CMakeLists.txt
        add_test_to_CMakeLists(app_destdir, subdir, cmakelist, testname)
        logger.debug("Content of Test file: %s", testpath_testname)
        logger.debug("[START TEST-BLOCK]")

        fd = open(testpath_testname, 'r')
        content = fd.read()
        logger.debug("%s", content)
        fd.close()
        logger.debug("[END TEST-BLOCK]")

        numiter = int(configmap["iter"])
        logger.debug("Making %s copy of test: %s", numiter, testpath_testname)
        # creating N-1 copies of tests
        for index in range(1, numiter):
            testname = filename + "_" + str(index + 1) + "." + shell_type
            src_testpath = testpath_testname
            dest_testpathname = os.path.join(destdir,
                                             testname).replace('\n', '')
            copyfile(src_testpath, dest_testpathname)
            out = "Iteration Test: " + dest_testpathname
            logger.info("%s", out)
            logger.debug("Adding test: %s to CMakeList", testname)
            add_test_to_CMakeLists(app_destdir, subdir, cmakelist, testname)