ci: add runtime testing on glinet-b1300 device
authorPetr Štetiar <ynezz@true.cz>
Sun, 26 Jun 2022 17:48:48 +0000 (19:48 +0200)
committerPetr Štetiar <ynezz@true.cz>
Thu, 25 Aug 2022 20:08:13 +0000 (22:08 +0200)
Signed-off-by: Petr Štetiar <ynezz@true.cz>
82 files changed:
.gitlab-ci.yml
.gitlab/README.md [new file with mode: 0644]
.gitlab/docker.yml [new file with mode: 0644]
.gitlab/docker/README.md [new file with mode: 0644]
.gitlab/docker/testbed/Dockerfile [new file with mode: 0644]
.gitlab/docker/testbed/gitlab.yml [new file with mode: 0644]
.gitlab/prebuild.yml [new file with mode: 0644]
.gitlab/scripts/README.md [new file with mode: 0644]
.gitlab/scripts/testbed-device.py [new file with mode: 0755]
.gitlab/testbed.yml [new file with mode: 0644]
.gitlab/testbed/archer-c7-v5.yml [new file with mode: 0644]
.gitlab/testbed/glinet-b1300.yml [new file with mode: 0644]
.gitlab/testbed/tplink-c6v2.yml [new file with mode: 0644]
.gitlab/testbed/turris-omnia.yml [new file with mode: 0644]
.gitlab/tests/README.md [new file with mode: 0644]
.gitlab/tests/cram/README.md [new file with mode: 0644]
.gitlab/tests/cram/generic/README.md [new file with mode: 0644]
.gitlab/tests/cram/generic/arch/README.md [new file with mode: 0644]
.gitlab/tests/cram/generic/arch/ath79/010-ubus.t [new file with mode: 0644]
.gitlab/tests/cram/generic/arch/ath79_generic [new symlink]
.gitlab/tests/cram/generic/arch/ipq40xx/010-ubus.t [new file with mode: 0644]
.gitlab/tests/cram/generic/arch/ipq40xx_generic [new symlink]
.gitlab/tests/cram/generic/arch/mvebu/010-ubus.t [new file with mode: 0644]
.gitlab/tests/cram/generic/arch/mvebu_cortexa9 [new symlink]
.gitlab/tests/cram/generic/board/README.md [new file with mode: 0644]
.gitlab/tests/cram/generic/board/archer-c7-v5/010-ubus.t [new file with mode: 0644]
.gitlab/tests/cram/generic/board/archer-c7-v5/020-network.t [new file with mode: 0644]
.gitlab/tests/cram/generic/board/archer-c7-v5_releases_19.07-SNAPSHOT [new symlink]
.gitlab/tests/cram/generic/board/archer-c7-v5_releases_21.02-SNAPSHOT [new symlink]
.gitlab/tests/cram/generic/board/archer-c7-v5_releases_22.03-SNAPSHOT [new symlink]
.gitlab/tests/cram/generic/board/archer-c7-v5_snapshots [new symlink]
.gitlab/tests/cram/generic/board/glinet-b1300/010-ubus.t [new file with mode: 0644]
.gitlab/tests/cram/generic/board/glinet-b1300/020-network.t [new file with mode: 0644]
.gitlab/tests/cram/generic/board/glinet-b1300_releases_19.07-SNAPSHOT [new symlink]
.gitlab/tests/cram/generic/board/glinet-b1300_releases_21.02-SNAPSHOT [new symlink]
.gitlab/tests/cram/generic/board/glinet-b1300_releases_22.03-SNAPSHOT [new symlink]
.gitlab/tests/cram/generic/board/glinet-b1300_snapshots [new symlink]
.gitlab/tests/cram/generic/board/turris-omnia/010-ubus.t [new file with mode: 0644]
.gitlab/tests/cram/generic/board/turris-omnia/020-network.t [new file with mode: 0644]
.gitlab/tests/cram/generic/board/turris-omnia_releases_19.07-SNAPSHOT/020-network.t [new file with mode: 0644]
.gitlab/tests/cram/generic/board/turris-omnia_releases_21.02-SNAPSHOT [new symlink]
.gitlab/tests/cram/generic/board/turris-omnia_releases_22.03-SNAPSHOT [new symlink]
.gitlab/tests/cram/generic/board/turris-omnia_snapshots/020-network.t [new file with mode: 0644]
.gitlab/tests/cram/generic/build/README.md [new file with mode: 0644]
.gitlab/tests/cram/generic/build/generic/.keep [new file with mode: 0644]
.gitlab/tests/cram/generic/build/releases_19.07-SNAPSHOT/.keep [new file with mode: 0644]
.gitlab/tests/cram/generic/build/releases_21.02-SNAPSHOT/.keep [new file with mode: 0644]
.gitlab/tests/cram/generic/build/releases_22.03-SNAPSHOT/.keep [new file with mode: 0644]
.gitlab/tests/cram/generic/build/snapshots/.keep [new file with mode: 0644]
.gitlab/tests/cram/initramfs [new symlink]
.gitlab/tests/cram/squashfs/README.md [new file with mode: 0644]
.gitlab/tests/cram/squashfs/arch/README.md [new file with mode: 0644]
.gitlab/tests/cram/squashfs/arch/ath79/.keep [new file with mode: 0644]
.gitlab/tests/cram/squashfs/arch/ath79_generic [new symlink]
.gitlab/tests/cram/squashfs/arch/ipq40xx/.keep [new file with mode: 0644]
.gitlab/tests/cram/squashfs/arch/ipq40xx_generic [new symlink]
.gitlab/tests/cram/squashfs/arch/mvebu/.keep [new file with mode: 0644]
.gitlab/tests/cram/squashfs/arch/mvebu_cortexa9 [new symlink]
.gitlab/tests/cram/squashfs/board/README.md [new file with mode: 0644]
.gitlab/tests/cram/squashfs/board/archer-c7-v5/030-wifi.t [new file with mode: 0644]
.gitlab/tests/cram/squashfs/board/archer-c7-v5_releases_19.07-SNAPSHOT [new symlink]
.gitlab/tests/cram/squashfs/board/archer-c7-v5_releases_19.07.7 [new symlink]
.gitlab/tests/cram/squashfs/board/archer-c7-v5_releases_21.02-SNAPSHOT [new symlink]
.gitlab/tests/cram/squashfs/board/archer-c7-v5_snapshots [new symlink]
.gitlab/tests/cram/squashfs/board/glinet-b1300/030-wifi.t [new file with mode: 0644]
.gitlab/tests/cram/squashfs/board/glinet-b1300_releases_19.07-SNAPSHOT [new symlink]
.gitlab/tests/cram/squashfs/board/glinet-b1300_releases_19.07.7 [new symlink]
.gitlab/tests/cram/squashfs/board/glinet-b1300_releases_21.02-SNAPSHOT [new symlink]
.gitlab/tests/cram/squashfs/board/glinet-b1300_snapshots [new symlink]
.gitlab/tests/cram/squashfs/board/turris-omnia/030-wifi.t [new file with mode: 0644]
.gitlab/tests/cram/squashfs/board/turris-omnia_releases_19.07-SNAPSHOT/020-network.t [new file with mode: 0644]
.gitlab/tests/cram/squashfs/board/turris-omnia_releases_19.07.7 [new symlink]
.gitlab/tests/cram/squashfs/board/turris-omnia_releases_21.02-SNAPSHOT/020-network.t [new file with mode: 0644]
.gitlab/tests/cram/squashfs/board/turris-omnia_snapshots [new symlink]
.gitlab/tests/cram/squashfs/build/README.md [new file with mode: 0644]
.gitlab/tests/cram/squashfs/build/generic/.keep [new file with mode: 0644]
.gitlab/tests/cram/squashfs/build/releases_19.07-SNAPSHOT/.keep [new file with mode: 0644]
.gitlab/tests/cram/squashfs/build/releases_19.07.7 [new symlink]
.gitlab/tests/cram/squashfs/build/releases_21.02-SNAPSHOT/.keep [new file with mode: 0644]
.gitlab/tests/cram/squashfs/build/snapshots/.keep [new file with mode: 0644]
.testbed/README.md [new file with mode: 0644]
.testbed/labgrid/default.yaml [new file with mode: 0644]

index 2ce76dae98eda57062df4119abb62d87a0f3efe3..3a42336c795a5cded73d57e2c57039876204b447 100644 (file)
@@ -1,12 +1,20 @@
 include:
   - remote: https://gitlab.com/ynezz/openwrt-ci/raw/master/openwrt-ci/gitlab/main.yml
   - remote: https://gitlab.com/ynezz/openwrt-ci/raw/master/openwrt-ci/gitlab/target.yml
