Skip to content

Commit

Permalink
dist: add tests for deb packages and fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
matzf committed Dec 14, 2023
1 parent 0643c3d commit b45700f
Show file tree
Hide file tree
Showing 11 changed files with 223 additions and 3 deletions.
3 changes: 2 additions & 1 deletion dist/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ scion_pkg_deb(
],
description = "SCION inter-domain network architecture border router",
executables = {
"//router/cmd/router:router": "/usr/bin/scion-router",
"//router/cmd/router:router": "scion-router",
},
package = "scion-router",
postinst = "debian/scion.postinst",
Expand Down Expand Up @@ -109,6 +109,7 @@ scion_pkg_deb(

multiplatform_filegroup(
name = "deb",
visibility = ["//dist:__subpackages__"],
srcs = [
"control_deb",
"daemon_deb",
Expand Down
4 changes: 3 additions & 1 deletion dist/platform.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ DEFAULT_PLATFORMS = [
"@io_bazel_rules_go//go/toolchain:linux_arm",
]

def multiplatform_filegroup(name, srcs, target_platforms = DEFAULT_PLATFORMS):
def multiplatform_filegroup(name, srcs, target_platforms = DEFAULT_PLATFORMS, **kwargs):
all_platforms = []
for target_platform in target_platforms:
platform_name = target_platform.split(":")[-1]
Expand All @@ -21,6 +21,7 @@ def multiplatform_filegroup(name, srcs, target_platforms = DEFAULT_PLATFORMS):
native.filegroup(
name = name + "_all",
srcs = all_platforms,
**kwargs,
)

# also add the default filegroup, without platform transition, but
Expand All @@ -29,4 +30,5 @@ def multiplatform_filegroup(name, srcs, target_platforms = DEFAULT_PLATFORMS):
name = name,
srcs = srcs,
tags = ["manual"],
**kwargs,
)
2 changes: 2 additions & 0 deletions dist/systemd/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ Description=SCION Control Service
Documentation=https://docs.scion.org
After=network-online.target scion-dispatcher.service
Wants=scion-dispatcher.service
StartLimitBurst=1
StartLimitInterval=1s

[Service]
Type=simple
Expand Down
4 changes: 3 additions & 1 deletion dist/systemd/scion-daemon.service
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ Description=SCION Daemon
Documentation=https://docs.scion.org
After=network-online.target scion-dispatcher.service
Wants=scion-dispatcher.service
StartLimitBurst=1
StartLimitInterval=1s

[Service]
Type=simple
User=scion
Group=scion
ExecStart=/usr/bin/sciond --config /etc/scion/sciond.toml
ExecStart=/usr/bin/scion-daemon --config /etc/scion/sciond.toml
Restart=on-failure

[Install]
Expand Down
2 changes: 2 additions & 0 deletions dist/systemd/scion-dispatcher.service
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
Description=SCION Dispatcher
Documentation=https://docs.scion.org
After=network-online.target
StartLimitBurst=1
StartLimitInterval=1s

[Service]
Type=simple
Expand Down
3 changes: 3 additions & 0 deletions dist/systemd/scion-ip-gateway.service
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ Description=SCION IP Gateway
Documentation=https://docs.scion.org
After=network-online.target scion-daemon.service
Wants=scion-daemon.service
StartLimitBurst=1
StartLimitInterval=1s

[Service]
Type=simple
User=scion
Group=scion
AmbientCapabilities=cap_net_admin
ExecStart=/usr/bin/scion-ip-gateway --config /etc/scion/sig.toml
Restart=on-failure

Expand Down
2 changes: 2 additions & 0 deletions dist/systemd/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
Description=SCION Router
Documentation=https://docs.scion.org
After=network-online.target
StartLimitBurst=1
StartLimitInterval=1s

[Service]
Type=simple
Expand Down
16 changes: 16 additions & 0 deletions dist/test/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
sh_test(
name = "deb_test",
srcs = ["deb_test.sh"],
data = [
"Dockerfile",
"//dist:deb",
],
env = {
"SCION_DEB_PACKAGES": "$(locations //dist:deb)",
"DEBUG": "1",
},
tags = [
"exclusive",
"integration",
],
)
12 changes: 12 additions & 0 deletions dist/test/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM debian:12-slim

# Force debconf (called by apt-get) to be noninteractive
ENV DEBIAN_FRONTEND=noninteractive
RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections

RUN apt-get update && apt-get install --assume-yes systemd libcap2-bin

ENV container docker

# Only "boot" a minimal system with journald and nothing else
CMD ["/bin/systemd", "--unit", "systemd-journald.socket"]
35 changes: 35 additions & 0 deletions dist/test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Test for Debian packages

This is a minimal test for the debian packages built in dist/BUILD.bazel.

### Run

There are two ways to run this test:

```sh
# Build packages to bazel internal directory and run test
bazel test --test_output=streamed //dist/test:deb_test
```

OR

```sh
# Build packages .. or any other way to get the packages into deb/
make dist-deb
# Run the test script
dist/test/deb_test.sh
```


### Scope

The test should determine whether

- the packages can be installed
- the binaries in the packages are runnable
- the systemd units in the packages can be used to interact with the SCION services

The test does **not** attempt to simulate a working SCION network.
The assumption is that if the services installed from the packages
can be started (meaning they don't crash immediately after startup), the
findings of the various acceptence and end-to-end integration tests apply.
143 changes: 143 additions & 0 deletions dist/test/deb_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#!/bin/bash

set -euo pipefail

set -x
if [ -n ${SCION_DEB_PACKAGES+x} ]; then
# Invocation from bazel:
# SCION_DEB_PACKAGES is a space-separated list of filenames of (symlinks to) .deb packages.
# Below we mount this stuff into a docker container, which won't work with symlinks.
# Copy everything into a tmp directory.
tmpdir="${TEST_TMPDIR?}"
cp ${SCION_DEB_PACKAGES} "${tmpdir}"
SCION_DEB_PACKAGES_DIR=$(realpath ${tmpdir})
else
SCION_ROOT=$(realpath $(dirname $0)/../../)
SCION_DEB_PACKAGES_DIR=${SCION_DEB_PACKAGES_DIR:-${SCION_ROOT}/deb}
fi
DEBUG=${DEBUG:-0}
set +x

function cleanup {
docker container rm -f debian-systemd || true
docker image rm --no-prune debian-systemd || true
}
cleanup

if [ "$DEBUG" == 0 ]; then # if DEBUG: keep container debian-systemd running after test
trap cleanup EXIT
fi

# Note: specify absolute path to Dockerfile because docker will not follow bazel's symlinks.
# Luckily we don't need anything else in this directory.
docker build -t debian-systemd -f $(realpath dist/test/Dockerfile) dist/test

# Start container with systemd in PID 1.
# Note: there are ways to avoid --privileged, but its unreliable and appears to depend on the host system
docker run -d --rm --name debian-systemd -t \
--tmpfs /tmp \
--tmpfs /run \
--tmpfs /run/lock \
--tmpfs /run/shm \
-v $SCION_DEB_PACKAGES_DIR:/deb \
--privileged \
debian-systemd:latest

docker exec -i debian-systemd /bin/bash <<'EOF'
set -xeuo pipefail
arch=$(dpkg --print-architecture)
# check that the deb files are all here (avoid cryptic error from apt-get)
stat /deb/scion-{router,control,dispatcher,daemon,ip-gateway,tools}_*_${arch}.deb > /dev/null
# router
apt-get install /deb/scion-router_*_${arch}.deb
cat > /etc/scion/br-1.toml <<INNER_EOF
[general]
id = "br-1"
config_dir = "/etc/scion"
INNER_EOF
cat > /etc/scion/topology.json <<INNER_EOF
{
"isd_as": "1-ff00:0:a",
"mtu": 1472,
"border_routers": {
"br-1": {
"internal_addr": "127.0.0.1:30001"
}
},
"control_service": {
"cs-1": {
"addr": "127.0.0.1:31002"
}
}
}
INNER_EOF
mkdir /etc/scion/keys
echo -n 0123456789abcdef | base64 | tee /etc/scion/keys/master{0,1}.key
systemctl enable --now [email protected]
sleep 1
systemctl status [email protected]
# dispatcher
apt-get install /deb/scion-dispatcher_*_${arch}.deb
systemctl enable --now scion-dispatcher.service
sleep 1
systemctl status scion-dispatcher.service
systemctl stop scion-dispatcher.service
# tools
# Install first so we can directly use them to generate some testcrypto
# This has a depency on the daemon package
apt-get install /deb/scion-tools_*_${arch}.deb /deb/scion-daemon_*_${arch}.deb
pushd /tmp/
scion-pki testcrypto --topo <(cat << INNER_EOF
ASes:
"1-ff00:0:1": {core: true, voting: true, issuing: true, authoritative: true}
"1-ff00:0:a": {cert_issuer: "1-ff00:0:1"}
INNER_EOF
)
cp -r gen/ASff00_0_a/* /etc/scion/
cp gen/ISD1/trcs/* /etc/scion/certs/
popd
# ... (to be continued)
# control
apt-get install /deb/scion-control*_${arch}.deb
cat > /etc/scion/cs-1.toml << INNER_EOF
general.id = "cs-1"
general.config_dir = "/etc/scion"
trust_db.connection = "/var/lib/scion/cs-1.trust.db"
beacon_db.connection = "/var/lib/scion/cs-1.beacon.db"
path_db.connection = "/var/lib/scion/cs-1.path.db"
INNER_EOF
systemctl enable --now [email protected]
sleep 1
systemctl status [email protected]
systemctl is-active scion-dispatcher.service # should be re-started as dependency
systemctl stop [email protected] scion-dispatcher.service
# daemon
systemctl enable --now scion-daemon.service
systemctl status scion-daemon.service
sleep 1
systemctl is-active scion-dispatcher.service # should be re-started as dependency
# ... tools (continued)
# now with the daemon running, we can test `scion` e.g. to inspect our local SCION address
scion address
systemctl stop scion-daemon.service scion-dispatcher.service
# scion-ip-gateway
apt-get install /deb/scion-ip-gateway_*_${arch}.deb
systemctl start scion-ip-gateway.service
sleep 1
# Note: this starts even if the default sig.json is not a valid configuration
systemctl status scion-ip-gateway.service
systemctl is-active scion-dispatcher.service scion-daemon.service # should be re-started as dependency
# Note: the gateway will only create a tunnel device once a session with a
# neighbor is up. This is too complicated to arrange in this test. Instead,
# we just ensure that the process has the required capabilities to do so.
getpcaps $(pidof scion-ip-gateway) | tee /dev/stderr | grep -q "cap_net_admin" || echo "missing capability 'cap_net_admin'"
echo "Success!"
EOF

0 comments on commit b45700f

Please sign in to comment.