Skip to content

Commit

Permalink
ci(spread): support slice testing through Spread (#281)
Browse files Browse the repository at this point in the history
  • Loading branch information
cjdcordeiro authored Jul 23, 2024
1 parent 987415a commit 4373954
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ jobs:
lint:
name: Lint
uses: canonical/chisel-releases/.github/workflows/lint.yaml@main

integration-tests:
name: Integration tests
uses: canonical/chisel-releases/.github/workflows/spread.yaml@main
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# ubuntu-24.04

This is the `ubuntu-24.04` Chisel release.

To learn more about Chisel, Chisel releases and how to contribute to this
branch, please read
[this](https://github.com/canonical/chisel-releases/blob/main/README.md).
7 changes: 7 additions & 0 deletions slices/libpython3.12-stdlib.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ slices:
essential:
- libbz2-1.0_libs
- libc6_libs
# Adding libgcc-s1 here because it is required for the arm arch.
# In practice, libc6 should bring it anyway, BUT, there is a circular
# dependency in the archives, where libc6 depends on libgcc-s1 and
# vice versa. We don't allow that circular dependency to exist in Chisel
# and libgcc-s1 already depends on libc6, so we'll have to include this
# line here, explicitly.
- libgcc-s1_libs
- liblzma5_libs
- libpython3.12-minimal_libs
- media-types_data
Expand Down
74 changes: 74 additions & 0 deletions spread.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
project: chisel-releases

path: /chisel-releases

environment:
PROJECT_PATH: /chisel-releases
SHARED_LIBRARIES: $PROJECT_PATH/tests/spread/lib
PATH: /snap/bin:$PATH:$SHARED_LIBRARIES

exclude:
- .github

backends:
docker:
type: adhoc
allocate: |
echo "Allocating $SPREAD_SYSTEM..."
docker_image=$(echo $SPREAD_SYSTEM | awk -F '-' '{print $1":"$2}')
docker_arch=$(echo $SPREAD_SYSTEM | awk -F '-' '{print $NF}')
docker run --rm -e DEBIAN_FRONTEND=noninteractice \
-e usr=$SPREAD_SYSTEM_USERNAME -e pass=$SPREAD_SYSTEM_PASSWORD \
--name $SPREAD_SYSTEM -d $docker_arch/$docker_image sh -c '
set -x
apt update
apt install -y openssh-server sudo
mkdir /run/sshd
echo "root:$pass" | chpasswd
echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
/usr/sbin/sshd -D
'
# The container will be up really fast, but the CMD might take time to
# run, and Spread will timeout the SSH op after 5 min. So we wait for the
# container during the allocation script.
until docker exec $SPREAD_SYSTEM pgrep sshd
do
sleep 5
done
ADDRESS `docker inspect $SPREAD_SYSTEM --format '{{.NetworkSettings.Networks.bridge.IPAddress}}'`
discard: docker rm -f $SPREAD_SYSTEM
systems:
- ubuntu-24.04-amd64:
password: ubuntu
- ubuntu-24.04-arm64v8:
password: ubuntu
- ubuntu-24.04-arm32v7:
password: ubuntu
- ubuntu-24.04-ppc64le:
password: ubuntu
- ubuntu-24.04-s390x:
password: ubuntu
# Re-enable risvc64 once we have re-enabled this arch for the Ubuntu container
# - ubuntu-24.04-riscv64:
# password: ubuntu

prepare: |
# Deb arch to GOARCH
arch="$(dpkg --print-architecture | sed -e 's/armhf/arm/g' -e 's/ppc64el/ppc64le/g')"
chisel_tar="chisel.tar.gz"
apt install -y curl wget
curl -s https://api.github.com/repos/canonical/chisel/releases/latest \
| awk "/browser_download_url/ && /chisel_v/ && /$arch/" \
| cut -d : -f 2,3 \
| tr -d \" \
| xargs wget -O $chisel_tar
tar -xf $chisel_tar -C /usr/local/bin
prepare-each:
chisel version

suites:
tests/spread/integration/:
summary: Tests common scenarios
13 changes: 13 additions & 0 deletions tests/spread/integration/base-passwd/task.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
summary: Integration tests for base-passwd

execute: |
rootfs="$(install-slices base-passwd_data)"
test -f ${rootfs}/etc/group
! grep FIXME ${rootfs}/etc/group
test -f ${rootfs}/etc/passwd
! grep FIXME ${rootfs}/etc/passwd
test ! -f ${rootfs}/usr/share/base-passwd/group.master
test ! -f ${rootfs}/usr/share/base-passwd/passwd.master
14 changes: 14 additions & 0 deletions tests/spread/integration/python3.12/task.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
summary: Integration tests for Python3.12

environment:
SLICE/core: "core"
SLICE/standard: "standard"

execute: |
# Test different slice installations
echo "SLICE=${SLICE}"
rootfs="$(install-slices python3.12_${SLICE})"
cp test_${SLICE}.py "${rootfs}/"
chroot "$rootfs" python3.12 /test_${SLICE}.py
49 changes: 49 additions & 0 deletions tests/spread/integration/python3.12/test_core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""
Tests some of the core Python functionality
"""

import sys
import os
import socket
import time


def hello_world():
# Asserting the stdout would require additional modules (like StringIO)
# that are not available in the "core" slice. So this test case only tests
# the functionality, but not the outcome.
print("Hello, world!")


def check_python_version():
print("Checking Python version...")
assert sys.version.startswith(
"3.12"
), f"Wrong Python version installed: {sys.version}. Expected 3.12."


def check_file_operations():
print("Checking file operations...")
filename = f"/test-file-{int(time.time())}"

original_content = "This is a test file."
with open(filename, "w") as f:
f.write(original_content)
with open(filename, "r") as f:
content = f.read()
assert content == original_content
os.remove(filename)
assert not os.path.exists(filename)
print(f"File operations are working. Content: {content}")


def check_network_operations():
print("Checking network operations...")
print(socket.gethostname())


if __name__ == "__main__":
hello_world()
check_python_version()
check_file_operations()
check_network_operations()
35 changes: 35 additions & 0 deletions tests/spread/integration/python3.12/test_standard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""
Tests some of the standard Python functionality
"""

import html
import json
import urllib
import uuid


def check_json_loading():
print("Checking JSON loading...")

sample = '{"foo": ["bar"]}'
assert json.loads(sample) == {"foo": ["bar"]}


def check_html_escaping():
print("Checking HTML escaping...")

sample = "Some <sample> & 'text' with \"HTML\" characters"
exp = "Some &lt;sample&gt; &amp; &#x27;text&#x27; with &quot;HTML&quot; characters"
assert html.escape(sample) == exp


def check_uuid_gen():
print("Checking UUID generation...")

assert type(uuid.uuid1().int) == int


if __name__ == "__main__":
check_json_loading()
check_html_escaping()
check_uuid_gen()
10 changes: 10 additions & 0 deletions tests/spread/lib/install-slices
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash -ex

# Installs one or more slices into a dynamically created temporary path.
# Usage: install-slices [<slice>...]
# Returns the path of the chiselled rootfs

tmpdir="$(mktemp -d)"

echo "${tmpdir}"
chisel cut --release "$PROJECT_PATH" --root "$tmpdir" $@

0 comments on commit 4373954

Please sign in to comment.