+  - local: .gitlab/testbed.yml
+  - local: .gitlab/testbed/glinet-b1300.yml
+  - local: .gitlab/testbed/turris-omnia.yml
+
+stages:
+  - build
+  - run
 
 variables:
   CI_TARGET_BUILD_CONFIG_EXTRA: +BUILDBOT +DEVEL +KERNEL_KALLSYMS +BUILD_LOG +BPF_TOOLCHAIN_NONE +TESTING_KERNEL -IB -SDK -PACKAGE_kmod-acx-mac80211
 
 .truecz:
   extends: .openwrt-target-build
+  stage: build
   tags:
     - truecz-hetzner-autoscale
 
@@ -20,6 +28,12 @@ variables:
   rules:
     - when: always
 
+target build ipq40xx generic:
+  extends: .always
+
+runtime testing on Gl.iNet B1300 with initramfs image:
+  extends: .glinet-b1300 labgrid initramfs
+  needs: ["target build ipq40xx generic"]
 
 .target build x86 64:
   extends: .always
diff --git a/.gitlab/README.md b/.gitlab/README.md
new file mode 100644 (file)
index 0000000..56115ea
--- /dev/null
@@ -0,0 +1,41 @@
+# Content
+
+This directory contains stuff used on the GitLab CI.
+
+## docker
+
+Contains definitions for Docker images.
+
+## testbed
+
+Contains definitions for testbed related tests.
+
+## scripts
+
+Contains scripts used on GitLab CI.
+
+## tests
+
+Contains tests used on GitLab CI.
+
+## docker.yml
+
+Provides support for building, tagging and pushing the Docker images to image registry.
+
+For example let's build image `foo`.
+
+Prerequisites:
+
+ * Create directory for new Docker image `mkdir -p .gitlab/docker/foo`
+ * Docker image description `$EDITOR .gitlab/docker/foo/Dockefile`
+
+Then just put following into `.gitlab/docker/foo/gitlab.yml`
+
+```yaml
+build Docker image foo:
+  extends: .build Docker image
+```
+
+## testbed.yml
+
+Provides bits needed for runtime testing on real device using [labgrid](https://labgrid.readthedocs.io/en/latest/) Python testing framework.
diff --git a/.gitlab/docker.yml b/.gitlab/docker.yml
new file mode 100644 (file)
index 0000000..e7add4e
--- /dev/null
@@ -0,0 +1,28 @@
+.docker in docker:
+  tags:
+    - gce
+  image: docker:19.03.7
+  services:
+    - docker:19.03.7-dind
+  variables:
+    DOCKER_DRIVER: overlay2
+    DOCKER_TLS_CERTDIR: "/certs"
+
+.build Docker image:
+  stage: docker
+  extends: .docker in docker
+  script:
+    - export IMAGE_NAME="$(echo $CI_JOB_NAME | sed 's/build Docker image \(.*\)/\1/')"
+    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+    - docker build -t "$IMAGE_NAME" $DOCKER_DOCKERFILE_PATH
+    - docker tag "$IMAGE_NAME" "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$CI_COMMIT_REF_SLUG"
+    - docker push "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$CI_COMMIT_REF_SLUG"
+
+.deploy Docker image:
+  extends: .docker in docker
+  script:
+    - export IMAGE_NAME="$(echo $CI_JOB_NAME | sed 's/deploy Docker image \(.*\)/\1/')"
+    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+    - docker pull "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$CI_COMMIT_REF_SLUG"
+    - docker tag "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$CI_COMMIT_REF_SLUG" "$CI_REGISTRY_IMAGE/$IMAGE_NAME:latest"
+    - docker push "$CI_REGISTRY_IMAGE/$IMAGE_NAME:latest"
diff --git a/.gitlab/docker/README.md b/.gitlab/docker/README.md
new file mode 100644 (file)
index 0000000..8a251b1
--- /dev/null
@@ -0,0 +1,7 @@
+# Content
+
+This directory contains bits for Docker images used on the GitLab CI.
+
+## testbed
+
+Docker image used for runtime testing.
diff --git a/.gitlab/docker/testbed/Dockerfile b/.gitlab/docker/testbed/Dockerfile
new file mode 100644 (file)
index 0000000..eb58040
--- /dev/null
@@ -0,0 +1,47 @@
+FROM debian:buster-slim
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN \
+    apt-get update && \
+    apt-get install --yes --no-install-recommends \
+       curl \
+       git-core \
+       iputils-ping \
+       iproute2 \
+       locales \
+       nmap \
+       openssh-client \
+       python3 \
+       python3-pip \
+       python3-setuptools \
+       sudo && \
+    apt-get -y autoremove && \
+    apt-get clean && \
+    rm -rf /var/lib/apt/lists/*
+
+RUN localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
+ENV LANG=en_US.utf8
+
+ENV LABGRID_COMMIT=e1da2a319314
+RUN git clone --branch wip/testbed-next https://github.com/ynezz/labgrid
+WORKDIR labgrid
+RUN git reset --hard $LABGRID_COMMIT
+
+RUN pip3 install -U pip
+
+RUN \
+       pip3 install -r requirements.txt && \
+       python3 setup.py install
+
+RUN pip3 install cram
+
+RUN \
+    echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && \
+    useradd -c "OpenWrt Testbed" -m -d /home/testbed -G sudo -s /bin/bash testbed
+
+USER testbed
+ENV HOME /home/testbed
+WORKDIR /home/testbed/
+
+VOLUME [ "/home/testbed" ]
diff --git a/.gitlab/docker/testbed/gitlab.yml b/.gitlab/docker/testbed/gitlab.yml
new file mode 100644 (file)
index 0000000..84f6380
--- /dev/null
@@ -0,0 +1,23 @@
+build Docker image testbed:
+  stage: docker
+  extends: .build Docker image
+  variables:
+    DOCKER_DOCKERFILE_PATH: .gitlab/docker/testbed
+
+test Docker image testbed:
+  stage: docker test
+  extends: .docker in docker
+  needs: ["build Docker image testbed"]
+  script:
+    - export IMAGE_NAME="$(echo $CI_JOB_NAME | sed 's/test Docker image \(.*\)/\1/')"
+    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+    - docker pull "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$CI_COMMIT_REF_SLUG"
+    - >
+      docker run --rm "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$CI_COMMIT_REF_SLUG" sh -c "
+      python3 -c 'import labgrid; import yaml'
+      "
+
+deploy Docker image testbed:
+  stage: docker deploy
+  extends: .deploy Docker image
+  needs: ["test Docker image testbed"]
diff --git a/.gitlab/prebuild.yml b/.gitlab/prebuild.yml
new file mode 100644 (file)
index 0000000..c614eef
--- /dev/null
@@ -0,0 +1,16 @@
+include:
+  - remote: https://gitlab.com/ynezz/openwrt-ci/raw/master/openwrt-ci/gitlab/main.yml
+
+.check shell scripts with shellcheck:
+  stage: pre-build
+  extends: .openwrt-shellcheck
+
+check Python scripts with black and flake8:
+  stage: pre-build
+  extends: .openwrt-pythoncheck
+  rules:
+    - if: $CI_PIPELINE_SOURCE == "push"
+      changes:
+        - .gitlab/scripts/*
+    - when: manual
+      allow_failure: true
diff --git a/.gitlab/scripts/README.md b/.gitlab/scripts/README.md
new file mode 100644 (file)
index 0000000..1c49411
--- /dev/null
@@ -0,0 +1,11 @@
+# Content
+
+This directory contains files used mainly during testing on the GitLab CI.
+
+## requirements.txt
+
+This `requirements.txt` file is used for specifying what Python packages are required to run the scripts in this directory. Usually used with `pip install -f requirements.txt` command.
+
+## testbed-device.py
+
+This helper Python scripts allows managing of device under test (DUT) via labgrid framework.
diff --git a/.gitlab/scripts/testbed-device.py b/.gitlab/scripts/testbed-device.py
new file mode 100755 (executable)
index 0000000..73643b1
--- /dev/null
@@ -0,0 +1,140 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+import sys
+import logging
+
+from labgrid import Environment, StepReporter
+from labgrid.consoleloggingreporter import ConsoleLoggingReporter
+
+
+class TestbedDevice:
+    def __init__(self, args):
+        self.args = args
+        self.env = Environment(config_file=self.args.config)
+        ConsoleLoggingReporter.start(args.console_logpath)
+        self.target = self.env.get_target(args.target)
+
+    def boot_into(self):
+        strategy = self.target.get_driver("UBootStrategy")
+        dest = self.args.destination
+        if dest == "shell":
+            strategy.transition("shell")
+        if dest == "bootloader":
+            strategy.transition("uboot")
+
+    def power(self):
+        power = self.target.get_driver("PowerProtocol")
+        action = self.args.action
+        if action == "on":
+            power.on()
+        if action == "off":
+            power.off()
+        if action == "cycle":
+            power.cycle()
+
+    def check_network(self):
+        host = self.args.remote_host
+        network = self.args.network
+        shell = self.target.get_driver("ShellDriver")
+        shell.wait_for(
+            'ifstatus {} | jsonfilter -qe "@.up" || true'.format(network), "true", 60.0
+        )
+
+        shell.wait_for("ping -c1 {} || true".format(host), ", 0% packet loss", 90.0)
+
+
+def main():
+    logging.basicConfig(
+        level=logging.INFO, format="%(levelname)7s: %(message)s", stream=sys.stderr
+    )
+
+    parser = argparse.ArgumentParser()
+    parser.add_argument(
+        "-c",
+        "--config",
+        type=str,
+        default=os.environ.get("TB_CONFIG", ".testbed/labgrid/default.yaml"),
+        help="config file (default: %(default)s)",
+    )
+    parser.add_argument(
+        "-t",
+        "--target",
+        type=str,
+        default=os.environ.get("TB_TARGET", None),
+        help="target device",
+    )
+    parser.add_argument(
+        "-o",
+        "--console-logpath",
+        type=str,
+        default=os.environ.get("TB_CONSOLE_LOGPATH", os.getcwd()),
+        help="path for console logfile (default: %(default)s)",
+    )
+    parser.add_argument(
+        "-v",
+        "--verbose",
+        action="count",
+        default=int(os.environ.get("TB_VERBOSE", 0)),
+        help="enable verbose mode",
+    )
+    parser.add_argument(
+        "-d",
+        "--debug",
+        action="store_true",
+        default=os.environ.get("TB_DEBUG"),
+        help="enable debug mode",
+    )
+
+    subparsers = parser.add_subparsers(dest="command", title="available subcommands")
+
+    subparser = subparsers.add_parser("power", help="control target power")
+    subparser.add_argument(
+        "action", choices=["on", "off", "cycle"], help="power on/off/cycle target"
+    )
+    subparser.set_defaults(func=TestbedDevice.power)
+
+    subparser = subparsers.add_parser("boot_into", help="boot target into console")
+    subparser.add_argument(
+        "destination",
+        choices=["shell", "bootloader"],
+        help="boot target either into system shell or bootloader console",
+    )
+    subparser.set_defaults(func=TestbedDevice.boot_into)
+
+    subparser = subparsers.add_parser(
+        "check_network", help="ensure that network is usable"
+    )
+    subparser.add_argument(
+        "-r",
+        "--remote-host",
+        default="192.168.1.2",
+        help="remote host used for ping check (default: %(default)s)",
+    )
+    subparser.add_argument(
+        "-n", "--network", default="lan", help="target network (default: %(default)s)"
+    )
+    subparser.set_defaults(func=TestbedDevice.check_network)
+
+    args = parser.parse_args()
+    if args.verbose >= 1:
+        StepReporter.start()
+
+    if args.debug:
+        logging.getLogger().setLevel(logging.DEBUG)
+
+    if not args.target:
+        print("target device name is mandatory")
+        exit(1)
+
+    if not args.command:
+        print("command is missing")
+        exit(1)
+
+    device = TestbedDevice(args)
+    args.func(device)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/.gitlab/testbed.yml b/.gitlab/testbed.yml
new file mode 100644 (file)
index 0000000..5164b07
--- /dev/null
@@ -0,0 +1,99 @@
+.testbed:
+  stage: run
+  image: "$CI_REGISTRY_IMAGE/testbed:latest"
+  variables:
+    DUT_SLEEP_AFTER_BOOT: 30
+    OWRT_DOWNLOADS_URL: https://downloads.openwrt.org
+    TESTBED_TFTP_PATH: /var/lib/tftpboot
+    TFTP_IMAGE_PATH: bin/targets/$DUT_TARGET/$DUT_SUBTARGET
+    TARGET_LAN_IP: 192.168.1.1
+    TARGET_LAN_TEST_HOST: 192.168.1.2
+    CRAM_REMOTE_COMMAND: ssh root@$TARGET_LAN_IP
+    CRAM_TEST_SUITE: |
+      .gitlab/tests/cram/generic/build/generic
+      .gitlab/tests/cram/generic/build/$OWRT_IMAGE_BUILD_RELEASE
+      .gitlab/tests/cram/generic/arch/$DUT_TARGET
+      .gitlab/tests/cram/generic/arch/${DUT_TARGET}_$DUT_SUBTARGET
+      .gitlab/tests/cram/generic/board/$DUT_BOARD
+      .gitlab/tests/cram/generic/board/${DUT_BOARD}_$OWRT_IMAGE_BUILD_RELEASE
+      .gitlab/tests/cram/$DUT_BOOT_MEDIUM/build/generic
+      .gitlab/tests/cram/$DUT_BOOT_MEDIUM/build/$OWRT_IMAGE_BUILD_RELEASE
+      .gitlab/tests/cram/$DUT_BOOT_MEDIUM/arch/$DUT_TARGET
+      .gitlab/tests/cram/$DUT_BOOT_MEDIUM/arch/${DUT_TARGET}_$DUT_SUBTARGET
+      .gitlab/tests/cram/$DUT_BOOT_MEDIUM/board/$DUT_BOARD
+      .gitlab/tests/cram/$DUT_BOOT_MEDIUM/board/${DUT_BOARD}_$OWRT_IMAGE_BUILD_RELEASE
+
+  before_script:
+    - eval $(ssh-agent -s)
+    - echo "$TESTBED_SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
+    - mkdir -p ~/.ssh; chmod 700 ~/.ssh
+    - ssh-keyscan $TESTBED_UART_RELAY_HOST > ~/.ssh/known_hosts 2> /dev/null
+    - chmod 644 ~/.ssh/known_hosts
+
+    - >
+      if [ -n "$TFTP_IMAGE_DOWNLOAD_URL" ]; then
+        echo "Downloading firmware image from $TFTP_IMAGE_DOWNLOAD_URL"
+        curl --fail "$TFTP_IMAGE_DOWNLOAD_URL" > "$TESTBED_TFTP_PATH/$DUT_TFTP_IMAGE_FILENAME"
+      elif [ -n "$OWRT_IMAGE_BUILD_RELEASE" ]; then
+        url="$OWRT_DOWNLOADS_URL/$(echo $OWRT_IMAGE_BUILD_RELEASE | tr '_' '/')/targets/$DUT_TARGET/$DUT_SUBTARGET";
+        image=$(curl "$url/" | sed -nE "s/.*href\=\"($DUT_IMAGE_MATCH_PATTERN)\".*/\1/p");
+        echo "Downloading $url/$image to $TESTBED_TFTP_PATH/$DUT_TFTP_IMAGE_FILENAME";
+        curl --fail "$url/$image" > "$TESTBED_TFTP_PATH/$DUT_TFTP_IMAGE_FILENAME"
+      else
+        echo "Using firmware image $TESTBED_TFTP_PATH/$DUT_TFTP_IMAGE_FILENAME"
+        cp "$TFTP_IMAGE_PATH/$DUT_TFTP_IMAGE_FILENAME" "$TESTBED_TFTP_PATH/"
+      fi
+
+    - .gitlab/scripts/testbed-device.py --target $LABGRID_TARGET boot_into shell
+    - >
+      .gitlab/scripts/testbed-device.py
+      --target $LABGRID_TARGET check_network
+      --network lan
+      --remote-host $TARGET_LAN_TEST_HOST
+
+    - ssh-keyscan $TARGET_LAN_IP >> ~/.ssh/known_hosts 2> /dev/null
+    - ssh root@$TARGET_LAN_IP "ubus call system board" | tee system-$LABGRID_TARGET.json
+
+  script:
+    - set -o pipefail
+    - sleep $DUT_SLEEP_AFTER_BOOT
+    - python3 -m cram --verbose $CRAM_TEST_SUITE $CRAM_TEST_SUITE_EXTRA | tee cram-result-$LABGRID_TARGET.txt
+
+  after_script:
+    - eval $(ssh-agent -s)
+    - echo "$TESTBED_SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
+    - mkdir -p ~/.ssh; chmod 700 ~/.ssh
+    - ssh-keyscan $TESTBED_UART_RELAY_HOST > ~/.ssh/known_hosts 2> /dev/null
+    - chmod 644 ~/.ssh/known_hosts
+
+    - ssh-keyscan $TARGET_LAN_IP >> ~/.ssh/known_hosts 2> /dev/null
+    - >
+      ssh root@$TARGET_LAN_IP exit && {
+        ssh root@$TARGET_LAN_IP ps > processes-$LABGRID_TARGET.txt
+        ssh root@$TARGET_LAN_IP dmesg > dmesg-$LABGRID_TARGET.txt
+        ssh root@$TARGET_LAN_IP logread > logread-$LABGRID_TARGET.txt
+        ssh root@$TARGET_LAN_IP cat /etc/config/network > uci-network-$LABGRID_TARGET.txt
+        ssh root@$TARGET_LAN_IP cat /etc/config/wireless > uci-wireless-$LABGRID_TARGET.txt
+      } || true
+
+    - .gitlab/scripts/testbed-device.py --target $LABGRID_TARGET power off
+
+    - mv console_$LABGRID_TARGET console_$LABGRID_TARGET.txt || true
+
+  artifacts:
+    expire_in: 1 month
+    when: always
+    paths:
+      - .gitlab/tests/cram/**/*.t.err
+      - processes-$LABGRID_TARGET.txt
+      - dmesg-$LABGRID_TARGET.txt
+      - logread-$LABGRID_TARGET.txt
+      - uci-*-$LABGRID_TARGET.txt
+      - system-$LABGRID_TARGET.json
+      - console_$LABGRID_TARGET.txt
+      - cram-result-$LABGRID_TARGET.txt
+
+.testbed true.cz:
+  extends: .testbed
+  variables:
+    TESTBED_UART_RELAY_HOST: uart-relay.testbed.vpn.true.cz
diff --git a/.gitlab/testbed/archer-c7-v5.yml b/.gitlab/testbed/archer-c7-v5.yml
new file mode 100644 (file)
index 0000000..ffdf9d6
--- /dev/null
@@ -0,0 +1,21 @@
+.archer-c7-v5 labgrid initramfs:
+  extends: .archer-c7-v5 testbed initramfs
+  variables:
+    DUT_SLEEP_AFTER_BOOT: 90
+    LABGRID_TARGET: "${DUT_BOARD}-$DUT_BOOT_MEDIUM"
+
+.archer-c7-v5 testbed initramfs:
+  extends: .archer-c7-v5 testbed
+  variables:
+    DUT_BOOT_MEDIUM: initramfs
+    DUT_IMAGE_MATCH_PATTERN: .*tplink_archer-c7-v5.*initramfs.*bin
+    DUT_TFTP_IMAGE_FILENAME: openwrt-ath79-generic-tplink_archer-c7-v5-initramfs-kernel.bin
+
+.archer-c7-v5 testbed:
+  extends: .testbed true.cz
+  variables:
+    DUT_TARGET: ath79
+    DUT_SUBTARGET: generic
+    DUT_BOARD: archer-c7-v5
+  tags:
+    - dut-archer-c7-v5
diff --git a/.gitlab/testbed/glinet-b1300.yml b/.gitlab/testbed/glinet-b1300.yml
new file mode 100644 (file)
index 0000000..c098aeb
--- /dev/null
@@ -0,0 +1,20 @@
+.glinet-b1300 labgrid initramfs:
+  extends: .glinet-b1300 testbed initramfs
+  variables:
+    LABGRID_TARGET: "${DUT_BOARD}-$DUT_BOOT_MEDIUM"
+
+.glinet-b1300 testbed initramfs:
+  extends: .glinet-b1300 testbed
+  variables:
+    DUT_BOOT_MEDIUM: initramfs
+    DUT_IMAGE_MATCH_PATTERN: .*glinet_gl-b1300.*initramfs.*itb
+    DUT_TFTP_IMAGE_FILENAME: openwrt-ipq40xx-generic-glinet_gl-b1300-initramfs-fit-uImage.itb
+
+.glinet-b1300 testbed:
+  extends: .testbed true.cz
+  variables:
+    DUT_TARGET: ipq40xx
+    DUT_SUBTARGET: generic
+    DUT_BOARD: glinet-b1300
+  tags:
+    - dut-glinet-b1300
diff --git a/.gitlab/testbed/tplink-c6v2.yml b/.gitlab/testbed/tplink-c6v2.yml
new file mode 100644 (file)
index 0000000..508901a
--- /dev/null
@@ -0,0 +1,10 @@
+.tplink-c6v2 testbed:
+  extends: .testbed true.cz
+  variables:
+    DUT_TARGET: ath79
+    DUT_SUBTARGET: generic
+    DUT_BOARD: tplink-c6v2
+    DUT_IMAGE_MATCH_PATTERN: .*archer-c6-v2.*initramfs.*.bin
+    DUT_TFTP_IMAGE_FILENAME: openwrt-ath79-generic-tplink_archer-c6-v2-initramfs-kernel.bin
+  tags:
+    - dut-tplink-c6v2
diff --git a/.gitlab/testbed/turris-omnia.yml b/.gitlab/testbed/turris-omnia.yml
new file mode 100644 (file)
index 0000000..e9edabb
--- /dev/null
@@ -0,0 +1,21 @@
+.turris-omnia labgrid initramfs:
+  retry: 1
+  extends: .turris-omnia testbed initramfs
+  variables:
+    LABGRID_TARGET: "${DUT_BOARD}-$DUT_BOOT_MEDIUM"
+
+.turris-omnia testbed initramfs:
+  extends: .turris-omnia testbed
+  variables:
+    DUT_BOOT_MEDIUM: initramfs
+    DUT_IMAGE_MATCH_PATTERN: .*turris-omnia-initramfs.*.bin
+    DUT_TFTP_IMAGE_FILENAME: openwrt-mvebu-cortexa9-cznic_turris-omnia-initramfs-kernel.bin
+
+.turris-omnia testbed:
+  extends: .testbed true.cz
+  variables:
+    DUT_TARGET: mvebu
+    DUT_SUBTARGET: cortexa9
+    DUT_BOARD: turris-omnia
+  tags:
+    - dut-turris-omnia
diff --git a/.gitlab/tests/README.md b/.gitlab/tests/README.md
new file mode 100644 (file)
index 0000000..973c1ba
--- /dev/null
@@ -0,0 +1,12 @@
+# Content
+
+This directory contains tests.
+
+## cram
+
+Contains [Cram](https://github.com/brodie/cram/) based tests. [Cram](https://github.com/brodie/cram/) is a functional
+testing framework for command line applications. [Cram](https://github.com/brodie/cram/) tests look like snippets of
+interactive shell sessions. Cram runs each command and compares the command output in the test with the command's actual
+output.
+
+Tests in this directory should be run against device, usually over network via SSH connection.
diff --git a/.gitlab/tests/cram/README.md b/.gitlab/tests/cram/README.md
new file mode 100644 (file)
index 0000000..423ce84
--- /dev/null
@@ -0,0 +1,15 @@
+# Content
+
+This directory contains Cram based tests.
+
+## generic
+
+Contains tests which can be run on DUT booted from any root filesystem.
+
+## initramfs
+
+Contains tests which can be run on DUT booted from initramfs root filesystem.
+
+## squashfs
+
+Contains tests which can be run on DUT booted from squashfs root filesystem.
diff --git a/.gitlab/tests/cram/generic/README.md b/.gitlab/tests/cram/generic/README.md
new file mode 100644 (file)
index 0000000..d410447
--- /dev/null
@@ -0,0 +1,15 @@
+# Content
+
+This directory contains Cram based tests.
+
+## arch
+
+Contains tests separated by target/subtarget architecture.
+
+## board
+
+Contains tests which should be used only on specific boards/DUTs.
+
+## build
+
+Contains tests which could be used on specific build type.
diff --git a/.gitlab/tests/cram/generic/arch/README.md b/.gitlab/tests/cram/generic/arch/README.md
new file mode 100644 (file)
index 0000000..a4dbddb
--- /dev/null
@@ -0,0 +1,10 @@
+# Content
+
+Contains tests separated by target/subtarget architecture.
+
+## ath79
+## ath79_generic
+## ipq40xx
+## ipq40xx_generic
+## mvebu
+## mvebu_cortexa9
diff --git a/.gitlab/tests/cram/generic/arch/ath79/010-ubus.t b/.gitlab/tests/cram/generic/arch/ath79/010-ubus.t
new file mode 100644 (file)
index 0000000..ce28154
--- /dev/null
@@ -0,0 +1,8 @@
+Create R alias:
+
+  $ alias R="${CRAM_REMOTE_COMMAND:-}"
+
+Check that we've correct system info:
+
+  $ R "ubus call system board | jsonfilter -e @.system"
+  Qualcomm Atheros QCA956X ver 1 rev 0
diff --git a/.gitlab/tests/cram/generic/arch/ath79_generic b/.gitlab/tests/cram/generic/arch/ath79_generic
new file mode 120000 (symlink)
index 0000000..c96a060
--- /dev/null
@@ -0,0 +1 @@
+ath79
\ No newline at end of file
diff --git a/.gitlab/tests/cram/generic/arch/ipq40xx/010-ubus.t b/.gitlab/tests/cram/generic/arch/ipq40xx/010-ubus.t
new file mode 100644 (file)
index 0000000..6d55bd6
--- /dev/null
@@ -0,0 +1,8 @@
+Create R alias:
+
+  $ alias R="${CRAM_REMOTE_COMMAND:-}"
+
+Check that we've correct system info:
+
+  $ R "ubus call system board | jsonfilter -e @.system"
+  ARMv7 Processor rev 5 (v7l)
diff --git a/.gitlab/tests/cram/generic/arch/ipq40xx_generic b/.gitlab/tests/cram/generic/arch/ipq40xx_generic
new file mode 120000 (symlink)
index 0000000..43dc074
--- /dev/null
@@ -0,0 +1 @@
+ipq40xx
\ No newline at end of file
diff --git a/.gitlab/tests/cram/generic/arch/mvebu/010-ubus.t b/.gitlab/tests/cram/generic/arch/mvebu/010-ubus.t
new file mode 100644 (file)
index 0000000..cf68a3d
--- /dev/null
@@ -0,0 +1,8 @@
+Create R alias:
+
+  $ alias R="${CRAM_REMOTE_COMMAND:-}"
+
+Check that we've correct system info:
+
+  $ R "ubus call system board | jsonfilter -e @.system"
+  ARMv7 Processor rev 1 (v7l)
diff --git a/.gitlab/tests/cram/generic/arch/mvebu_cortexa9 b/.gitlab/tests/cram/generic/arch/mvebu_cortexa9
new file mode 120000 (symlink)
index 0000000..138857a
--- /dev/null
@@ -0,0 +1 @@
+mvebu
\ No newline at end of file
diff --git a/.gitlab/tests/cram/generic/board/README.md b/.gitlab/tests/cram/generic/board/README.md
new file mode 100644 (file)
index 0000000..1648ff7
--- /dev/null
@@ -0,0 +1,15 @@
+# Content
+
+This directory contains Cram based tests for specific DUTs.
+
+## archer-c7-v5
+
+Contains tests which could be used against `TP-Link Archer C7 v5` device.
+
+## glinet-b1300
+
+Contains tests which could be used against `Gl.iNet B1300` device.
+
+## turris-omnia
+
+Contains tests which could be used against `Turris Omnia` device.
diff --git a/.gitlab/tests/cram/generic/board/archer-c7-v5/010-ubus.t b/.gitlab/tests/cram/generic/board/archer-c7-v5/010-ubus.t
new file mode 100644 (file)
index 0000000..c92352c
--- /dev/null
@@ -0,0 +1,9 @@
+Create R alias:
+
+  $ alias R="${CRAM_REMOTE_COMMAND:-}"
+
+Check that we've correct system info:
+
+  $ R "ubus call system board | jsonfilter -e @.model -e @.board_name"
+  TP-Link Archer C7 v5
+  tplink,archer-c7-v5
diff --git a/.gitlab/tests/cram/generic/board/archer-c7-v5/020-network.t b/.gitlab/tests/cram/generic/board/archer-c7-v5/020-network.t
new file mode 100644 (file)
index 0000000..0d35a9c
--- /dev/null
@@ -0,0 +1,20 @@
+Create R alias:
+
+  $ alias R="${CRAM_REMOTE_COMMAND:-}"
+
+Check correct routing table:
+
+  $ R ip route
+  default via 10.0.0.1 dev eth0.2  src 10.0.0.2 
+  10.0.0.0/24 dev eth0.2 scope link  src 10.0.0.2 
+  192.168.1.0/24 dev br-lan scope link  src 192.168.1.1 
+
+Check correct interface setup:
+
+  $ R "ip link | grep ^\\\\d | cut -d: -f2-" | LC_ALL=C sort
+   br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
+   eth0.1@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-lan state UP qlen 1000
+   eth0.2@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
+   eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP qlen 1000
+   lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
+   wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
diff --git a/.gitlab/tests/cram/generic/board/archer-c7-v5_releases_19.07-SNAPSHOT b/.gitlab/tests/cram/generic/board/archer-c7-v5_releases_19.07-SNAPSHOT
new file mode 120000 (symlink)
index 0000000..8271131
--- /dev/null
@@ -0,0 +1 @@
+archer-c7-v5
\ No newline at end of file
diff --git a/.gitlab/tests/cram/generic/board/archer-c7-v5_releases_21.02-SNAPSHOT b/.gitlab/tests/cram/generic/board/archer-c7-v5_releases_21.02-SNAPSHOT
new file mode 120000 (symlink)
index 0000000..8271131
--- /dev/null
@@ -0,0 +1 @@
+archer-c7-v5
\ No newline at end of file
diff --git a/.gitlab/tests/cram/generic/board/archer-c7-v5_releases_22.03-SNAPSHOT b/.gitlab/tests/cram/generic/board/archer-c7-v5_releases_22.03-SNAPSHOT
new file mode 120000 (symlink)
index 0000000..8271131
--- /dev/null
@@ -0,0 +1 @@
+archer-c7-v5
\ No newline at end of file
diff --git a/.gitlab/tests/cram/generic/board/archer-c7-v5_snapshots b/.gitlab/tests/cram/generic/board/archer-c7-v5_snapshots
new file mode 120000 (symlink)
index 0000000..8271131
--- /dev/null
@@ -0,0 +1 @@
+archer-c7-v5
\ No newline at end of file
diff --git a/.gitlab/tests/cram/generic/board/glinet-b1300/010-ubus.t b/.gitlab/tests/cram/generic/board/glinet-b1300/010-ubus.t
new file mode 100644 (file)
index 0000000..b7166e0
--- /dev/null
@@ -0,0 +1,9 @@
+Create R alias:
+
+  $ alias R="${CRAM_REMOTE_COMMAND:-}"
+
+Check that we've correct system info:
+
+  $ R "ubus call system board | jsonfilter -e @.model -e @.board_name"
+  GL.iNet GL-B1300
+  glinet,gl-b1300
diff --git a/.gitlab/tests/cram/generic/board/glinet-b1300/020-network.t b/.gitlab/tests/cram/generic/board/glinet-b1300/020-network.t
new file mode 100644 (file)
index 0000000..c246b1e
--- /dev/null
@@ -0,0 +1,20 @@
+Create R alias:
+
+  $ alias R="${CRAM_REMOTE_COMMAND:-}"
+
+Check correct routing table:
+
+  $ R ip route
+  default via 10.0.0.1 dev eth1  src 10.0.0.2 
+  10.0.0.0/24 dev eth1 scope link  src 10.0.0.2 
+  192.168.1.0/24 dev br-lan scope link  src 192.168.1.1 
+
+Check correct interface setup:
+
+  $ R "ip link | grep ^\\\\d | cut -d: -f2-" | LC_ALL=C sort
+   br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
+   eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br-lan state UP qlen 1000
+   eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
+   lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
+   wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
+   wlan1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
diff --git a/.gitlab/tests/cram/generic/board/glinet-b1300_releases_19.07-SNAPSHOT b/.gitlab/tests/cram/generic/board/glinet-b1300_releases_19.07-SNAPSHOT
new file mode 120000 (symlink)
index 0000000..cab7913
--- /dev/null
@@ -0,0 +1 @@
+glinet-b1300
\ No newline at end of file
diff --git a/.gitlab/tests/cram/generic/board/glinet-b1300_releases_21.02-SNAPSHOT b/.gitlab/tests/cram/generic/board/glinet-b1300_releases_21.02-SNAPSHOT
new file mode 120000 (symlink)
index 0000000..cab7913
--- /dev/null
@@ -0,0 +1 @@
+glinet-b1300
\ No newline at end of file
diff --git a/.gitlab/tests/cram/generic/board/glinet-b1300_releases_22.03-SNAPSHOT b/.gitlab/tests/cram/generic/board/glinet-b1300_releases_22.03-SNAPSHOT
new file mode 120000 (symlink)
index 0000000..cab7913
--- /dev/null
@@ -0,0 +1 @@
+glinet-b1300
\ No newline at end of file
diff --git a/.gitlab/tests/cram/generic/board/glinet-b1300_snapshots b/.gitlab/tests/cram/generic/board/glinet-b1300_snapshots
new file mode 120000 (symlink)
index 0000000..cab7913
--- /dev/null
@@ -0,0 +1 @@
+glinet-b1300
\ No newline at end of file
diff --git a/.gitlab/tests/cram/generic/board/turris-omnia/010-ubus.t b/.gitlab/tests/cram/generic/board/turris-omnia/010-ubus.t
new file mode 100644 (file)
index 0000000..360b95b
--- /dev/null
@@ -0,0 +1,9 @@
+Create R alias:
+
+  $ alias R="${CRAM_REMOTE_COMMAND:-}"
+
+Check that we've correct system info:
+
+  $ R "ubus call system board | jsonfilter -e @.model -e @.board_name"
+  Turris Omnia
+  cznic,turris-omnia
diff --git a/.gitlab/tests/cram/generic/board/turris-omnia/020-network.t b/.gitlab/tests/cram/generic/board/turris-omnia/020-network.t
new file mode 100644 (file)
index 0000000..6c59592
--- /dev/null
@@ -0,0 +1,10 @@
+Create R alias:
+
+  $ alias R="${CRAM_REMOTE_COMMAND:-}"
+
+Check correct routing table:
+
+  $ R ip route
+  default via 10.0.0.1 dev eth2  src 10.0.0.2 
+  10.0.0.0/24 dev eth2 scope link  src 10.0.0.2 
+  192.168.1.0/24 dev br-lan scope link  src 192.168.1.1 
diff --git a/.gitlab/tests/cram/generic/board/turris-omnia_releases_19.07-SNAPSHOT/020-network.t b/.gitlab/tests/cram/generic/board/turris-omnia_releases_19.07-SNAPSHOT/020-network.t
new file mode 100644 (file)
index 0000000..b8777c9
--- /dev/null
@@ -0,0 +1,17 @@
+Create R alias:
+
+  $ alias R="${CRAM_REMOTE_COMMAND:-}"
+
+Check correct interface setup:
+
+  $ R "ip link | grep ^\\\\d | cut -d: -f2-" | LC_ALL=C sort
+   br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
+   eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 532
+   eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 532
+   eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 532
+   lan0@eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master br-lan state LOWERLAYERDOWN qlen 1000
+   lan1@eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master br-lan state LOWERLAYERDOWN qlen 1000
+   lan2@eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master br-lan state LOWERLAYERDOWN qlen 1000
+   lan3@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-lan state UP qlen 1000
+   lan4@eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master br-lan state LOWERLAYERDOWN qlen 1000
+   lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
diff --git a/.gitlab/tests/cram/generic/board/turris-omnia_releases_21.02-SNAPSHOT b/.gitlab/tests/cram/generic/board/turris-omnia_releases_21.02-SNAPSHOT
new file mode 120000 (symlink)
index 0000000..21d97f5
--- /dev/null
@@ -0,0 +1 @@
+turris-omnia_snapshots
\ No newline at end of file
diff --git a/.gitlab/tests/cram/generic/board/turris-omnia_releases_22.03-SNAPSHOT b/.gitlab/tests/cram/generic/board/turris-omnia_releases_22.03-SNAPSHOT
new file mode 120000 (symlink)
index 0000000..21d97f5
--- /dev/null
@@ -0,0 +1 @@
+turris-omnia_snapshots
\ No newline at end of file
diff --git a/.gitlab/tests/cram/generic/board/turris-omnia_snapshots/020-network.t b/.gitlab/tests/cram/generic/board/turris-omnia_snapshots/020-network.t
new file mode 100644 (file)
index 0000000..768df0a
--- /dev/null
@@ -0,0 +1,17 @@
+Create R alias:
+
+  $ alias R="${CRAM_REMOTE_COMMAND:-}"
+
+Check correct interface setup:
+
+  $ R "ip link | grep ^\\\\d | cut -d: -f2-" | LC_ALL=C sort
+   br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
+   eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1024
+   eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1508 qdisc mq state UP qlen 1024
+   eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1024
+   lan0@eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master br-lan state LOWERLAYERDOWN qlen 1000
+   lan1@eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master br-lan state LOWERLAYERDOWN qlen 1000
+   lan2@eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master br-lan state LOWERLAYERDOWN qlen 1000
+   lan3@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-lan state UP qlen 1000
+   lan4@eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master br-lan state LOWERLAYERDOWN qlen 1000
+   lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
diff --git a/.gitlab/tests/cram/generic/build/README.md b/.gitlab/tests/cram/generic/build/README.md
new file mode 100644 (file)
index 0000000..c048204
--- /dev/null
@@ -0,0 +1,19 @@
+# Content
+
+Contains tests which could be used on specific build type.
+
+## generic
+
+Tests run on all build types.
+
+## snapshots
+
+Tests run on all snapshot builds.
+
+## releases_19.07-SNAPSHOT
+
+Tests run on 19.07-SNAPSHOT releases.
+
+## releases_19.07.7
+
+Tests run only on 19.07.7 release.
diff --git a/.gitlab/tests/cram/generic/build/generic/.keep b/.gitlab/tests/cram/generic/build/generic/.keep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/.gitlab/tests/cram/generic/build/releases_19.07-SNAPSHOT/.keep b/.gitlab/tests/cram/generic/build/releases_19.07-SNAPSHOT/.keep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/.gitlab/tests/cram/generic/build/releases_21.02-SNAPSHOT/.keep b/.gitlab/tests/cram/generic/build/releases_21.02-SNAPSHOT/.keep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/.gitlab/tests/cram/generic/build/releases_22.03-SNAPSHOT/.keep b/.gitlab/tests/cram/generic/build/releases_22.03-SNAPSHOT/.keep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/.gitlab/tests/cram/generic/build/snapshots/.keep b/.gitlab/tests/cram/generic/build/snapshots/.keep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/.gitlab/tests/cram/initramfs b/.gitlab/tests/cram/initramfs
new file mode 120000 (symlink)
index 0000000..df999dd
--- /dev/null
@@ -0,0 +1 @@
+generic
\ No newline at end of file
diff --git a/.gitlab/tests/cram/squashfs/README.md b/.gitlab/tests/cram/squashfs/README.md
new file mode 100644 (file)
index 0000000..d410447
--- /dev/null
@@ -0,0 +1,15 @@
+# Content
+
+This directory contains Cram based tests.
+
+## arch
+
+Contains tests separated by target/subtarget architecture.
+
+## board
+
+Contains tests which should be used only on specific boards/DUTs.
+
+## build
+
+Contains tests which could be used on specific build type.
diff --git a/.gitlab/tests/cram/squashfs/arch/README.md b/.gitlab/tests/cram/squashfs/arch/README.md
new file mode 100644 (file)
index 0000000..a4dbddb
--- /dev/null
@@ -0,0 +1,10 @@
+# Content
+
+Contains tests separated by target/subtarget architecture.
+
+## ath79
+## ath79_generic
+## ipq40xx
+## ipq40xx_generic
+## mvebu
+## mvebu_cortexa9
diff --git a/.gitlab/tests/cram/squashfs/arch/ath79/.keep b/.gitlab/tests/cram/squashfs/arch/ath79/.keep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/.gitlab/tests/cram/squashfs/arch/ath79_generic b/.gitlab/tests/cram/squashfs/arch/ath79_generic
new file mode 120000 (symlink)
index 0000000..c96a060
--- /dev/null
@@ -0,0 +1 @@
+ath79
\ No newline at end of file
diff --git a/.gitlab/tests/cram/squashfs/arch/ipq40xx/.keep b/.gitlab/tests/cram/squashfs/arch/ipq40xx/.keep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/.gitlab/tests/cram/squashfs/arch/ipq40xx_generic b/.gitlab/tests/cram/squashfs/arch/ipq40xx_generic
new file mode 120000 (symlink)
index 0000000..43dc074
--- /dev/null
@@ -0,0 +1 @@
+ipq40xx
\ No newline at end of file
diff --git a/.gitlab/tests/cram/squashfs/arch/mvebu/.keep b/.gitlab/tests/cram/squashfs/arch/mvebu/.keep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/.gitlab/tests/cram/squashfs/arch/mvebu_cortexa9 b/.gitlab/tests/cram/squashfs/arch/mvebu_cortexa9
new file mode 120000 (symlink)
index 0000000..138857a
--- /dev/null
@@ -0,0 +1 @@
+mvebu
\ No newline at end of file
diff --git a/.gitlab/tests/cram/squashfs/board/README.md b/.gitlab/tests/cram/squashfs/board/README.md
new file mode 100644 (file)
index 0000000..1648ff7
--- /dev/null
@@ -0,0 +1,15 @@
+# Content
+
+This directory contains Cram based tests for specific DUTs.
+
+## archer-c7-v5
+
+Contains tests which could be used against `TP-Link Archer C7 v5` device.
+
+## glinet-b1300
+
+Contains tests which could be used against `Gl.iNet B1300` device.
+
+## turris-omnia
+
+Contains tests which could be used against `Turris Omnia` device.
diff --git a/.gitlab/tests/cram/squashfs/board/archer-c7-v5/030-wifi.t b/.gitlab/tests/cram/squashfs/board/archer-c7-v5/030-wifi.t
new file mode 100644 (file)
index 0000000..35975a1
--- /dev/null
@@ -0,0 +1,9 @@
+Create R alias:
+
+  $ alias R="${CRAM_REMOTE_COMMAND:-}"
+
+Check for correct SSID setup:
+
+  $ R "iwinfo | grep ESSID"
+  wlan0     ESSID: unknown
+  wlan1     ESSID: unknown
diff --git a/.gitlab/tests/cram/squashfs/board/archer-c7-v5_releases_19.07-SNAPSHOT b/.gitlab/tests/cram/squashfs/board/archer-c7-v5_releases_19.07-SNAPSHOT
new file mode 120000 (symlink)
index 0000000..8271131
--- /dev/null
@@ -0,0 +1 @@
+archer-c7-v5
\ No newline at end of file
diff --git a/.gitlab/tests/cram/squashfs/board/archer-c7-v5_releases_19.07.7 b/.gitlab/tests/cram/squashfs/board/archer-c7-v5_releases_19.07.7
new file mode 120000 (symlink)
index 0000000..8271131
--- /dev/null
@@ -0,0 +1 @@
+archer-c7-v5
\ No newline at end of file
diff --git a/.gitlab/tests/cram/squashfs/board/archer-c7-v5_releases_21.02-SNAPSHOT b/.gitlab/tests/cram/squashfs/board/archer-c7-v5_releases_21.02-SNAPSHOT
new file mode 120000 (symlink)
index 0000000..8271131
--- /dev/null
@@ -0,0 +1 @@
+archer-c7-v5
\ No newline at end of file
diff --git a/.gitlab/tests/cram/squashfs/board/archer-c7-v5_snapshots b/.gitlab/tests/cram/squashfs/board/archer-c7-v5_snapshots
new file mode 120000 (symlink)
index 0000000..8271131
--- /dev/null
@@ -0,0 +1 @@
+archer-c7-v5
\ No newline at end of file
diff --git a/.gitlab/tests/cram/squashfs/board/glinet-b1300/030-wifi.t b/.gitlab/tests/cram/squashfs/board/glinet-b1300/030-wifi.t
new file mode 100644 (file)
index 0000000..35975a1
--- /dev/null
@@ -0,0 +1,9 @@
+Create R alias:
+
+  $ alias R="${CRAM_REMOTE_COMMAND:-}"
+
+Check for correct SSID setup:
+
+  $ R "iwinfo | grep ESSID"
+  wlan0     ESSID: unknown
+  wlan1     ESSID: unknown
diff --git a/.gitlab/tests/cram/squashfs/board/glinet-b1300_releases_19.07-SNAPSHOT b/.gitlab/tests/cram/squashfs/board/glinet-b1300_releases_19.07-SNAPSHOT
new file mode 120000 (symlink)
index 0000000..cab7913
--- /dev/null
@@ -0,0 +1 @@
+glinet-b1300
\ No newline at end of file
diff --git a/.gitlab/tests/cram/squashfs/board/glinet-b1300_releases_19.07.7 b/.gitlab/tests/cram/squashfs/board/glinet-b1300_releases_19.07.7
new file mode 120000 (symlink)
index 0000000..cab7913
--- /dev/null
@@ -0,0 +1 @@
+glinet-b1300
\ No newline at end of file
diff --git a/.gitlab/tests/cram/squashfs/board/glinet-b1300_releases_21.02-SNAPSHOT b/.gitlab/tests/cram/squashfs/board/glinet-b1300_releases_21.02-SNAPSHOT
new file mode 120000 (symlink)
index 0000000..cab7913
--- /dev/null
@@ -0,0 +1 @@
+glinet-b1300
\ No newline at end of file
diff --git a/.gitlab/tests/cram/squashfs/board/glinet-b1300_snapshots b/.gitlab/tests/cram/squashfs/board/glinet-b1300_snapshots
new file mode 120000 (symlink)
index 0000000..cab7913
--- /dev/null
@@ -0,0 +1 @@
+glinet-b1300
\ No newline at end of file
diff --git a/.gitlab/tests/cram/squashfs/board/turris-omnia/030-wifi.t b/.gitlab/tests/cram/squashfs/board/turris-omnia/030-wifi.t
new file mode 100644 (file)
index 0000000..35975a1
--- /dev/null
@@ -0,0 +1,9 @@
+Create R alias:
+
+  $ alias R="${CRAM_REMOTE_COMMAND:-}"
+
+Check for correct SSID setup:
+
+  $ R "iwinfo | grep ESSID"
+  wlan0     ESSID: unknown
+  wlan1     ESSID: unknown
diff --git a/.gitlab/tests/cram/squashfs/board/turris-omnia_releases_19.07-SNAPSHOT/020-network.t b/.gitlab/tests/cram/squashfs/board/turris-omnia_releases_19.07-SNAPSHOT/020-network.t
new file mode 100644 (file)
index 0000000..b8777c9
--- /dev/null
@@ -0,0 +1,17 @@
+Create R alias:
+
+  $ alias R="${CRAM_REMOTE_COMMAND:-}"
+
+Check correct interface setup:
+
+  $ R "ip link | grep ^\\\\d | cut -d: -f2-" | LC_ALL=C sort
+   br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
+   eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 532
+   eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 532
+   eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 532
+   lan0@eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master br-lan state LOWERLAYERDOWN qlen 1000
+   lan1@eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master br-lan state LOWERLAYERDOWN qlen 1000
+   lan2@eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master br-lan state LOWERLAYERDOWN qlen 1000
+   lan3@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-lan state UP qlen 1000
+   lan4@eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master br-lan state LOWERLAYERDOWN qlen 1000
+   lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
diff --git a/.gitlab/tests/cram/squashfs/board/turris-omnia_releases_19.07.7 b/.gitlab/tests/cram/squashfs/board/turris-omnia_releases_19.07.7
new file mode 120000 (symlink)
index 0000000..35d5807
--- /dev/null
@@ -0,0 +1 @@
+turris-omnia_releases_19.07-SNAPSHOT
\ No newline at end of file
diff --git a/.gitlab/tests/cram/squashfs/board/turris-omnia_releases_21.02-SNAPSHOT/020-network.t b/.gitlab/tests/cram/squashfs/board/turris-omnia_releases_21.02-SNAPSHOT/020-network.t
new file mode 100644 (file)
index 0000000..768df0a
--- /dev/null
@@ -0,0 +1,17 @@
+Create R alias:
+
+  $ alias R="${CRAM_REMOTE_COMMAND:-}"
+
+Check correct interface setup:
+
+  $ R "ip link | grep ^\\\\d | cut -d: -f2-" | LC_ALL=C sort
+   br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
+   eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1024
+   eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1508 qdisc mq state UP qlen 1024
+   eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1024
+   lan0@eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master br-lan state LOWERLAYERDOWN qlen 1000
+   lan1@eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master br-lan state LOWERLAYERDOWN qlen 1000
+   lan2@eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master br-lan state LOWERLAYERDOWN qlen 1000
+   lan3@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-lan state UP qlen 1000
+   lan4@eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue master br-lan state LOWERLAYERDOWN qlen 1000
+   lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
diff --git a/.gitlab/tests/cram/squashfs/board/turris-omnia_snapshots b/.gitlab/tests/cram/squashfs/board/turris-omnia_snapshots
new file mode 120000 (symlink)
index 0000000..fb11f8a
--- /dev/null
@@ -0,0 +1 @@
+turris-omnia
\ No newline at end of file
diff --git a/.gitlab/tests/cram/squashfs/build/README.md b/.gitlab/tests/cram/squashfs/build/README.md
new file mode 100644 (file)
index 0000000..c048204
--- /dev/null
@@ -0,0 +1,19 @@
+# Content
+
+Contains tests which could be used on specific build type.
+
+## generic
+
+Tests run on all build types.
+
+## snapshots
+
+Tests run on all snapshot builds.
+
+## releases_19.07-SNAPSHOT
+
+Tests run on 19.07-SNAPSHOT releases.
+
+## releases_19.07.7
+
+Tests run only on 19.07.7 release.
diff --git a/.gitlab/tests/cram/squashfs/build/generic/.keep b/.gitlab/tests/cram/squashfs/build/generic/.keep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/.gitlab/tests/cram/squashfs/build/releases_19.07-SNAPSHOT/.keep b/.gitlab/tests/cram/squashfs/build/releases_19.07-SNAPSHOT/.keep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/.gitlab/tests/cram/squashfs/build/releases_19.07.7 b/.gitlab/tests/cram/squashfs/build/releases_19.07.7
new file mode 120000 (symlink)
index 0000000..46e7539
--- /dev/null
@@ -0,0 +1 @@
+releases_19.07-SNAPSHOT
\ No newline at end of file
diff --git a/.gitlab/tests/cram/squashfs/build/releases_21.02-SNAPSHOT/.keep b/.gitlab/tests/cram/squashfs/build/releases_21.02-SNAPSHOT/.keep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/.gitlab/tests/cram/squashfs/build/snapshots/.keep b/.gitlab/tests/cram/squashfs/build/snapshots/.keep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/.testbed/README.md b/.testbed/README.md
new file mode 100644 (file)
index 0000000..86a7a6c
--- /dev/null
@@ -0,0 +1,7 @@
+# Content
+
+This directory contains bits needed for testbed.
+
+## labgrid
+
+Provides content used during runtime testing on real device using [labgrid](https://labgrid.readthedocs.io/en/latest/) Python testing framework.
diff --git a/.testbed/labgrid/default.yaml b/.testbed/labgrid/default.yaml
new file mode 100644 (file)
index 0000000..93269c0
--- /dev/null
@@ -0,0 +1,133 @@
+targets:
+
+  archer-c7-v5-initramfs:
+    resources:
+      RawSerialPort:
+        port: "/dev/archer-c7-v5"
+    drivers:
+      ExternalPowerDriver:
+        cmd_on: ssh root@uart-relay.testbed.vpn.true.cz power_on 3
+        cmd_off: ssh root@uart-relay.testbed.vpn.true.cz power_off 3
+      SerialDriver: {}
+      ShellDriver:
+        console_ready: Please press Enter to activate this console.
+        prompt: 'root@[\w()]+:[^ ]+ '
+        login_prompt: built-in shell (ash)
+        await_login_timeout: 15
+        username: kingbanik
+      SmallUBootDriver:
+        prompt: 'ath> '
+        boot_expression: 'Hit any key to stop autoboot'
+        init_commands:
+          - setenv serverip 192.168.1.2
+          - setenv ipaddr 192.168.1.1
+          - setenv bootargs debug earlyprintk console=ttyS0,115200
+          - ping 192.168.1.2; ping 192.168.1.2; ping 192.168.1.2
+          - tftpboot 0x81000000 openwrt-ath79-generic-tplink_archer-c7-v5-initramfs-kernel.bin
+      UBootStrategy: {}
+
+  glinet-b1300-initramfs:
+    resources:
+      RawSerialPort:
+        port: "/dev/glinet-b1300"
+    drivers:
+      ExternalPowerDriver:
+        cmd_on: ssh root@uart-relay.testbed.vpn.true.cz power_on 1
+        cmd_off: ssh root@uart-relay.testbed.vpn.true.cz power_off 1
+      SerialDriver: {}
+      ShellDriver:
+        console_ready: Please press Enter to activate this console.
+        prompt: 'root@[\w()]+:[^ ]+ '
+        login_prompt: built-in shell (ash)
+        await_login_timeout: 15
+        username: kingbanik
+      UBootDriver:
+        prompt: '\(IPQ40xx\) # '
+        password: 'gl'
+        password_prompt: 'Hit "gl" key to stop booting'
+        init_commands:
+          - setenv bootdelay 0
+          - setenv serverip 192.168.1.2
+          - setenv ipaddr 192.168.1.1
+          - setenv tftpimage openwrt-ipq40xx-generic-glinet_gl-b1300-initramfs-fit-uImage.itb
+        boot_command_delay: 5
+        boot_command: tftpboot 0x83000000 $tftpimage && bootm 0x83000000
+      UBootStrategy: {}
+
+  glinet-b1300-nor:
+    resources:
+      RawSerialPort:
+        port: "/dev/glinet-b1300"
+    drivers:
+      ExternalPowerDriver:
+        cmd_on: ssh root@uart-relay.testbed.vpn.true.cz power_on 1
+        cmd_off: ssh root@uart-relay.testbed.vpn.true.cz power_off 1
+      SerialDriver: {}
+      ShellDriver:
+        console_ready: Please press Enter to activate this console.
+        prompt: 'root@[\w()]+:[^ ]+ '
+        login_prompt: built-in shell (ash)
+        await_login_timeout: 15
+        username: kingbanik
+      UBootDriver:
+        prompt: '\(IPQ40xx\) # '
+        password: 'gl'
+        password_prompt: 'Hit "gl" key to stop booting'
+        init_commands:
+          - setenv bootdelay 0
+          - setenv serverip 192.168.1.2
+          - setenv ipaddr 192.168.1.1
+        boot_command_delay: 5
+        boot_timeout: 180
+        boot_command: tftpboot 0x84000000 openwrt-ipq40xx-generic-glinet_gl-b1300-squashfs-sysupgrade.bin && sf probe && sf erase 0x180000 0x1e80000 && sf write 0x84000000 0x180000 $filesize && bootipq
+      UBootStrategy: {}
+
+  # needs patched u-boot for emmc r/w https://lists.denx.de/pipermail/u-boot/2021-February/441964.html
+  turris-omnia-emmc:
+    resources:
+      RawSerialPort:
+        port: "/dev/turris-omnia"
+    drivers:
+      ExternalPowerDriver:
+        cmd_on: ssh root@uart-relay.testbed.vpn.true.cz power_on 0
+        cmd_off: ssh root@uart-relay.testbed.vpn.true.cz power_off 0
+      SerialDriver:
+        txdelay: 0.01
+      ShellDriver:
+        console_ready: Please press Enter to activate this console.
+        prompt: 'root@[\w()]+:[^ ]+ '
+        login_prompt: built-in shell (ash)
+        await_login_timeout: 15
+        username: kingbanik
+      UBootDriver:
+        prompt: '=> '
+        init_commands:
+          - setenv bootargs earlyprintk console=ttyS0,115200
+          - setenv set_blkcnt 'setexpr blkcnt ${filesize} + 0x1ff && setexpr blkcnt ${blkcnt} / 0x200'
+          - dhcp ${kernel_addr_r} openwrt-mvebu-cortexa9-cznic_turris-omnia-sysupgrade.img
+        boot_command: run set_blkcnt && mmc dev 0 0 && mmc erase 0 ${blkcnt} && mmc write ${kernel_addr_r} 0 ${blkcnt} && run bootcmd
+      UBootStrategy: {}
+
+  turris-omnia-initramfs:
+    resources:
+      RawSerialPort:
+        port: "/dev/turris-omnia"
+    drivers:
+      ExternalPowerDriver:
+        cmd_on: ssh root@uart-relay.testbed.vpn.true.cz power_on 0
+        cmd_off: ssh root@uart-relay.testbed.vpn.true.cz power_off 0
+      SerialDriver:
+        txdelay: 0.01
+      ShellDriver:
+        console_ready: Please press Enter to activate this console.
+        prompt: 'root@[\w()]+:[^ ]+ '
+        login_prompt: built-in shell (ash)
+        await_login_timeout: 15
+        username: kingbanik
+      UBootDriver:
+        prompt: '=> '
+        init_commands:
+          - setenv bootargs earlyprintk console=ttyS0,115200
+          - dhcp ${kernel_addr_r} openwrt-mvebu-cortexa9-cznic_turris-omnia-initramfs-kernel.bin
+        boot_command: bootm ${kernel_addr_r}
+      UBootStrategy: {}