From 55635f9d042b5dfd3c338eca051117b1d0e5bbbf Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Tue, 24 Apr 2018 17:47:35 -0400 Subject: [PATCH] [Arm64/Ubuntu] match arm32 except triggers --- netci.groovy | 101 ++++++++++++++++++++++---------------- tests/scripts/run-corefx-tests.py | 29 ++--------- 2 files changed, 65 insertions(+), 65 deletions(-) diff --git a/netci.groovy b/netci.groovy index 27c353d..3bbe4c5 100755 --- a/netci.groovy +++ b/netci.groovy @@ -323,14 +323,6 @@ class Constants { 'gcstress0xc_jitstressregs0x1000': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"] ] - def static validLinuxArm64Scenarios = [ - 'innerloop', - 'normal', - 'r2r', - 'gcstress0x3', - 'gcstress0xc' - ] - def static validLinuxArmScenarios = [ 'innerloop', 'normal', @@ -620,9 +612,14 @@ def static setMachineAffinity(def job, def os, def architecture, def options = n assert os in supportedArmLinuxOs if (architecture == 'arm64') { - if ((options != null) && (options['is_build_only'] == true)) { - // Arm64 Linux build machine - Utilities.setMachineAffinity(job, os, 'arm64-cross-latest') + assert (architecture == 'arm64') && (os == 'Ubuntu') + def isFlow = (options != null) && (options['is_flow_job'] == true) + def isBuild = (options != null) && (options['is_build_job'] == true) + if (isFlow || isBuild) { + // Arm64 Ubuntu build machine. Build uses docker, so the actual host OS is not + // very important. Therefore, use latest or auto. Flow jobs don't need to use + // Arm64 hardware. + Utilities.setMachineAffinity(job, 'Ubuntu16.04', 'latest-or-auto') } else { // Arm64 Linux test machines if ((options != null) && (options['large_pages'] == true)) { @@ -686,7 +683,9 @@ def static setJobMachineAffinity(def architecture, def os, def isBuildJob, def i else { if (architecture == 'arm64') { if (isBuildJob) { - affinityOptions = ['is_build_only': true] + affinityOptions = ['is_build_job': true] + } else if (isFlowJob) { + affinityOptions = ['is_flow_job': true] } else if (isTestJob) { affinityOptions = [ "large_pages" : false ] } @@ -990,6 +989,11 @@ def static isNeedDocker(def architecture, def os, def isBuild) { return true } } + else if (architecture == 'arm64') { + if (os == 'Ubuntu') { + return true + } + } } else { if (architecture == 'x86' && os == 'Ubuntu') { @@ -1021,6 +1025,11 @@ def static getDockerImageName(def architecture, def os, def isBuild) { return "microsoft/dotnet-buildtools-prereqs:ubuntu-14.04-cross-e435274-20180426002420" } } + else if (architecture == 'arm64') { + if (os == 'Ubuntu') { + return "microsoft/dotnet-buildtools-prereqs:ubuntu-16.04-cross-arm64-a3ae44b-20180315221921" + } + } } else { if (architecture == 'x86' && os == 'Ubuntu') { @@ -1043,6 +1052,10 @@ def static jobRequiresLimitedHardware(def architecture, def os) { // These test jobs require Linux/arm32 hardware return true } + else if ((architecture == 'arm64') && (os == 'Ubuntu')) { + // These test jobs require Linux/arm64 hardware + return true + } else { return false } @@ -1119,6 +1132,11 @@ def static addNonPRTriggers(def job, def branch, def isPR, def architecture, def return } + // No arm64 Ubuntu cron jobs for now: we don't have enough hardware. + if ((architecture == 'arm64') && (os != 'Windows_NT')) { + return + } + // Check scenario. switch (scenario) { case 'innerloop': @@ -1146,7 +1164,7 @@ def static addNonPRTriggers(def job, def branch, def isPR, def architecture, def else { // Only the flow jobs get push triggers; the build and test jobs are triggered by the flow job. if (isFlowJob) { - addPeriodicTriggerHelper(job, "H H/4 * * *") + addPeriodicTriggerHelper(job, '@daily') } } break @@ -1380,6 +1398,9 @@ def static addNonPRTriggers(def job, def branch, def isPR, def architecture, def if ((architecture == 'arm') && isCoreFxScenario(scenario) && !isFlowJob) { break } + if ((architecture == 'arm64') && isCoreFxScenario(scenario) && !isFlowJob) { + break + } assert (os == 'Windows_NT') || (os in Constants.crossList) if (jobRequiresLimitedHardware(architecture, os)) { addPeriodicTriggerHelper(job, '@weekly') @@ -2415,20 +2436,6 @@ def static calculateBuildCommands(def newJob, def scenario, def branch, def isPR Utilities.addXUnitDotNETResults(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml") } break - case 'arm64': - if (!doCoreFxTesting) { - buildCommands += "ROOTFS_DIR=/opt/arm64-xenial-rootfs ./build.sh ${lowerConfiguration} ${architecture} cross crosscomponent clang3.8" - - // HACK -- Arm64 does not have corefx jobs yet. - buildCommands += "git clone https://github.com/dotnet/corefx fx" - buildCommands += "ROOTFS_DIR=/opt/arm64-xenial-rootfs-corefx ./fx/build-native.sh -release -buildArch=arm64 -- verbose cross clang3.8" - buildCommands += "mkdir ./bin/Product/Linux.arm64.${configuration}/corefxNative" - buildCommands += "cp fx/bin/Linux.arm64.Release/native/* ./bin/Product/Linux.arm64.${configuration}/corefxNative" - - // Basic archiving of the build - Utilities.addArchival(newJob, "bin/Product/**,bin/obj/*/tests/**/*.dylib,bin/obj/*/tests/**/*.so", "bin/Product/**/.nuget/**") - } - break case 'armem': // Emulator cross builds for ARM runs on Ubuntu, Ubuntu16.04 and Tizen currently assert (os == 'Ubuntu') || (os == 'Ubuntu16.04') || (os == 'Tizen') @@ -2472,6 +2479,7 @@ def static calculateBuildCommands(def newJob, def scenario, def branch, def isPR // Basic archiving of the build, no pal tests Utilities.addArchival(newJob, "bin/Product/**,bin/obj/*/tests/**/*.dylib,bin/obj/*/tests/**/*.so", "bin/Product/**/.nuget/**") break + case 'arm64': case 'arm': // Non-Windows ARM cross builds on hardware run on Ubuntu only assert (os == 'Ubuntu') @@ -2479,6 +2487,11 @@ def static calculateBuildCommands(def newJob, def scenario, def branch, def isPR // Add some useful information to the log file. Ignore return codes. buildCommands += "uname -a || true" + def additionalOpts = "" + if (architecture == 'arm') { + additionalOpts = "-e CAC_ROOTFS_DIR=/crossrootfs/x86" + } + // Cross build the Ubuntu/arm product using docker with a docker image that contains the correct // Ubuntu cross-compilation toolset (running on a Ubuntu x64 host). // For CoreFX testing, we only need the product build; we don't need to generate the layouts. The product @@ -2486,7 +2499,7 @@ def static calculateBuildCommands(def newJob, def scenario, def branch, def isPR // ZIP up the generated CoreFX runtime and tests. def dockerImage = getDockerImageName(architecture, os, true) - def dockerCmd = "docker run -i --rm -v \${WORKSPACE}:\${WORKSPACE} -w \${WORKSPACE} -e ROOTFS_DIR=/crossrootfs/arm -e CAC_ROOTFS_DIR=/crossrootfs/x86 ${dockerImage} " + def dockerCmd = "docker run -i --rm -v \${WORKSPACE}:\${WORKSPACE} -w \${WORKSPACE} -e ROOTFS_DIR=/crossrootfs/${architecture} ${additionalOpts} ${dockerImage} " buildCommands += "${dockerCmd}\${WORKSPACE}/build.sh ${lowerConfiguration} ${architecture} cross crosscomponent" @@ -2528,8 +2541,8 @@ def static calculateBuildCommands(def newJob, def scenario, def branch, def isPR // used by runtest.sh as the "--testNativeBinDir" argument. // These commands are assumed to be run from the root of the workspace. - buildCommands += "zip -r coreroot.${lowerConfiguration}.zip ./bin/tests/Linux.arm.${configuration}/Tests/Core_Root" - buildCommands += "zip -r testnativebin.${lowerConfiguration}.zip ./bin/obj/Linux.arm.${configuration}/tests" + buildCommands += "zip -r coreroot.${lowerConfiguration}.zip ./bin/tests/Linux.${architecture}.${configuration}/Tests/Core_Root" + buildCommands += "zip -r testnativebin.${lowerConfiguration}.zip ./bin/obj/Linux.${architecture}.${configuration}/tests" Utilities.addArchival(newJob, "coreroot.${lowerConfiguration}.zip,testnativebin.${lowerConfiguration}.zip", "") } @@ -2642,7 +2655,7 @@ def static shouldGenerateJob(def scenario, def isPR, def architecture, def confi return false } - def isEnabledOS = (os == 'Windows_NT') || (os == 'Ubuntu' && architecture == 'arm') || (os == 'Ubuntu' && isCoreFxScenario(scenario)) + def isEnabledOS = (os == 'Windows_NT') || (os == 'Ubuntu' && (isCoreFxScenario(scenario) || architecture == 'arm' || architecture == 'arm64')) if (!isEnabledOS) { return false } @@ -2677,6 +2690,17 @@ def static shouldGenerateJob(def scenario, def isPR, def architecture, def confi } break + case 'arm64': + if (os == 'Windows_NT') { + return false + } + else { + if (!isCoreFxScenario(scenario)) { + return false + } + } + break + default: // arm64, armlb: stress is handled through flow jobs. // armem: no stress jobs for ARM emulator. @@ -3101,7 +3125,7 @@ def static CreateWindowsArmTestJob(def dslFactory, def project, def architecture // Returns the newly created job. def static CreateOtherTestJob(def dslFactory, def project, def branch, def architecture, def os, def configuration, def scenario, def isPR, def inputCoreCLRBuildName, def inputTestsBuildName) { - def isUbuntuArmJob = ((os == "Ubuntu") && (architecture == 'arm')) // ARM Ubuntu running on hardware (not emulator) + def isUbuntuArmJob = (os == "Ubuntu") && ((architecture == 'arm') || (architecture == 'arm64')) // ARM Ubuntu running on hardware (not emulator) def doCoreFxTesting = isCoreFxScenario(scenario) def workspaceRelativeFxRootLinux = "_/fx" // only used for CoreFX testing @@ -3247,12 +3271,7 @@ def static CreateOtherTestJob(def dslFactory, def project, def branch, def archi shell("uname -a || true") } - if (architecture == 'arm64') { - shell("mkdir -p ./bin/CoreFxBinDir") - shell("cp ./bin/Product/Linux.arm64.${configuration}/corefxNative/* ./bin/CoreFxBinDir") - shell("chmod +x ./bin/Product/Linux.arm64.${configuration}/corerun") - } - else if (architecture == 'x86') { + if (architecture == 'x86') { shell("mkdir ./bin/CoreFxNative") def fxBranch = getFxBranch(branch) @@ -3288,8 +3307,8 @@ def static CreateOtherTestJob(def dslFactory, def project, def branch, def archi if (!doCoreFxTesting) { if (isUbuntuArmJob) { def lowerConfiguration = configuration.toLowerCase() - shell("unzip -o ./coreroot.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/tests/Linux.arm.${configuration}/Tests/Core_Root - shell("unzip -o ./testnativebin.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/obj/Linux.arm.${configuration}/tests + shell("unzip -o ./coreroot.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/tests/Linux.${architecture}.${configuration}/Tests/Core_Root + shell("unzip -o ./testnativebin.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/obj/Linux.${architecture}.${configuration}/tests } else { shell("./build-test.sh ${architecture} ${configuration} generatelayoutonly") @@ -3524,7 +3543,7 @@ def static shouldGenerateFlowJob(def scenario, def isPR, def architecture, def c else { // Non-Windows if (architecture == 'arm64') { - if (!(scenario in Constants.validLinuxArm64Scenarios)) { + if (!(scenario in Constants.validLinuxArmScenarios)) { return false } } diff --git a/tests/scripts/run-corefx-tests.py b/tests/scripts/run-corefx-tests.py index b7af2ca..4acd5d2 100644 --- a/tests/scripts/run-corefx-tests.py +++ b/tests/scripts/run-corefx-tests.py @@ -307,6 +307,11 @@ def main(args): # (there doesn't appear to be a way to pass these individually). build_native_args = '-AdditionalArgs:"-portable -cross" -Clang:clang5.0' + if not Is_windows and arch == 'arm64' : + # We need to pass "-cross", but we also pass "-portable", which build-native.sh normally + # passes (there doesn't appear to be a way to pass these individually). + build_native_args = '-AdditionalArgs:"-portable -cross"' + command = ' '.join(('build-native.cmd' if Is_windows else './build-native.sh', config_args, build_native_args)) @@ -321,14 +326,6 @@ def main(args): if returncode != 0: sys.exit(1) - if not Is_windows and arch == 'arm64' : - # Rename runtime to arm64 - os.rename(os.path.join(fx_root,'bin','runtime', 'netcoreapp-%s-%s-%s' % (clr_os, 'Release', 'x64')), - os.path.join(fx_root,'bin','runtime', 'netcoreapp-%s-%s-%s' % (clr_os, 'Release', 'arm64'))) - - os.rename(os.path.join(fx_root,'bin','testhost', 'netcoreapp-%s-%s-%s' % (clr_os, 'Release', 'x64')), - os.path.join(fx_root,'bin','testhost', 'netcoreapp-%s-%s-%s' % (clr_os, 'Release', 'arm64'))) - # Override the built corefx runtime (which it picked up by copying from packages determined # by its dependencies.props file). Note that we always build Release corefx. # We must copy all files, not just the files that already exist in the corefx runtime @@ -347,22 +344,6 @@ def main(args): log('Updating CoreCLR: %s => %s' % (core_root, fx_runtime)) copy_files(core_root, fx_runtime) - if not Is_windows and arch == 'arm64' : - fx_arm64_native = os.path.join(fx_root, - 'bin', - '%s.%s.%s' % (clr_os, 'arm64', 'Release'), - 'native') - log('Copying CoreFx Arm64 Native libraries: %s => %s' % (fx_arm64_native, fx_runtime)) - copy_files(fx_arm64_native, fx_runtime) - - # Replace dotnet binary with corerun softlink, to make run-test.sh work as is on ARM64 platform - # with the built runtime. - dotnet_base= os.path.join(fx_root,'bin','testhost', 'netcoreapp-%s-%s-%s' % (clr_os, 'Release', arch)) - os.remove(os.path.join(dotnet_base,'dotnet')) - os.chdir(dotnet_base) - os.symlink(os.path.join('shared','Microsoft.NETCore.App','9.9.9','corerun'), 'dotnet') - os.chdir(fx_root) - # Build the build-tests command line. if Is_windows: -- 2.7.4