diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..9477e44 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,141 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2024 Bartosz Golaszewski + +name: CI + +on: + push: + #branches: [main] + pull_request: + #branches: [main] + +jobs: + ptest: + runs-on: ubuntu-22.04 + # Full Yocto builds from a cold cache take several hours. + timeout-minutes: 480 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + # Remove large pre-installed packages that are unused in a Yocto build. + # This reclaims ~15 GB, bringing total available space to ~25 GB. + - name: Free disk space + run: | + sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc + sudo rm -rf /opt/hostedtoolcache/CodeQL + sudo docker image prune --all --force + sudo apt-get remove -y '^aspnetcore-.*' '^dotnet-.*' '^llvm-.*' \ + 'php.*' '^mongodb-.*' '^mysql-.*' azure-cli google-cloud-cli \ + google-chrome-stable firefox powershell mono-devel libgl1-mesa-dri \ + --fix-broken 2>/dev/null || true + sudo apt-get autoremove -y + sudo apt-get clean + df -h + + - name: Install Yocto host dependencies + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + gawk wget git diffstat unzip texinfo gcc build-essential \ + chrpath socat cpio python3 python3-pip python3-pexpect \ + xz-utils debianutils iputils-ping python3-git python3-jinja2 \ + libegl1-mesa libsdl1.2-dev python3-subunit mesa-common-dev \ + zstd liblz4-tool file locales libacl1 sshpass + sudo locale-gen en_US.UTF-8 + + - name: Install kas + run: pip3 install kas + + - name: Restore downloads cache + uses: actions/cache/restore@v4 + with: + path: /home/runner/yocto-downloads + key: yocto-downloads-${{ hashFiles('kas/ci.yml') }} + restore-keys: | + yocto-downloads- + + - name: Restore sstate cache + uses: actions/cache/restore@v4 + with: + path: /home/runner/yocto-sstate + key: yocto-sstate-${{ runner.arch }}-${{ hashFiles('kas/ci.yml') }}-${{ github.sha }} + restore-keys: | + yocto-sstate-${{ runner.arch }}-${{ hashFiles('kas/ci.yml') }}- + yocto-sstate-${{ runner.arch }}- + + - name: Build image + run: kas build kas/ci.yml + + - name: Run ptests in QEMU + timeout-minutes: 30 + run: | + # kas checks out repos next to the project directory; poky ends up + # in the kas work dir (defaults to $GITHUB_WORKSPACE). + POKY_DIR="${GITHUB_WORKSPACE}/poky" + BUILD_DIR="${GITHUB_WORKSPACE}/build" + + source "${POKY_DIR}/oe-init-build-env" "${BUILD_DIR}" + + # Start QEMU with slirp (user-mode) networking; no root or tap device + # needed. runqemu maps host:2222 -> guest:22 by default under slirp. + runqemu qemux86-64 nographic slirp \ + QB_KERNEL_CMDLINE_APPEND="console=ttyS0" & + QEMU_PID=$! + + # Wait up to 5 minutes for SSH to become available. + READY=0 + for i in $(seq 1 60); do + if sshpass -p "" ssh \ + -p 2222 \ + -o StrictHostKeyChecking=no \ + -o ConnectTimeout=5 \ + -o PasswordAuthentication=yes \ + -o PreferredAuthentications=password \ + root@localhost true 2>/dev/null; then + READY=1 + break + fi + sleep 5 + done + + if [ "${READY}" -ne 1 ]; then + echo "Timed out waiting for QEMU to boot" >&2 + kill "${QEMU_PID}" || true + exit 1 + fi + + sshpass -p "" ssh \ + -p 2222 \ + -o StrictHostKeyChecking=no \ + -o PasswordAuthentication=yes \ + -o PreferredAuthentications=password \ + root@localhost \ + ptest-runner gpiod-sysfs-proxy \ + | tee "${GITHUB_WORKSPACE}/ptest-results.txt" + RC=${PIPESTATUS[0]} + + kill "${QEMU_PID}" || true + exit "${RC}" + + - name: Upload ptest results + if: always() + uses: actions/upload-artifact@v4 + with: + name: ptest-results + path: ptest-results.txt + + - name: Save downloads cache + if: always() + uses: actions/cache/save@v4 + with: + path: /home/runner/yocto-downloads + key: yocto-downloads-${{ hashFiles('kas/ci.yml') }} + + - name: Save sstate cache + if: always() + uses: actions/cache/save@v4 + with: + path: /home/runner/yocto-sstate + key: yocto-sstate-${{ runner.arch }}-${{ hashFiles('kas/ci.yml') }}-${{ github.sha }} diff --git a/README.md b/README.md index 49352f2..1afb4d8 100644 --- a/README.md +++ b/README.md @@ -79,3 +79,22 @@ allow to associate a hard-coded base with a GPIO chip by its label. * [sysfs-gpio-shim](https://github.com/info-beamer/sysfs-gpio-shim), written in C. Officially only supports Raspberry Pi. + + +## Testing + +To test this project, you need to build a test image first using OpenEmbedded. + +Install `kas` using the [upstream instructions](https://kas.readthedocs.io/en/latest/userguide/getting-started.html). + +Install other tools required, for instance on debian: +``` +sudo apt install + +TODO +``` + +Then build the image: +``` +kas-container build tests/yocto/gpiod-sysfs-proxy-tests.yml +``` diff --git a/test.md b/test.md new file mode 100644 index 0000000..08bf277 --- /dev/null +++ b/test.md @@ -0,0 +1,66 @@ +# TODO: move into README.md under testing heading + + +Then run: + + +# TODO: remove mkdir and cd ??? +```bash +kas-container build tests/yocto/gpiod-sysfs-proxy-tests.yml +``` + +That should produce: + +# TODO: Wrong path +```bash +build/tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.rootfs.ext4 +``` + +Start a kas shell: + +```bash +kas-container --runtime-args "-v $PWD:/mnt:ro" shell tests/yocto/gpiod-sysfs-proxy-tests.yml +``` + +Boot the image in QEMU: + +```bash +runqemu qemux86-64 core-image-minimal nographic slirp snapshot \ + qemuparams="-virtfs local,path=/mnt,mount_tag=hostshare,security_model=none,id=hostshare" +``` + +Once the VM boots, log in as `root` with an empty password, then run: + +```bash +mount -t 9p -o trans=virtio,version=9p2000.L hostshare /mnt + + +#root@qemux86-64:/usr/lib/gpiod-sysfs-proxy/ptest/tests# cp /mnt/gpiod-sysfs-proxy /usr/bin/gpiod-sysfs-proxy +#systemctl restart gpiod-sysfs-proxy +#root@qemux86-64:/usr/lib/gpiod-sysfs-proxy/ptest/tests# ./gpio-sysfs-compat-tests -v + + +# root@qemux86-64:/usr/lib/gpiod-sysfs-proxy/ptest/tests# ./gpio-sysfs-compat-tests -v +# ptest-runner gpiod-sysfs-proxy + + + +# TODO: didn't try this +# modprobe configfs +# modprobe gpio-sim +# modprobe gpio-mockup +``` + +# TODO: didn't try this +#For an interactive shell over SSH instead of the QEMU console, keep `slirp` and add host forwarding: + +#```bash +#runqemu qemux86-64 core-image-minimal nographic slirp \ +# qemuparams="-m 2048 -smp 4 -netdev user,id=net0,hostfwd=tcp::2222-:22" +#``` +#Then from another terminal: +# +#```bash +#ssh -p 2222 root@localhost +#ptest-runner gpiod-sysfs-proxy +#``` diff --git a/tests/yocto/conf/layer.conf b/tests/yocto/conf/layer.conf new file mode 100644 index 0000000..2fef919 --- /dev/null +++ b/tests/yocto/conf/layer.conf @@ -0,0 +1,11 @@ +BBPATH .= ":${LAYERDIR}" + +BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ + ${LAYERDIR}/recipes-*/*/*.bbappend" + +BBFILE_COLLECTIONS += "gpiod-sysfs-proxy-tests" +BBFILE_PATTERN_gpiod-sysfs-proxy-tests = "^${LAYERDIR}/" +BBFILE_PRIORITY_gpiod-sysfs-proxy-tests = "6" + +# TODO: Fixup +LAYERSERIES_COMPAT_gpiod-sysfs-proxy-tests = "wrynose master" diff --git a/tests/yocto/gpiod-sysfs-proxy-tests.yml b/tests/yocto/gpiod-sysfs-proxy-tests.yml new file mode 100644 index 0000000..e1a2104 --- /dev/null +++ b/tests/yocto/gpiod-sysfs-proxy-tests.yml @@ -0,0 +1,104 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2024 Bartosz Golaszewski + +header: + version: 14 + +machine: qemux86-64 +distro: poky + +target: core-image-minimal + +repos: + bitbake: + url: https://git.openembedded.org/bitbake + branch: master + path: bitbake + layers: + .: disabled + + openembedded-core: + url: https://git.openembedded.org/openembedded-core + branch: master + path: openembedded-core + layers: + meta: + + meta-yocto: + url: https://git.yoctoproject.org/meta-yocto + branch: master + path: meta-yocto + layers: + meta-poky: + + meta-openembedded: + url: https://git.openembedded.org/meta-openembedded + branch: master + path: meta-openembedded + layers: + meta-oe: + meta-python: + meta-networking: + meta-filesystems: + + # TODO: See if we can add the source here rather than mounting via 9pfs ? + gpiod-sysfs-proxy: + path: . + layers: + tests/yocto: + +local_conf_header: + features: | + EXTRA_IMAGE_FEATURES = "allow-empty-password empty-root-password allow-root-login" + EXTRA_IMAGE_FEATURES += "ptest-pkgs" + + DISTRO_FEATURES = "ipv4 xattr zeroconf ldconfig" + DISTRO_FEATURES:append = " ptest" + + INIT_MANAGER = "systemd" + + kernel: | + KERNEL_FEATURES:append = " \ + features/gpio/sim.scc \ + features/gpio/mockup.scc \ + features/gpio/sysfs.scc \ + features/overlayfs/overlayfs.scc \ + " + + packages: | + IMAGE_INSTALL:append = " \ + kernel-module-gpio-sim \ + kernel-module-gpio-mockup \ + kernel-module-configfs \ + " + + IMAGE_INSTALL:append = " libgpiod libgpiodcxx libgpiod-tools" + #IMAGE_INSTALL:append = " libgpiod-cli" + + #PACKAGECONFIG:append:pn-libgpiod = " glib" + #PACKAGECONFIG:append:pn-libgpiod = " dbus" + + #IMAGE_INSTALL:append = " python3-gpiod" + + # TODO: make it install the source from this repo + IMAGE_INSTALL:append = " gpiod-sysfs-proxy" + PACKAGECONFIG:append:pn-gpiod-sysfs-proxy = " sys-class-mount" + + IMAGE_INSTALL:append = " ptest-runner" + + IMAGE_FEATURES += "ssh-server-openssh" + + qemu-virtfs: | + PACKAGECONFIG:append:pn-qemu-system-native = " virtfs" + + build: | + # TODO: remove this; it was for github actions + # Fixed paths so the GitHub Actions cache keys are stable across runs. + #DL_DIR = "/home/runner/yocto-downloads" + #SSTATE_DIR = "/home/runner/yocto-sstate" + DL_DIR = "${TOPDIR}/../downloads" + SSTATE_DIR = "${TOPDIR}/../sstate-cache" + + # TODO: remove this; it was for github actions + #BB_NUMBER_THREADS = "4" + #PARALLEL_MAKE = "-j4" diff --git a/tests/yocto/recipes-kernel/linux/files/kernel-9pfs.cfg b/tests/yocto/recipes-kernel/linux/files/kernel-9pfs.cfg new file mode 100644 index 0000000..23dd2ba --- /dev/null +++ b/tests/yocto/recipes-kernel/linux/files/kernel-9pfs.cfg @@ -0,0 +1,5 @@ +CONFIG_NET_9P=y +CONFIG_NET_9P_VIRTIO=y +CONFIG_9P_FS=y +CONFIG_9P_FS_POSIX_ACL=y +CONFIG_VIRTIO_PCI=y diff --git a/tests/yocto/recipes-kernel/linux/linux-yocto_%.bbappend b/tests/yocto/recipes-kernel/linux/linux-yocto_%.bbappend new file mode 100644 index 0000000..8150966 --- /dev/null +++ b/tests/yocto/recipes-kernel/linux/linux-yocto_%.bbappend @@ -0,0 +1,3 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" + +SRC_URI:append:qemux86-64 = " file://kernel-9pfs.cfg"