aboutsummaryrefslogtreecommitdiff
path: root/cli-tests/common.sh
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2020-05-09 14:04:47 -0700
committerEric Biggers <ebiggers@google.com>2020-05-09 14:04:47 -0700
commit3619eed4515cf51161cfa7c57be4f330cd07e377 (patch)
treef09f6f8963088dc05fa62e4a6e4003a8825c697f /cli-tests/common.sh
parent5716215ceae3ab8b49a7b2ba410cb51a82c3176b (diff)
Add cli-tests framework
Add a framework for writing automated tests of the fscrypt command-line tool. See cli-tests/README.md for details.
Diffstat (limited to 'cli-tests/common.sh')
-rw-r--r--cli-tests/common.sh154
1 files changed, 154 insertions, 0 deletions
diff --git a/cli-tests/common.sh b/cli-tests/common.sh
new file mode 100644
index 0000000..fcebfd6
--- /dev/null
+++ b/cli-tests/common.sh
@@ -0,0 +1,154 @@
+#!/bin/bash
+#
+# common.sh - helper functions for fscrypt command-line interface tests
+#
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+#
+
+# Use extra-strict mode.
+set -e -u -o pipefail
+
+# Don't allow running the test scripts directly. They need to be run via
+# run.sh, to set up everything correctly.
+if [ -z "${MNT:-}" ] || [ -z "${MNT_ROOT:-}" ]; then
+ echo 1>&2 "ERROR: This script can only be run via run.sh, not on its own."
+ exit 1
+fi
+
+# Prints an error message, then fails the test by exiting with failure status.
+_fail()
+{
+ [ $# -ne 1 ] && _fail "wrong argument count to ${FUNCNAME[0]}"
+ echo 1>&2 "ERROR: $1"
+ exit 1
+}
+
+# Runs a shell command and expects that it fails.
+_expect_failure()
+{
+ [ $# -ne 1 ] && _fail "wrong argument count to ${FUNCNAME[0]}"
+ if eval "$1"; then
+ _fail "command unexpectedly succeeded: \"$1\""
+ fi
+}
+
+# Prints a message to mark the beginning of the next part of the test.
+_print_header()
+{
+ [ $# -ne 1 ] && _fail "wrong argument count to ${FUNCNAME[0]}"
+ echo
+ echo "# $1"
+}
+
+# Deletes all files on the test filesystems, including all policies and
+# protectors. Leaves the fscrypt metadata directories themselves.
+_reset_filesystems()
+{
+ local mnt
+
+ [ $# -ne 0 ] && _fail "wrong argument count to ${FUNCNAME[0]}"
+
+ for mnt in "$MNT" "$MNT_ROOT"; do
+ rm -rf "${mnt:?}"/* "${mnt:?}"/.fscrypt/{policies,protectors}/*
+ done
+}
+
+# Prints the number of filesystems that have encryption support enabled.
+_get_enabled_fs_count()
+{
+ local count
+
+ [ $# -ne 0 ] && _fail "wrong argument count to ${FUNCNAME[0]}"
+
+ count=$(fscrypt status | awk '/filesystems supporting encryption/ { print $4 }')
+ if [ -z "$count" ]; then
+ _fail "encryption support status line not found"
+ fi
+ echo "$count"
+}
+
+# Prints the number of filesystems that have fscrypt metadata.
+_get_setup_fs_count()
+{
+ local count
+
+ [ $# -ne 0 ] && _fail "wrong argument count to ${FUNCNAME[0]}"
+
+ count=$(fscrypt status | awk '/filesystems with fscrypt metadata/ { print $5 }')
+ if [ -z "$count" ]; then
+ _fail "fscrypt metadata status line not found"
+ fi
+ echo "$count"
+}
+
+# Removes all fscrypt metadata from the given filesystem.
+_rm_metadata()
+{
+ [ $# -ne 1 ] && _fail "wrong argument count to ${FUNCNAME[0]}"
+
+ rm -r "${1:?}/.fscrypt"
+}
+
+# Runs a shell command, ignoring its output (stdout and stderr) if it succeeds.
+# If the command fails, prints its output and fails the test.
+_run_noisy_command()
+{
+ [ $# -ne 1 ] && _fail "wrong argument count to ${FUNCNAME[0]}"
+
+ if ! eval "$1" &> "$TMPDIR/out"; then
+ _fail "Command failed: '$1'. Output was: $(cat "$TMPDIR/out")"
+ fi
+}
+
+# Runs the given shell command as the test user.
+_user_do()
+{
+ [ $# -ne 1 ] && _fail "wrong argument count to ${FUNCNAME[0]}"
+
+ su "$TEST_USER" --command="$1"
+}
+
+# Runs the given shell command as the test user and expects it to fail.
+_user_do_and_expect_failure()
+{
+ [ $# -ne 1 ] && _fail "wrong argument count to ${FUNCNAME[0]}"
+
+ _expect_failure "_user_do '$1'"
+}
+
+# Gives the test a new session keyring which contains the test user's keyring
+# but not root's keyring. Also clears the test user's keyring. This must be
+# called at the beginning of the test script as it may re-execute the script.
+_setup_session_keyring()
+{
+ [ $# -ne 0 ] && _fail "wrong argument count to ${FUNCNAME[0]}"
+
+ # This *should* just use 'keyctl new_session', but that doesn't work if
+ # the session keyring is owned by a user other than root. So instead we
+ # have to use 'keyctl session' and re-execute the script.
+ if [ -z "${FSCRYPT_SESSION_KEYRING_SET:-}" ]; then
+ export FSCRYPT_SESSION_KEYRING_SET=1
+ set +e
+ keyctl session - "$0" |& grep -v '^Joined session keyring'
+ exit "${PIPESTATUS[0]}"
+ fi
+
+ # Link the test user's keyring into the new session keyring.
+ keyctl setperm @s 0x3f000000 # all possessor permissions
+ _user_do "keyctl link @u @s"
+
+ # Clear the test user's keyring.
+ _user_do "keyctl clear @u"
+}