diff --git a/apps/microtvm/reference-vm/README.md b/apps/microtvm/reference-vm/README.md index 7ef7900c3e05..7ff75c75b4f9 100644 --- a/apps/microtvm/reference-vm/README.md +++ b/apps/microtvm/reference-vm/README.md @@ -49,19 +49,19 @@ Reference VMs are organized as follows: ## Creating Releases -1. Build the base box for the given platform: `$ ./base-box-tool.py build ` +1. Build the base box for the given platform: `$ ./base-box-tool.py [--provider=] build ` 2. Run release tests for each platform: 1. Connect any needed hardware to the VM host machine. - 2. Run tests: `$ ./base-box-tool.py test [--test-device-serial=]`. This + 2. Run tests: `$ ./base-box-tool.py [--provider=] test [--microtvm-platform=] [--test-device-serial=]`. This command does the following for each provider: 1. Copies all files inside `./` except `.vagrant` and `base-box` to `./release-test`. This is done to avoid reusing any VM the developer may have started. - 2. Executes `$ vagrant up --provider=`. + 2. Executes `$ vagrant up [--provider=]`. 3. Finds an attached USB device matching the VID and PID specified in `test-config.json`, and if `--test-device-serial` was given, that serial number (as reported to USB). Creates a rule to autoconnect this device to the VM, and also attaches it to the VM> 4. SSHs to the VM, `cd` to the TVM root directory, and runs `test_cmd` from `test-config.json`. Nonzero status means failure. 3. If release tests fail, fix them and restart from step 1. -4. If release tests pass: `$ ./base-box-tool.py release `. Be sure you've logged +4. If release tests pass: `$ ./base-box-tool.py [--provider=] release <--release-version=> <--platform-version=> `. Be sure you've logged in to Vagrant Cloud using the `vagrant` tool. diff --git a/apps/microtvm/reference-vm/base-box-tool.py b/apps/microtvm/reference-vm/base-box-tool.py index fb7a9c0b5ce6..c22eff4cdbad 100755 --- a/apps/microtvm/reference-vm/base-box-tool.py +++ b/apps/microtvm/reference-vm/base-box-tool.py @@ -34,7 +34,6 @@ THIS_DIR = os.path.realpath(os.path.dirname(__file__) or ".") - # List of vagrant providers supported by this tool ALL_PROVIDERS = ( "parallels", @@ -46,8 +45,11 @@ ALL_MICROTVM_PLATFORMS = ( "stm32f746xx", "nrf5340dk", + "mps2_an521", ) +PACKER_FILE_NAME = "packer.json" + def parse_virtualbox_devices(): output = subprocess.check_output(["VBoxManage", "list", "usbhost"], encoding="utf-8") @@ -173,12 +175,21 @@ def attach_vmware(uuid, vid_hex=None, pid_hex=None, serial=None): "vmware_desktop": attach_vmware, } +# Extra scripts required to execute on provisioning +# in zephyr/base-box/base_box_provision.sh +EXTRA_SCRIPTS = ( + "docker/install/ubuntu_init_zephyr_project.sh", + "docker/install/ubuntu_install_qemu.sh", +) + def generate_packer_config(file_path, providers): builders = [] + provisioners = [] for provider_name in providers: builders.append( { + "name": f"{provider_name}", "type": "vagrant", "box_name": f"microtvm-base-{provider_name}", "output_dir": f"output-packer-{provider_name}", @@ -189,10 +200,26 @@ def generate_packer_config(file_path, providers): } ) + repo_root = subprocess.check_output( + ["git", "rev-parse", "--show-toplevel"], cwd=os.path.dirname(__file__), encoding="utf-8" + ).strip() + for script in EXTRA_SCRIPTS: + script_path = os.path.join(repo_root, script) + filename = os.path.basename(script_path) + provisioners.append({"type": "file", "source": script_path, "destination": f"~/{filename}"}) + + provisioners.append( + { + "type": "shell", + "script": "base_box_provision.sh", + } + ) + with open(file_path, "w") as f: json.dump( { "builders": builders, + "provisioners": provisioners, }, f, sort_keys=True, @@ -202,7 +229,7 @@ def generate_packer_config(file_path, providers): def build_command(args): generate_packer_config( - os.path.join(THIS_DIR, args.platform, "base-box", "packer.json"), + os.path.join(THIS_DIR, args.platform, "base-box", PACKER_FILE_NAME), args.provider or ALL_PROVIDERS, ) env = copy.copy(os.environ) @@ -212,7 +239,7 @@ def build_command(args): if args.debug_packer: packer_args += ["-debug"] - packer_args += ["packer.json"] + packer_args += [PACKER_FILE_NAME] subprocess.check_call( packer_args, cwd=os.path.join(THIS_DIR, args.platform, "base-box"), env=env ) @@ -221,7 +248,6 @@ def build_command(args): REQUIRED_TEST_CONFIG_KEYS = { "vid_hex": str, "pid_hex": str, - "test_cmd": list, } @@ -284,7 +310,6 @@ def do_build_release_test_vm(release_test_dir, user_box_dir, base_box_dir, provi return_code = subprocess.call(remove_args, cwd=release_test_dir) assert return_code in (0, 1), f'{" ".join(remove_args)} returned exit code {return_code}' subprocess.check_call(["vagrant", "up", f"--provider={provider_name}"], cwd=release_test_dir) - return True @@ -293,18 +318,30 @@ def do_run_release_test(release_test_dir, provider_name, test_config, test_devic os.path.join(release_test_dir, ".vagrant", "machines", "default", provider_name, "id") ) as f: machine_uuid = f.read() - ATTACH_USB_DEVICE[provider_name]( - machine_uuid, - vid_hex=test_config["vid_hex"], - pid_hex=test_config["pid_hex"], - serial=test_device_serial, - ) + + # Check if target is not QEMU + if test_config["vid_hex"] and test_config["pid_hex"]: + ATTACH_USB_DEVICE[provider_name]( + machine_uuid, + vid_hex=test_config["vid_hex"], + pid_hex=test_config["pid_hex"], + serial=test_device_serial, + ) tvm_home = os.path.realpath(os.path.join(THIS_DIR, "..", "..", "..")) def _quote_cmd(cmd): return " ".join(shlex.quote(a) for a in cmd) - test_cmd = _quote_cmd(["cd", tvm_home]) + " && " + _quote_cmd(test_config["test_cmd"]) + test_cmd = ( + _quote_cmd(["cd", tvm_home]) + + " && " + + _quote_cmd( + [ + "apps/microtvm/reference-vm/zephyr/base-box/base_box_test.sh", + test_config["microtvm_platform"], + ] + ) + ) subprocess.check_call(["vagrant", "ssh", "-c", f"bash -ec '{test_cmd}'"], cwd=release_test_dir) @@ -325,6 +362,7 @@ def test_command(args): microtvm_test_platform["vid_hex"] = microtvm_test_platform["vid_hex"].lower() microtvm_test_platform["pid_hex"] = microtvm_test_platform["pid_hex"].lower() + microtvm_test_platform["microtvm_platform"] = args.microtvm_platform providers = args.provider provider_passed = {p: False for p in providers} @@ -399,18 +437,18 @@ def parse_args(): description="Automates building, testing, and releasing a base box" ) subparsers = parser.add_subparsers(help="Action to perform.") - parser.add_argument( - "platform", - help="Name of the platform VM to act on. Must be a sub-directory of this directory.", - ) parser.add_argument( "--provider", choices=ALL_PROVIDERS, action="append", - default=list(ALL_PROVIDERS), help="Name of the provider or providers to act on; if not specified, act on all.", ) + parser.add_argument( + "platform", + help="Name of the platform VM to act on. Must be a sub-directory of this directory.", + ) + parser_build = subparsers.add_parser("build", help="Build a base box.") parser_build.set_defaults(func=build_command) parser_test = subparsers.add_parser("test", help="Test a base box before release.") diff --git a/apps/microtvm/reference-vm/zephyr/Vagrantfile b/apps/microtvm/reference-vm/zephyr/Vagrantfile index 2778d7ca8a49..be41c0b733e5 100644 --- a/apps/microtvm/reference-vm/zephyr/Vagrantfile +++ b/apps/microtvm/reference-vm/zephyr/Vagrantfile @@ -46,7 +46,7 @@ Vagrant.configure("2") do |config| end end - config.vm.provision "shell", path: "setup.sh", env: {"TVM_HOME": dirs_to_mount[0]}, privileged: false + config.vm.provision "shell", path: "provision_setup.sh", env: {"TVM_HOME": dirs_to_mount[0]}, privileged: false # Enable USB Controller on VirtualBox vm_name = "microtvm-#{Time.now.tv_sec}" diff --git a/apps/microtvm/reference-vm/zephyr/base-box/Vagrantfile.packer-template b/apps/microtvm/reference-vm/zephyr/base-box/Vagrantfile.packer-template index 38f9a20b56cf..b43596bb83c1 100644 --- a/apps/microtvm/reference-vm/zephyr/base-box/Vagrantfile.packer-template +++ b/apps/microtvm/reference-vm/zephyr/base-box/Vagrantfile.packer-template @@ -41,7 +41,7 @@ Vagrant.configure("2") do |config| config.vm.provision "shell", inline: "touch ~/skip_zeroing_disk", privileged: false {{- end}} - # NOTE: setup.sh resides in the parent directory (../) because this template is expanded into a + # NOTE: base_box_setup.sh resides in the parent directory (../) because this template is expanded into a # sub-directory of base-box (output-packer-*). - config.vm.provision "shell", path: "../setup.sh", privileged: false + config.vm.provision "shell", path: "../base_box_setup.sh", privileged: false end diff --git a/apps/microtvm/reference-vm/zephyr/base-box/base_box_provision.sh b/apps/microtvm/reference-vm/zephyr/base-box/base_box_provision.sh new file mode 100644 index 000000000000..69e6171d06dd --- /dev/null +++ b/apps/microtvm/reference-vm/zephyr/base-box/base_box_provision.sh @@ -0,0 +1,37 @@ +#!/bin/bash -e +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# Using this script we can reuse docker/install scripts to configure the reference +# virtual machine similar to CI QEMU setup. +# + +set -e +set -x + +source ~/.profile + +# Init Zephyr +cd ~ +# Using most recent commit that passes all the tests. +~/ubuntu_init_zephyr_project.sh ~/zephyr v2.5-branch --commit dabf23758417fd041fec2a2a821d8f526afac29d + +# Build QEMU +sudo ~/ubuntu_install_qemu.sh --target-list arm-softmmu + +# Cleanup +rm -f *.sh diff --git a/apps/microtvm/reference-vm/zephyr/base-box/setup.sh b/apps/microtvm/reference-vm/zephyr/base-box/base_box_setup.sh similarity index 97% rename from apps/microtvm/reference-vm/zephyr/base-box/setup.sh rename to apps/microtvm/reference-vm/zephyr/base-box/base_box_setup.sh index 8f7ed41af337..e8385af9f663 100644 --- a/apps/microtvm/reference-vm/zephyr/base-box/setup.sh +++ b/apps/microtvm/reference-vm/zephyr/base-box/base_box_setup.sh @@ -17,6 +17,7 @@ # under the License. set -e +set -x skip_zeroing_disk=0 if [ -e "$HOME/skip_zeroing_disk" ]; then @@ -81,8 +82,6 @@ pip3 install --user -U west echo 'export PATH=$HOME/.local/bin:"$PATH"' >> ~/.profile source ~/.profile echo PATH=$PATH -REPO_ROOT=$(git rev-parse --show-toplevel) -${REPO_ROOT}/docker/install/ubuntu_init_zephyr_project.sh ~/zephyr v2.5.0 cd ~ echo "Downloading zephyr SDK..." diff --git a/apps/microtvm/reference-vm/zephyr/base-box/base_box_test.sh b/apps/microtvm/reference-vm/zephyr/base-box/base_box_test.sh new file mode 100755 index 000000000000..8eba63e9e331 --- /dev/null +++ b/apps/microtvm/reference-vm/zephyr/base-box/base_box_test.sh @@ -0,0 +1,39 @@ +#!/bin/bash -e +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# Usage: base_box_test.sh +# Execute microTVM Zephyr tests. +# + +set -e +set -x + +if [ "$#" -lt 1 ]; then + echo "Usage: base_box_test.sh " + exit -1 +fi + +microtvm_platform=$1 + +pytest tests/micro/zephyr/test_zephyr.py --microtvm-platforms=${microtvm_platform} + +if [ $microtvm_platform == "stm32f746xx" ]; then + echo "NOTE: skipped test_zephyr_aot.py on $microtvm_platform -- known failure" +else + pytest tests/micro/zephyr/test_zephyr_aot.py --microtvm-platforms=${microtvm_platform} +fi diff --git a/apps/microtvm/reference-vm/zephyr/base-box/test-config.json b/apps/microtvm/reference-vm/zephyr/base-box/test-config.json index 1a39d34c7e64..48b6915a10f4 100644 --- a/apps/microtvm/reference-vm/zephyr/base-box/test-config.json +++ b/apps/microtvm/reference-vm/zephyr/base-box/test-config.json @@ -1,12 +1,14 @@ { "stm32f746xx": { "vid_hex": "0483", - "pid_hex": "374b", - "test_cmd": ["pytest", "tests/micro/zephyr/test_zephyr.py", "--microtvm-platforms=stm32f746xx"] + "pid_hex": "374b" }, "nrf5340dk": { "vid_hex": "1366", - "pid_hex": "1055", - "test_cmd": ["pytest", "tests/micro/zephyr/test_zephyr.py", "--microtvm-platforms=nrf5340dk"] + "pid_hex": "1055" + }, + "mps2_an521": { + "vid_hex": "", + "pid_hex": "" } } diff --git a/apps/microtvm/reference-vm/zephyr/setup.sh b/apps/microtvm/reference-vm/zephyr/provision_setup.sh similarity index 95% rename from apps/microtvm/reference-vm/zephyr/setup.sh rename to apps/microtvm/reference-vm/zephyr/provision_setup.sh index e0f382cfc23e..f95c7e24f5aa 100644 --- a/apps/microtvm/reference-vm/zephyr/setup.sh +++ b/apps/microtvm/reference-vm/zephyr/provision_setup.sh @@ -24,6 +24,7 @@ cd "${TVM_HOME}" apps/microtvm/reference-vm/zephyr/rebuild-tvm.sh +# Build poetry cd apps/microtvm/reference-vm/zephyr poetry env use 3.6 @@ -41,7 +42,7 @@ echo "downloaded and cached for future use." echo "------------------------------[ TVM Message ]------------------------------" poetry lock -vvv poetry install -poetry run pip3 install -r ~/zephyr/zephyr/scripts/requirements.txt +poetry run pip3 install -r ${ZEPHYR_BASE}/scripts/requirements.txt echo "export TVM_LIBRARY_PATH=\"$TVM_HOME\"/build-microtvm" >>~/.profile echo "VENV_PATH=\$((cd \"$TVM_HOME\"/apps/microtvm/reference-vm/zephyr && poetry env list --full-path) | sed -E 's/^(.*)[[:space:]]\(Activated\)\$/\1/g')" >>~/.profile diff --git a/apps/microtvm/reference-vm/zephyr/rebuild-tvm.sh b/apps/microtvm/reference-vm/zephyr/rebuild-tvm.sh index 2eb55e385520..1cebcf7166af 100755 --- a/apps/microtvm/reference-vm/zephyr/rebuild-tvm.sh +++ b/apps/microtvm/reference-vm/zephyr/rebuild-tvm.sh @@ -18,6 +18,14 @@ set -e +# Get number of cores for build +if [ -n "${TVM_CI_NUM_CORES}" ]; then + num_cores=${TVM_CI_NUM_CORES} +else + # default setup for Vagrantfile + num_cores=2 +fi + cd "$(dirname $0)" cd "$(git rev-parse --show-toplevel)" BUILD_DIR=build-microtvm @@ -32,4 +40,4 @@ sed -i 's/USE_GRAPH_EXECUTOR_DEBUG OFF/USE_GRAPH_EXECUTOR_DEBUG ON/' config.cmak sed -i 's/USE_LLVM OFF/USE_LLVM ON/' config.cmake cmake .. rm -rf standalone_crt host_standalone_crt # remove stale generated files -make -j4 +make -j${num_cores} diff --git a/docker/install/ubuntu_init_zephyr_project.sh b/docker/install/ubuntu_init_zephyr_project.sh index 2116a4d981f5..573ff30c38a8 100755 --- a/docker/install/ubuntu_init_zephyr_project.sh +++ b/docker/install/ubuntu_init_zephyr_project.sh @@ -16,10 +16,35 @@ # specific language governing permissions and limitations # under the License. +# +# Initialize Zephyr Project. +# +# Usage: ubuntu_init_zephyr_project.sh path branch [--commit hash] +# path is the installation path for the repository. +# branch is the zephyr branch. +# --commit is the commit hash number of zephyrproject repository. If not specified, it uses the latest commit. +# + +set -x + DOWNLOAD_DIR=$1 -ZEPHYR_BRANCH=$2 +shift +ZEPHYR_BRANCH=$1 +shift + +commit_hash= +if [ "$1" == "--commit" ]; then + shift + commit_hash=$1 +fi west init --mr ${ZEPHYR_BRANCH} ${DOWNLOAD_DIR} + +if [ -n "$commit_hash" ]; then + cd ${DOWNLOAD_DIR}/zephyr + git checkout ${commit_hash} +fi + cd ${DOWNLOAD_DIR} west update west zephyr-export diff --git a/docker/install/ubuntu_install_qemu.sh b/docker/install/ubuntu_install_qemu.sh index ad4037a34187..b1d375253e05 100755 --- a/docker/install/ubuntu_install_qemu.sh +++ b/docker/install/ubuntu_install_qemu.sh @@ -26,6 +26,13 @@ set -e set -o pipefail +QEMU_NAME=qemu-5.1.0 +QEMU_SIG_FILE=${QEMU_NAME}.tar.xz.sig +QEMU_TAR_FILE=${QEMU_NAME}.tar.xz + +# Clean previous build +rm -rf ${QEMU_NAME} ${QEMU_SIG_FILE} ${QEMU_TAR_FILE} + # Get number of cores for build if [ -n "${TVM_CI_NUM_CORES}" ]; then num_cores=${TVM_CI_NUM_CORES} @@ -62,10 +69,11 @@ p5ez/+2k4VAIwIQoP5DoO06waLBffvLIAdPPKYsx71K67OoGG2svc7duC/+5qf1x -----END PGP ARMORED FILE----- EOF curl -OLs https://download.qemu.org/qemu-5.1.0.tar.xz -gpg --verify qemu-5.1.0.tar.xz.sig +gpg --verify ${QEMU_SIG_FILE} + +tar -xf ${QEMU_TAR_FILE} -tar -xf qemu-5.1.0.tar.xz -cd qemu-5.1.0 +cd ${QEMU_NAME} ./configure --target-list=${target_list} make -j${num_cores} sudo make install