aboutsummaryrefslogtreecommitdiff
path: root/tests/agent
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-04-08 14:14:26 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-04-08 14:14:26 +0200
commit36e0c88e7a3912c8a2e6594841172adb9c14525b (patch)
tree909a269ded721a0201a01d3493af6fc11dd75292 /tests/agent
parentcfd31379be5eefb22a72b5ee90ce8fd17a0802b7 (diff)
Implement machine enumeration
Diffstat (limited to 'tests/agent')
-rwxr-xr-xtests/agent/btrfs-cpdir113
-rwxr-xr-xtests/agent/btrfs-rmdir66
-rw-r--r--tests/agent/buildfile8
-rw-r--r--tests/agent/testscript112
4 files changed, 299 insertions, 0 deletions
diff --git a/tests/agent/btrfs-cpdir b/tests/agent/btrfs-cpdir
new file mode 100755
index 0000000..d2dbd43
--- /dev/null
+++ b/tests/agent/btrfs-cpdir
@@ -0,0 +1,113 @@
+#! /usr/bin/env bash
+
+# Copy a directory on (the same) btrfs filesystem. Inside, subvolumes
+# are copied with btrfs subvolume snapshot and everything else with
+# cp --reflink=always.
+#
+# If the -f option is specified and <dst> exists, it is first removed by
+# calling btrfs-rmdir (which is expected to be found next to btrfs-cpdir).
+#
+# Notes:
+#
+# 1. <src> should not be a subvolume (use snapshot directly in this case).
+#
+# 2. Copying of symlinks is not supported (symlinks in submodules are ok).
+#
+# 3. Read-only subvolumes are snapshotted as read-only.
+#
+# Note also that <src> is clones as <dst>, not into <dst> (i.e., like cp -T).
+#
+usage="usage: $0 [-f] <src>/ <dst>/"
+
+owd="$(pwd)"
+trap "{ cd '$owd'; exit 1; }" ERR
+set -o errtrace # Trap in functions.
+
+function info () { echo "$*" 1>&2; }
+function error () { info "$*"; exit 1; }
+
+force=
+
+while [ "$#" -gt 0 ]; do
+ case "$1" in
+ -f)
+ shift
+ force="true"
+ ;;
+ --)
+ break
+ ;;
+ -*)
+ error "unknown option: $1"
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+src="${1%/}"
+dst="${2%/}"
+
+if [ -z "$src" -o -z "$dst" ]; then
+ error "$usage"
+fi
+
+shopt -s nullglob dotglob
+
+function cp_dir () # <src> <dst>
+{
+ local src="$1"
+ local dst="$2"
+
+ mkdir "$dst"
+
+ local s d
+ for s in "$src"/*; do
+
+ d="$dst/${s#$src/}"
+
+ if [ -f "$s" ]; then
+ cp -p --reflink=always "$s" "$d"
+ continue
+ fi
+
+ if [ -d "$s" ]; then
+
+ # See if this is a subvolume: btrfs subvolume list requires root
+ # priviliges so we use the inode number which for subvolumes is always
+ # 256.
+ #
+ if [ "$(stat --format=%i "$s")" -eq 256 ]; then
+ cp_subvol "$s" "$d"
+ else
+ cp_dir "$s" "$d"
+ fi
+ continue
+ fi
+
+ error "$s is not a file/directory, not supported"
+ done
+
+ chmod --reference="$src" "$dst"
+ chown --reference="$src" "$dst"
+}
+
+function cp_subvol () # <src> <dst>
+{
+ local src="$1"
+ local dst="$2"
+
+ local o=()
+ if [ "$(btrfs property get -ts "$src" ro)" = "ro=true" ]; then
+ o+=(-r)
+ fi
+
+ btrfs subvolume snapshot "${o[@]}" "$src" "$dst" >/dev/null
+}
+
+if [ -d "$dst" -a -n "$force" ]; then
+ "$(dirname "$(realpath ${BASH_SOURCE[0]})")/btrfs-rmdir" "$dst"
+fi
+
+cp_dir "$src" "$dst"
diff --git a/tests/agent/btrfs-rmdir b/tests/agent/btrfs-rmdir
new file mode 100755
index 0000000..cc51dc2
--- /dev/null
+++ b/tests/agent/btrfs-rmdir
@@ -0,0 +1,66 @@
+#! /usr/bin/env bash
+
+# Remove a directory on a btrfs filesystem. Inside, subvolumes are removed
+# with btrfs subvolume delete and everything else with rm.
+#
+# Notes:
+#
+# 1. <dir> should not be a subvolume (use delete directly in this case).
+#
+# 2. Read-only subvolumes are changed to read-write before deleting.
+#
+usage="usage: $0 <dir>/"
+
+owd="$(pwd)"
+trap "{ cd '$owd'; exit 1; }" ERR
+set -o errtrace # Trap in functions.
+
+function info () { echo "$*" 1>&2; }
+function error () { info "$*"; exit 1; }
+
+dir="${1%/}"
+
+if [ -z "$dir" ]; then
+ error "$usage"
+fi
+
+shopt -s nullglob dotglob
+
+function rm_dir () # <dir>
+{
+ local dir="$1"
+
+ local p
+ for p in "$dir"/*; do
+
+ if [ -d "$p" -a ! -L "$p" ]; then
+
+ # See if this is a subvolume: btrfs subvolume list requires root
+ # priviliges so we use the inode number which for subvolumes is always
+ # 256.
+ #
+ if [ "$(stat --format=%i "$p")" -eq 256 ]; then
+ rm_subvol "$p"
+ else
+ rm_dir "$p"
+ fi
+ else
+ rm "$p"
+ fi
+ done
+
+ rmdir "$dir"
+}
+
+function rm_subvol () # <dir>
+{
+ local dir="$1"
+
+ if [ "$(btrfs property get -ts "$dir" ro)" = "ro=true" ]; then
+ btrfs property set -ts "$dir" ro false >/dev/null
+ fi
+
+ btrfs subvolume delete "$dir" >/dev/null
+}
+
+rm_dir "$dir"
diff --git a/tests/agent/buildfile b/tests/agent/buildfile
new file mode 100644
index 0000000..1c6d59b
--- /dev/null
+++ b/tests/agent/buildfile
@@ -0,0 +1,8 @@
+# file : tests/agent/buildfile
+# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+# license : MIT; see accompanying LICENSE file
+
+./: ../../bbot/exe{bbot-agent} test{testscript} file{btrfs-cpdir btrfs-rmdir}
+dir{./}: test = ../../bbot/exe{bbot-agent}
+
+include ../../bbot/
diff --git a/tests/agent/testscript b/tests/agent/testscript
new file mode 100644
index 0000000..fa465a4
--- /dev/null
+++ b/tests/agent/testscript
@@ -0,0 +1,112 @@
+# file : tests/agent/testscript
+# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+# license : MIT; see accompanying LICENSE file
+
+# The /build/machines directory should be on a btrfs filesystem and have the
+# following layout and contents:
+#
+# /build/machines/
+# └── default/
+# └── linux-gcc/
+# ├── linux-gcc-1.0/
+# │ └── manifest
+# └── linux-gcc-1.1/
+# └── manifest
+#
+# Notes:
+#
+# - The test must be run serially (@@ TODO: serial directive)
+
+test.options = --verbose 2
+test.arguments = stage 1
+
+cp = $src_base/btrfs-cpdir -f /build/machines.orig /build/machines
+rm = $src_base/btrfs-rmdir /build/machines
+
+: dump-machines
+:
+{
+ m = /build/machines/default/linux-gcc
+
+ test.options += --dump-machines --fake-bootstrap
+
+ +$cp
+
+ : no-current-machine-symlink
+ :
+ $* 123 2>>"EOE"
+ trace: enumerate_machines: skipping $m/: no subvolume link
+ EOE
+
+ ln -T -s linux-gcc-1.0 $m/linux-gcc-1
+
+ : bootstrap
+ :
+ $* 123 >>EOO 2>>~"%EOE%d"
+ : 1
+ id: linux-gcc-1.0
+ name: linux-gcc
+ summary: Linux with GCC
+ EOO
+ %trace: enumerate_machines: btrfs subvolume snapshot $m/linux-gcc-1.0 $m/linux-gcc-stage-\\.+%
+ trace: enumerate_machines: bootstrapping $m/linux-gcc-stage/
+ EOE
+
+ ln -T -f -s linux-gcc-1.1 $m/linux-gcc-1
+
+ : re-bootstrap-machine
+ :
+ $* 123 >>EOO 2>>~"%EOE%d"
+ : 1
+ id: linux-gcc-1.1
+ name: linux-gcc
+ summary: Linux with GCC
+ EOO
+ %trace: enumerate_machines: btrfs subvolume snapshot $m/linux-gcc-1.1 $m/linux-gcc-stage-\\.+%
+ trace: enumerate_machines: re-bootstrapping $m/linux-gcc-stage/: new machine
+ trace: enumerate_machines: btrfs property set -ts $m/linux-gcc-stage ro false
+ trace: enumerate_machines: btrfs subvolume delete $m/linux-gcc-stage
+ EOE
+
+ : re-bootstrap-toolchain
+ :
+ $* 124 >>EOO 2>>~"%EOE%d"
+ : 1
+ id: linux-gcc-1.1
+ name: linux-gcc
+ summary: Linux with GCC
+ EOO
+ %trace: enumerate_machines: btrfs subvolume snapshot $m/linux-gcc-1.1 $m/linux-gcc-stage-\\.+%
+ trace: enumerate_machines: re-bootstrapping $m/linux-gcc-stage/: new toolchain
+ trace: enumerate_machines: btrfs property set -ts $m/linux-gcc-stage ro false
+ trace: enumerate_machines: btrfs subvolume delete $m/linux-gcc-stage
+ EOE
+
+ sed -i -e 's/^(bbot-version):.*/\1: 0/' $m/linux-gcc-stage/manifest
+
+ : re-bootstrap-bbot
+ :
+ $* 124 >>EOO 2>>~"%EOE%d"
+ : 1
+ id: linux-gcc-1.1
+ name: linux-gcc
+ summary: Linux with GCC
+ EOO
+ %trace: enumerate_machines: btrfs subvolume snapshot $m/linux-gcc-1.1 $m/linux-gcc-stage-\\.+%
+ trace: enumerate_machines: re-bootstrapping $m/linux-gcc-stage/: new bbot
+ trace: enumerate_machines: btrfs property set -ts $m/linux-gcc-stage ro false
+ trace: enumerate_machines: btrfs subvolume delete $m/linux-gcc-stage
+ EOE
+
+ sed -i -e 's/^(bbot-version):.*/\1: 99999900/' $m/linux-gcc-stage/manifest
+
+ : re-bootstrap-bbot-newer
+ :
+ $* 124 2>>~"%EOE%d"
+ %trace: enumerate_machines: btrfs subvolume snapshot $m/linux-gcc-1.1 $m/linux-gcc-stage-\\.+%
+ trace: enumerate_machines: ignoring $m/linux-gcc-stage/: old bbot
+ %trace: enumerate_machines: btrfs subvolume delete $m/linux-gcc-stage-\\.+%
+ EOE
+
+ -$rm
+}