1#!/usr/local/bin/python3.8 2# -*- mode: python; py-indent-offset: 4; py-continuation-offset: 4 -*- 3# 4# Change shebang line to '/usr/bin/python -3' for python 3.x porting warnings 5""" 6This script drives a PR testing build. It assume that Trilinos is already 7cloned under $WORKSPACE/Trilinos and that the 'origin' remote points to 8$TRILINOS_TARGET_REPO (but that is not checked here). 9 10As long as the ${WORKSPACE}/Trilinos git repo has the correct 'origin', this 11script will automatically set it up to do the merge correctly, no matter 12what its state before this script is called (i.e. from a past PR 13attempt). Unless the Trilinos/.git directory becomes corrupted, there should 14*NEVER* be any need to delete and reclone this Trilinos git repo. 15 16This script can be run in a mode where the driver scripts are run from one 17Trilinos git repo and operate on another Trilinos git repo that gets 18manipulated in order to merge the "source" topic branch into the "target" 19branch. This makes it easy to test changes to the PR scripts. But if this 20script is run from ${WORKSPACE}/Trilinos, then these repos are one and the same 21and we get the correct behavior for PR testing. 22 23Expectations 24------------ 25 26### Environment Variables 27- WORKSPACE : Root level directory for the Jenkins job. 28- MODULESHOME : Path to the location where modulefiles are. 29- CC : C Compiler 30- FC : Fortran Compiler 31- PULLREQUEST_CDASH_TRACK : Which CDash track should this result be published to? 32- JENKINS_JOB_WEIGHT : Number of cores to use to build Trilinos 33 34### Other Expectations? 35 36""" 37from __future__ import print_function 38 39# turn off generation of the .pyc/.pyo files. 40import sys 41sys.dont_write_bytecode = True 42 43import argparse 44import os 45import re 46import sys 47from textwrap import dedent 48 49import subprocess 50from multiprocessing import cpu_count 51 52sys.path.insert(1, os.path.join(os.environ['MODULESHOME'], 'init')) 53 54try: 55 from env_modules_python import module 56except ImportError: 57 def module(*args): 58 if type(args[0]) == type([]): 59 args = args[0] 60 else: 61 args = list(args) 62 (output, error) = subprocess.Popen(['/usr/bin/modulecmd', 'python'] + 63 args, 64 stdout=subprocess.PIPE).communicate() 65 exec(output) 66 67 68 69def parse_args(): 70 parser = argparse.ArgumentParser(description='Parse the repo and build information') 71 72 parser.add_argument('sourceRepo', action='store', help='Repo with the new changes') 73 parser.add_argument('sourceBranch', action='store', help='Branch with the new changes') 74 parser.add_argument('targetRepo', action='store', help='Repo to merge into') 75 parser.add_argument('targetBranch', action='store', help='Branch to merge to') 76 77 parser.add_argument('job_base_name', help='The jenkins job base name') 78 parser.add_argument('github_pr_number', help='The github PR number') 79 parser.add_argument('job_number', help='The jenkins build number') 80 parser.add_argument('workspaceDir', help='The local workspace directory jenkins set up') 81 82 arguments = parser.parse_args() 83 84 return arguments 85 86 87def print_input_variables(arguments): 88 print("\n" + "="*90) 89 print("Jenkins Input Variables:") 90 print("- JOB_BASE_NAME: {job_base_name}".format(**vars(arguments))) 91 print("- WORKSPACE : {workspaceDir}".format(**vars(arguments))) 92 print("\n" + "="*90) 93 print("Parameters:") 94 print("- TRILINOS_SOURCE_REPO : {sourceRepo}".format(**vars(arguments))) 95 print("- TRILINOS_SOURCE_BRANCH: {sourceBranch}\n".format(**vars(arguments))) 96 print("- TRILINOS_TARGET_REPO : {targetRepo}".format(**vars(arguments))) 97 print("- TRILINOS_TARGET_BRANCH: {targetBranch}\n".format(**vars(arguments))) 98 print("- PULLREQUESTNUM : {github_pr_number}".format(**vars(arguments))) 99 print("- BUILD_NUMBER : {job_number}".format(**vars(arguments))) 100 print("\n" + "="*90) 101 102 103def confirmGitVersion(): 104 """ 105 Verify that the version of Git we're using is > 2.10 106 """ 107 git_version_string = subprocess.check_output(['git', '--version']) 108 git_version_number_string = git_version_string[git_version_string.rfind(' '):] 109 major_git_version = int(git_version_number_string[:git_version_number_string.find('.')]) 110 minor_git_version = int(git_version_number_string[git_version_number_string.find('.')+1: 111 git_version_number_string.rfind('.')]) 112 113 if major_git_version < 2 or (major_git_version == 2 and minor_git_version < 10): 114 raise SystemExit("Git version should be 2.10 or better - Exiting!") 115 else: 116 print(git_version_string) 117 118 return None 119 120 121 122# TODO: moduleMap & environMap should be moved into files. 123# Let's try YAML since it allows comments, etc. 124def setBuildEnviron(arguments): 125 """ 126 TODO: Needs explanation. 127 - How is environMap structured? 128 - How is moduleMap structured? 129 TODO: wcm: Could it be possible to offload environMap and moduleMap into a 130 JSON or Yaml file? (Yaml allows comments which is more helpful 131 than JSON IMO.) 132 """ 133 134 moduleMap = {"Trilinos_pullrequest_gcc_4.8.4": 135 ["sems-env", 136 "sems-git/2.10.1", 137 "sems-gcc/4.8.4", 138 "sems-openmpi/1.10.1", 139 "sems-python/2.7.9", 140 "sems-boost/1.63.0/base", 141 "sems-zlib/1.2.8/base", 142 "sems-hdf5/1.10.6/parallel", 143 "sems-netcdf/4.7.3/parallel", 144 "sems-parmetis/4.0.3/parallel", 145 "sems-scotch/6.0.3/nopthread_64bit_parallel", 146 "sems-superlu/4.3/base", 147 "sems-cmake/3.10.3", 148 "atdm-env", 149 "atdm-ninja_fortran/1.7.2"], 150 "Trilinos_pullrequest_gcc_4.9.3_SERIAL": 151 ["sems-env", 152 "sems-git/2.10.1", 153 "sems-gcc/4.9.3", 154 "sems-python/2.7.9", 155 "sems-boost/1.63.0/base", 156 "sems-zlib/1.2.8/base", 157 "sems-hdf5/1.10.6/base", 158 "sems-netcdf/4.7.3/base", 159 "sems-metis/5.1.0/base", 160 "sems-superlu/4.3/base", 161 "sems-cmake/3.10.3", 162 "atdm-env", 163 "atdm-ninja_fortran/1.7.2"], 164 "Trilinos_pullrequest_python_2": 165 ["sems-git/2.10.1", 166 "sems-gcc/7.2.0", 167 ("", "sems-python/2.7.9"), 168 "sems-cmake/3.10.3", 169 "atdm-env", 170 "atdm-ninja_fortran/1.7.2"], 171 "Trilinos_pullrequest_python_3": 172 ["sems-git/2.10.1", 173 "sems-gcc/7.2.0", 174 ("", "sems-python/2.7.9"), 175 "sems-cmake/3.10.3", 176 "atdm-env", 177 "atdm-ninja_fortran/1.7.2"], 178 "Trilinos_pullrequest_gcc_7.2.0": 179 ["sems-env", 180 "sems-git/2.10.1", 181 "sems-gcc/7.2.0", 182 "sems-openmpi/1.10.1", 183 "sems-python/2.7.9", 184 "sems-boost/1.63.0/base", 185 "sems-zlib/1.2.8/base", 186 "sems-hdf5/1.10.6/parallel", 187 "sems-netcdf/4.7.3/parallel", 188 "sems-parmetis/4.0.3/parallel", 189 "sems-scotch/6.0.3/nopthread_64bit_parallel", 190 "sems-superlu/4.3/base", 191 "sems-cmake/3.10.3", 192 "atdm-env", 193 "atdm-ninja_fortran/1.7.2"], 194 "Trilinos_pullrequest_gcc_7.2.0_debug": 195 ["sems-env", 196 "sems-git/2.10.1", 197 "sems-gcc/7.2.0", 198 "sems-openmpi/1.10.1", 199 "sems-python/2.7.9", 200 "sems-boost/1.63.0/base", 201 "sems-zlib/1.2.8/base", 202 "sems-hdf5/1.10.6/parallel", 203 "sems-netcdf/4.7.3/parallel", 204 "sems-parmetis/4.0.3/parallel", 205 "sems-scotch/6.0.3/nopthread_64bit_parallel", 206 "sems-superlu/4.3/base", 207 "sems-cmake/3.10.3", 208 "atdm-env", 209 "atdm-ninja_fortran/1.7.2"], 210 "Trilinos_pullrequest_gcc_8.3.0": 211 ["sems-env", 212 "sems-git/2.10.1", 213 "sems-gcc/8.3.0", 214 "sems-openmpi/1.10.1", 215 "sems-python/2.7.9", 216 "sems-boost/1.66.0/base", 217 "sems-zlib/1.2.8/base", 218 "sems-hdf5/1.10.6/parallel", 219 "sems-netcdf/4.7.3/parallel", 220 "sems-parmetis/4.0.3/parallel", 221 "sems-scotch/6.0.3/nopthread_64bit_parallel", 222 "sems-superlu/4.3/base", 223 "sems-cmake/3.17.1", 224 "sems-ninja_fortran/1.10.0", 225 "atdm-env" 226 ], 227 "Trilinos_pullrequest_intel_17.0.1": 228 ["sems-env", 229 "sems-git/2.10.1", 230 "sems-gcc/4.9.3", 231 "sems-intel/17.0.1", 232 "sems-mpich/3.2", 233 "sems-python/2.7.9", 234 "sems-boost/1.63.0/base", 235 "sems-zlib/1.2.8/base", 236 "sems-hdf5/1.10.6/parallel", 237 "sems-netcdf/4.7.3/parallel", 238 "sems-parmetis/4.0.3/parallel", 239 "sems-scotch/6.0.3/nopthread_64bit_parallel", 240 "sems-superlu/4.3/base", 241 "sems-cmake/3.10.3", 242 "atdm-env", 243 "atdm-ninja_fortran/1.7.2"], 244 "Trilinos_pullrequest_clang_7.0.1": 245 ["sems-env", 246 "sems-git/2.10.1", 247 "sems-gcc/5.3.0", 248 "sems-clang/7.0.1", 249 "sems-openmpi/1.10.1", 250 "sems-python/2.7.9", 251 "sems-boost/1.63.0/base", 252 "sems-zlib/1.2.8/base", 253 "sems-hdf5/1.10.6/parallel", 254 "sems-netcdf/4.7.3/parallel", 255 "sems-parmetis/4.0.3/parallel", 256 "sems-scotch/6.0.3/nopthread_64bit_parallel", 257 "sems-superlu/4.3/base", 258 "sems-cmake/3.12.2", 259 "atdm-env", 260 "atdm-ninja_fortran/1.7.2"], 261 "Trilinos_pullrequest_clang_9.0.0": 262 ["sems-env", 263 "sems-git/2.10.1", 264 "sems-gcc/5.3.0", 265 "sems-clang/9.0.0", 266 "sems-openmpi/1.10.1", 267 "sems-python/2.7.9", 268 "sems-boost/1.63.0/base", 269 "sems-zlib/1.2.8/base", 270 "sems-hdf5/1.10.6/parallel", 271 "sems-netcdf/4.7.3/parallel", 272 "sems-parmetis/4.0.3/parallel", 273 "sems-scotch/6.0.3/nopthread_64bit_parallel", 274 "sems-superlu/4.3/base", 275 "sems-cmake/3.12.2", 276 "atdm-env", 277 "atdm-ninja_fortran/1.7.2"], 278 "Trilinos_pullrequest_clang_10.0.0": 279 ["sems-env", 280 "sems-git/2.10.1", 281 "sems-gcc/5.3.0", 282 "sems-clang/10.0.0", 283 "sems-openmpi/1.10.1", 284 "sems-python/2.7.9", 285 "sems-boost/1.69.0/base", 286 "sems-zlib/1.2.8/base", 287 "sems-hdf5/1.10.6/parallel", 288 "sems-netcdf/4.7.3/parallel", 289 "sems-parmetis/4.0.3/parallel", 290 "sems-scotch/6.0.3/nopthread_64bit_parallel", 291 "sems-superlu/4.3/base", 292 "sems-cmake/3.17.1", 293 "sems-ninja_fortran/1.10.0"], 294 "Trilinos_pullrequest_cuda_9.2": 295 ["git/2.10.1", 296 "devpack/20180521/openmpi/2.1.2/gcc/7.2.0/cuda/9.2.88", 297 ("openblas/0.2.20/gcc/7.2.0", "netlib/3.8.0/gcc/7.2.0")]} 298 299 environMap = { 300 "Trilinos_pullrequest_gcc_4.8.4": 301 {"OMP_NUM_THREADS": "2"}, 302 "Trilinos_pullrequest_gcc_4.9.3_SERIAL": 303 {"OMP_NUM_THREADS": "2"}, 304 "Trilinos_pullrequest_python_2": 305 {"PYTHONPATH": 306 os.path.join(os.path.sep, 307 "projects", 308 "sierra", 309 "linux_rh7", 310 "install", 311 "Python", 312 "extras", 313 "lib", 314 "python2.7", 315 "site-packages"), 316 "MANPATH": 317 os.path.join(os.path.sep, 318 "projects", 319 "sierra", 320 "linux_rh7", 321 "install", 322 "Python", 323 "2.7.15", 324 "share", 325 "man"), 326 "PATH": os.path.join(os.path.sep, 327 "projects", 328 "sierra", 329 "linux_rh7", 330 "install", 331 "Python", 332 "2.7.15", 333 "bin") + os.pathsep + 334 os.path.join(os.path.sep, 335 "projects", 336 "sierra", 337 "linux_rh7", 338 "install", 339 "Python", 340 "extras" 341 "bin")}, 342 "Trilinos_pullrequest_python_3": 343 {"PYTHONPATH": 344 os.path.join(os.path.sep, 345 "projects", 346 "sierra", 347 "linux_rh7", 348 "install", 349 "Python", 350 "extras", 351 "lib", 352 "python3.6", 353 "site-packages"), 354 "MANPATH": 355 os.path.join(os.path.sep, 356 "projects", 357 "sierra", 358 "linux_rh7", 359 "install", 360 "Python", 361 "3.6.3", 362 "share", 363 "man"), 364 "PATH": os.path.join(os.path.sep, 365 "projects", 366 "sierra", 367 "linux_rh7", 368 "install", 369 "Python", 370 "3.6.3", 371 "bin") + os.pathsep + 372 os.path.join(os.path.sep, 373 "projects", 374 "sierra", 375 "linux_rh7", 376 "install", 377 "Python", 378 "extras" 379 "bin")}, 380 "Trilinos_pullrequest_gcc_7.2.0": 381 {"SEMS_FORCE_LOCAL_COMPILER_VERSION": "4.9.3", 382 "OMP_NUM_THREADS": "2"}, 383 "Trilinos_pullrequest_gcc_7.2.0_debug": 384 {"SEMS_FORCE_LOCAL_COMPILER_VERSION": "4.9.3", 385 "OMP_NUM_THREADS": "2"}, 386 "Trilinos_pullrequest_gcc_8.3.0": 387 {"SEMS_FORCE_LOCAL_COMPILER_VERSION": "4.9.3", 388 "OMP_NUM_THREADS": "2"}, 389 "Trilinos_pullrequest_intel_17.0.1": 390 {"SEMS_FORCE_LOCAL_COMPILER_VERSION": "4.9.3", 391 "OMP_NUM_THREADS": "2"}, 392 "Trilinos_pullrequest_clang_7.0.1": 393 {"SEMS_FORCE_LOCAL_COMPILER_VERSION": "5.3.0", 394 "OMP_NUM_THREADS": "2"}, 395 "Trilinos_pullrequest_clang_9.0.0": 396 {"SEMS_FORCE_LOCAL_COMPILER_VERSION": "5.3.0", 397 "OMP_NUM_THREADS": "2"}, 398 "Trilinos_pullrequest_clang_10.0.0": 399 {"SEMS_FORCE_LOCAL_COMPILER_VERSION": "5.3.0", 400 "OMP_NUM_THREADS": "2"}, 401 "Trilinos_pullrequest_cuda_9.2": 402 {"OMPI_CXX": 403 os.path.join(os.environ["WORKSPACE"], 404 "Trilinos", 405 "packages", 406 "kokkos", 407 "bin", 408 "nvcc_wrapper"), 409 "OMPI_CC": os.environ.get("CC", ""), 410 "OMPI_FC": os.environ.get("FC", ""), 411 "CUDA_LAUNCH_BLOCKING": "1", 412 "CUDA_MANAGED_FORCE_DEVICE_ALLOC": "1", 413 "PATH": os.path.join(os.path.sep, 414 "ascldap", 415 "users", 416 "rabartl", 417 "install", 418 "white-ride", 419 "cmake-3.11.2", 420 "bin") + os.pathsep + 421 os.path.join(os.path.sep, 422 "ascldap", 423 "users", 424 "rabartl", 425 "install", 426 "white-ride", 427 "ninja-1.8.2", 428 "bin")} 429 } 430 431 try: 432 moduleList = moduleMap[arguments.job_base_name] 433 l_environMap = environMap[arguments.job_base_name] 434 except KeyError: 435 sys.exit(dedent("""\ 436 ERROR: Unable to find matching environment for job: Trilinos_pullrequest_UNKOWN 437 Error code was: 42""")) 438 439 if 'sems-env' == moduleList[0]: 440 module('use', '/projects/sems/modulefiles/projects') 441 442 for mod in moduleList: 443 if isinstance(mod, str): 444 module('load', mod) 445 else: 446 unl_mod, load_mod = mod 447 if '' == unl_mod: 448 module('unload', load_mod) 449 else: 450 module('swap', unl_mod, load_mod) 451 452 if 'OMPI_CC' in l_environMap: 453 l_environMap['OMPI_CC'] = os.environ.get('CC', '') 454 455 if 'OMPI_FC' in l_environMap: 456 l_environMap['OMPI_FC'] = os.environ.get('FC', '') 457 458 for key, value in l_environMap.items(): 459 if key in os.environ: 460 # we are assuming these are paths to be prepended 461 os.environ[key] = str(value) + os.pathsep + os.environ[key] 462 else: 463 os.environ[key] = str(value) 464 465 confirmGitVersion() 466 467 print ("Environment:\n") 468 print(" pwd = {cwd}".format(cwd=os.getcwd())) 469 print("") 470 for key in os.environ: 471 print(key + ' = ' + os.environ[key], 472 file=sys.stdout) 473 474 print("\n"+"="*90) 475 print(module('list')) 476 477 return None 478 479 480def getCDashTrack(): 481 returnValue = 'Pull Request' 482 if 'PULLREQUEST_CDASH_TRACK' in os.environ: 483 returnValue = os.environ['PULLREQUEST_CDASH_TRACK'] 484 print('PULLREQUEST_CDASH_TRACK is set. Setting CDASH_TRACK={}'.format(returnValue) ) 485 returnValue = os.environ['PULLREQUEST_CDASH_TRACK'] 486 else: 487 print('PULLREQUEST_CDASH_TRACK isn\'t set, using default value') 488 489 return returnValue 490 491 492def get_memory_info(): 493 """ 494 Get memory information 495 496 Returns dictionary : ["mem_gb": <Gigabytes of Memory>, "mem_kb": <Kilobytes of Memory>] 497 """ 498 mem_kb = None 499 500 try: 501 # if psutil isn't there, it can be installed via `pip install psutil` 502 import psutil 503 mem_total = psutil.virtual_memory().total 504 mem_kb = mem_total/1024 505 except: 506 # If we can't load psutil then just look for /proc/meminfo 507 # - Note: /proc/meminfo assumes a unix/linux system and will fail on 508 # windows or OSX systems that don't have that file. 509 # The nearest OSX equivalent would be to run vm_stat and parse 510 # the output but this isn't a 100% analog. 511 try: 512 with open('/proc/meminfo') as f_ptr: 513 meminfo = dict((i.split()[0].rstrip(':'), int(i.split()[1])) for i in f_ptr.readlines()) 514 mem_kb = meminfo['MemTotal'] 515 except IOError: 516 raise IOError(dedent('''\ 517 Import psutil failed and /proc/meminfo not found. 518 Testing cannot proceed because we can't determine system information. 519 Try running '$ pip install psutil' 520 ''')) 521 522 output = {} 523 output["mem_kb"] = mem_kb 524 output["mem_gb"] = mem_kb / (1024*1024) 525 526 return output 527 528 529def compute_n(): 530 ''' 531 Given the default and the hardware environment determine the 532 number of processors to use 533 ''' 534 try: 535 environment_weight = int(os.environ['JENKINS_JOB_WEIGHT']) 536 except KeyError: 537 environment_weight = 29 538 539 requested_mem_per_core = 3.0 540 541 n_cpu = cpu_count() 542 543 mem = get_memory_info() 544 mem_kib = mem["mem_kb"] 545 mem_G = mem["mem_gb"] 546 547 number_possible_jobs = max(1, int(n_cpu/environment_weight)) 548 parallel_level = int(mem_G/(requested_mem_per_core*number_possible_jobs)) 549 550 if parallel_level > environment_weight: 551 parallel_level = environment_weight 552 553 return parallel_level 554 555 556def createPackageEnables(arguments): 557 """ 558 """ 559 enable_map = {'Trilinos_pullrequest_python_2': 'TrilinosFrameworkTests', 560 'Trilinos_pullrequest_python_3': 'TrilinosFrameworkTests'} 561 562 try: 563 if arguments.job_base_name not in enable_map: 564 subprocess.check_call([os.path.join(arguments.workspaceDir, 565 'Trilinos', 566 'commonTools', 567 'framework', 568 'get-changed-trilinos-packages.sh'), 569 os.path.join('origin', arguments.targetBranch), 570 'HEAD', 571 'packageEnables.cmake', 572 'package_subproject_list.cmake']) 573 else: 574 with open('packageEnables.cmake', 'w') as f_out: 575 f_out.write(dedent('''\ 576 MACRO(PR_ENABLE_BOOL VAR_NAME VAR_VAL) 577 MESSAGE("-- Setting ${VAR_NAME} = ${VAR_VAL}") 578 SET(${VAR_NAME} ${VAR_VAL} CACHE BOOL "Set in $CMAKE_PACKAGE_ENABLES_OUT") 579 ENDMACRO() 580 581 PR_ENABLE_BOOL(Trilinos_ENABLE_''' + enable_map[arguments.job_base_name] + ''' ON) 582 ''')) 583 with open ('package_subproject_list.cmake', 'w') as f_out: 584 f_out.write(dedent('''\ 585 set(CTEST_LABELS_FOR_SUBPROJECTS ''' + enable_map[arguments.job_base_name] + ''') 586 ''')) 587 print('Enabled packages:') 588 cmake_rstring = subprocess.check_output(['cmake', 589 '-P', 590 'packageEnables.cmake'], 591 stderr=subprocess.STDOUT) 592 if(sys.version_info.major != 3): 593 print(cmake_rstring) 594 else: 595 print(str(cmake_rstring, 'ASCII')) 596 except subprocess.CalledProcessError as cpe: 597 print('There was an issue generating packageEnables.cmake. ' 598 'The error code was: {}'.format(cpe.returncode)) 599 600 return None 601 602 603def validateSourceBranchIfDestBranchIsMaster(arguments): 604 """ 605 We only allow special branches to be merged into master. 606 These should be protected branches that not everyone can create. 607 This routine checks that the source branch name is matches this form: 608 - master_merge_YYYYMMDD_HHMMSS 609 610 Script will exit with nonzero exit code if this test fails. 611 """ 612 re_src_branchname = "master_merge_[0-9]{8}_[0-9]{6}" 613 if "master" == arguments.targetBranch: 614 if re.match(re_src_branchname, arguments.sourceBranch) is None: 615 # If destination is master and source isn't master_merge_YYYYMMDD_HHMMSS 616 # then we exit here with nonzero exit status. 617 sys.exit(dedent("""\ 618 ------------------------------------------------------------------------------------------ 619 NOTICE: Destination branch is trilinos/Trilnos::master 620 ERROR : Source branch is NOT trilinos/Trilinos::master_merge_YYYYMMDD_HHMMSS 621 : This violates Trilinos policy, pull requests into the master branch are restricted. 622 : Perhaps you forgot to specify the develop branch as the target in your PR? 623 ------------------------------------------------------------------------------------------ 624 """)) 625 else: 626 print(dedent("""\ 627 NOTICE: Source branch IS trilinos/Trilinos::{sourceBranch} 628 : This is allowed, proceeding with testing.""".format(**vars(arguments)) 629 ) 630 ) 631 else: 632 print(dedent("""\ 633 NOTICE: Destination branch is NOT trilinos/Trilinos::master" 634 : PR testing will proceed.""")) 635 636 return 0 637 638 639def generateBuildNameString(arguments): 640 """ 641 Generate the build name string 642 PR-<PR Number>-test-<Jenkins Job Name>-<Jenkins Build Number> 643 """ 644 output = "PR-{github_pr_number}-test-{job_base_name}-{job_number}".format(**vars(arguments)) 645 return output 646 647 648 649config_map = { 650 'Trilinos_pullrequest_gcc_4.8.4': 'PullRequestLinuxGCC4.8.4TestingSettings.cmake', 651 'Trilinos_pullrequest_intel_17.0.1': 'PullRequestLinuxIntelTestingSettings.cmake', 652 'Trilinos_pullrequest_gcc_4.9.3_SERIAL': 'PullRequestLinuxGCC4.9.3TestingSettingsSERIAL.cmake', 653 'Trilinos_pullrequest_gcc_7.2.0': 'PullRequestLinuxGCC7.2.0TestingSettings.cmake', 654 'Trilinos_pullrequest_gcc_8.3.0': 'PullRequestLinuxGCC8.3.0TestingSettings.cmake', 655 'Trilinos_pullrequest_clang_7.0.1': 'PullRequestLinuxClang7.0.1TestingSettings.cmake', 656 'Trilinos_pullrequest_clang_9.0.0': 'PullRequestLinuxClang9.0.0TestingSettings.cmake', 657 'Trilinos_pullrequest_clang_10.0.0': 'PullRequestLinuxClang10.0.0TestingSettings.cmake', 658 'Trilinos_pullrequest_cuda_9.2': 'PullRequestLinuxCuda9.2TestingSettings.cmake', 659 'Trilinos_pullrequest_python_2': 'PullRequestLinuxPython2.cmake', 660 'Trilinos_pullrequest_python_3': 'PullRequestLinuxPython3.cmake' 661 } 662 663 664 665def run(): 666 """ 667 Top level function to execute in this script. 668 """ 669 return_value = True 670 arguments = parse_args() 671 672 os.chdir(arguments.workspaceDir) 673 674 print_input_variables(arguments) 675 676 validateSourceBranchIfDestBranchIsMaster(arguments) 677 678 setBuildEnviron(arguments) 679 680 CDash_Track = getCDashTrack() 681 682 createPackageEnables(arguments) 683 684 parallel_level = compute_n() 685 686 if 'JENKINS_TEST_WEIGHT' in os.environ: 687 test_parallel_level = os.environ['JENKINS_TEST_WEIGHT'] 688 else: 689 test_parallel_level = parallel_level 690 691 build_name = generateBuildNameString(arguments) 692 693 config_script = config_map[arguments.job_base_name] 694 695 os.chdir('TFW_testing_single_configure_prototype') 696 print('Set CWD = {}'.format(os.getcwd())) 697 698 # Execute the call to ctest. 699 # - NOTE: simple_testing.cmake can be found in the TFW_single_configure_support_scripts 700 # repository. 701 subprocess.check_call(['ctest', '-S', 'simple_testing.cmake', 702 '-Dbuild_name={}'.format(build_name), 703 '-Dskip_by_parts_submit=OFF', 704 '-Dskip_update_step=ON', 705 '-Ddashboard_model=Experimental', 706 '-Ddashboard_track={}'.format(CDash_Track), 707 '-DPARALLEL_LEVEL={}'.format(parallel_level), 708 '-DTEST_PARALLEL_LEVEL={}'.format(test_parallel_level), 709 '-Dbuild_dir={}/pull_request_test'.format(arguments.workspaceDir), 710 '-Dconfigure_script=' + 711 os.path.join(arguments.workspaceDir, 712 'Trilinos', 713 'cmake', 714 'std', 715 config_script), 716 '-Dpackage_enables=../packageEnables.cmake', 717 '-Dsubprojects_file=../package_subproject_list.cmake']) 718 719 return return_value 720 721 722 723if __name__ == '__main__': # pragma nocover 724 returnValue = run() 725 if returnValue: 726 exit(0) 727 else: 728 exit(1) 729