blob: 04f687e3db9b756e5e751ca3926fcb4b19eb1fa1 [file] [log] [blame]
#!/bin/bash
# Copyright 2020 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# Tests that verify that fpave correctly reboots a Fuchsia device into Zedboot
# and starts up a bootserver for paving.
set -e
SCRIPT_SRC_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
# shellcheck disable=SC1090
source "${SCRIPT_SRC_DIR}/gn-bash-test-lib.sh"
FPAVE_CMD="${BT_TEMP_DIR}/scripts/sdk/gn/base/bin/fpave.sh"
# Sets up an ssh mock binary on the $PATH of any subshells and creates a stub
# authorized_keys.
set_up_ssh() {
export PATH="${BT_TEMP_DIR}/isolated_path_for:${PATH}"
# This authorized_keys file must not be empty, but its contents aren't used.
echo ssh-ed25519 00000000000000000000000000000000000000000000000000000000000000000000 \
>"${BT_TEMP_DIR}/scripts/sdk/gn/base/testdata/authorized_keys"
}
# Sets up a device-finder mock. The implemented mock aims to produce minimal
# output that parses correctly but is otherwise uninteresting.
set_up_device_finder() {
cat >"${BT_TEMP_DIR}/scripts/sdk/gn/base/tools/device-finder.mock_side_effects" <<"EOF"
while (("$#")); do
case "$1" in
--local)
# Emit a different address than the default so the device and the host can
# have different IP addresses.
echo fe80::1234%coffee
exit
;;
--full)
echo fe80::c0ff:eec0:ffee%coffee coffee-coffee-coffee-coffee
exit
;;
esac
shift
done
echo fe80::c0ff:eec0:ffee%coffee
EOF
}
# Sets up a gsutil mock. The implemented mock creates an empty gzipped tarball
# at the destination of the cp command.
set_up_gsutil() {
cat >"${BT_TEMP_DIR}/scripts/sdk/gn/base/bin/gsutil.mock_side_effects" <<"EOF"
if [[ "$1" != "cp" ]]; then
# Ignore any invocations other than cp.
exit 0
fi
outpath="$3"
cp "${BT_TEMP_DIR}/scripts/sdk/gn/testdata/empty.tar.gz" "${outpath}"
EOF
}
set_up_gsutil_multibucket() {
cat > "${BT_TEMP_DIR}/scripts/sdk/gn/base/bin/gsutil.mock_side_effects" <<"EOF"
if [[ "$1" == "ls" ]]; then
if [[ "${2}" == *unknown.tgz ]]; then
echo "ls: cannot access \'${2}\': No such file or directory"
exit 1
elif [[ "${2}" == gs://fuchsia/development/*image1.tgz ]]; then
echo "${2}"
elif [[ "${2}" == gs://fuchsia/development/*image2.tgz ]]; then
echo "${2}"
elif [[ "${2}" == gs://fuchsia/* ]]; then
echo "gs://fuchsia/development/sdk_id/images/image1.tgz"
echo "gs://fuchsia/development/sdk_id/images/image2.tgz"
echo "gs://fuchsia/development/sdk_id/images/image3.tgz"
elif [[ "${2}" == gs://other/* ]]; then
echo "gs://other/development/sdk_id/images/image4.tgz"
echo "gs://other/development/sdk_id/images/image5.tgz"
echo "gs://other/development/sdk_id/images/image6.tgz"
fi
elif [[ "$1" == "cp" ]]; then
outpath="$3"
mkdir -p "$(dirname "${outpath}")"
cp ../testdata/empty.tar.gz "${outpath}"
fi
EOF
}
# Creates a stub Core SDK hashes file. The filename is based on the SDK version
# in manifest.json.
set_up_sdk_stubs() {
local hash
hash=$(md5sum "${BT_TEMP_DIR}/scripts/sdk/gn/testdata/empty.tar.gz" | cut -d ' ' -f 1)
# The filename is constructed from the Core SDK version ("id") in the
# manifest. See //scripts/sdk/gn/testdata/meta/manifest.json.
local tarball="${BT_TEMP_DIR}/scripts/sdk/gn/base/images/8890373976687374912_generic-x64.tgz"
echo "${hash} ${tarball}" >"${BT_TEMP_DIR}/scripts/sdk/gn/base/images/image/image.md5"
}
# Verifies that the pave script correctly invokes ssh to restart the Fuchsia
# device.
TEST_fpave_restarts_device() {
set_up_ssh
set_up_device_finder
set_up_gsutil
set_up_sdk_stubs
# Run command.
BT_EXPECT gn-test-run-bash-script "${FPAVE_CMD}" \
--authorized-keys "${BT_TEMP_DIR}/scripts/sdk/gn/base/testdata/authorized_keys"
# Verify that the script attempted to reboot the device over SSH.
# shellcheck disable=SC1090
source "${BT_TEMP_DIR}/isolated_path_for/ssh.mock_state"
local expected_args=( _ANY_ "-F" "${BT_TEMP_DIR}/scripts/sdk/gn/base/bin/sshconfig"
"fe80::c0ff:eec0:ffee%coffee" "dm" "reboot-recovery" )
gn-test-check-mock-args "${expected_args[@]}"
# Verify that ssh was only run once.
BT_EXPECT_FILE_DOES_NOT_EXIST "${BT_TEMP_DIR}/isolated_path_for/ssh.mock_state.1"
}
# Verifies that the pave script correctly invokes the pave script from the
# Fuchsia core SDK.
TEST_fpave_starts_paving() {
set_up_ssh
set_up_device_finder
set_up_gsutil
set_up_sdk_stubs
# Run command.
BT_EXPECT gn-test-run-bash-script \
"${FPAVE_CMD}" \
--authorized-keys "${BT_TEMP_DIR}/scripts/sdk/gn/base/testdata/authorized_keys"
# Verify that the pave.sh script from the Fuchsia SDK was started correctly.
# shellcheck disable=SC1090
source "${BT_TEMP_DIR}/scripts/sdk/gn/base/images/image/pave.sh.mock_state"
local expected_args=( _ANY_ --authorized-keys "${BT_TEMP_DIR}/scripts/sdk/gn/base/testdata/authorized_keys" -1 )
gn-test-check-mock-args "${expected_args[@]}"
# Verify that pave.sh was only run once.
BT_EXPECT_FILE_DOES_NOT_EXIST "${BT_TEMP_DIR}/scripts/sdk/gn/base/images/image/pave.sh.mock_state.1"
}
# Verify image names are listed if the image is not found.
TEST_fpave_lists_images() {
set_up_gsutil_multibucket
BT_EXPECT_FAIL gn-test-run-bash-script "${FPAVE_CMD}" --image unknown \
--authorized-keys "${BT_TEMP_DIR}/scripts/sdk/gn/base/testdata/authorized_keys" > list_images_output.txt 2>&1
BT_EXPECT_FILE_CONTAINS_SUBSTRING "list_images_output.txt" "image1 image2 image3"
BT_EXPECT_FAIL gn-test-run-bash-script "${FPAVE_CMD}" \
--authorized-keys "${BT_TEMP_DIR}/scripts/sdk/gn/base/testdata/authorized_keys" \
--bucket other --image unknown > list_images_output.txt 2>&1
BT_EXPECT_FILE_CONTAINS_SUBSTRING "list_images_output.txt" "image4 image5 image6 image1 image2 image3"
}
# Tests that paving the same image back to back does not re-unzip the image. Also tests that changing images
# causes the old image to be deleted before unpackaging.
TEST_fpave_switch_types() {
set_up_ssh
set_up_gsutil_multibucket
set_up_device_finder
BT_EXPECT "${FPAVE_CMD}" --prepare --image image1 --authorized-keys "${BT_TEMP_DIR}/scripts/sdk/gn/base/testdata/authorized_keys" > pave_image1.txt 2>&1
BT_EXPECT_FILE_CONTAINS pave_image1.txt ""
BT_EXPECT_FILE_CONTAINS_SUBSTRING "${BT_TEMP_DIR}/scripts/sdk/gn/base/images/image/image.md5" "8890373976687374912_image1.tgz"
# Same command, should skip download
BT_EXPECT "${FPAVE_CMD}" --prepare --image image1 --authorized-keys "${BT_TEMP_DIR}/scripts/sdk/gn/base/testdata/authorized_keys" > pave_image1_again.txt 2>&1
BT_EXPECT_FILE_CONTAINS pave_image1_again.txt "Skipping download, image exists."
BT_EXPECT_FILE_CONTAINS_SUBSTRING "${BT_TEMP_DIR}/scripts/sdk/gn/base/images/image/image.md5" "8890373976687374912_image1.tgz"
# Switch images, should delete old file.
BT_EXPECT "${FPAVE_CMD}" --prepare --image image2 --authorized-keys "${BT_TEMP_DIR}/scripts/sdk/gn/base/testdata/authorized_keys" > pave_image2.txt 2>&1
BT_EXPECT_FILE_CONTAINS "pave_image2.txt" "WARNING: Removing old image files."
BT_EXPECT_FILE_CONTAINS_SUBSTRING "${BT_TEMP_DIR}/scripts/sdk/gn/base/images/image/image.md5" "8890373976687374912_image2.tgz"
}
# shellcheck disable=SC2034
# Test initialization.
BT_FILE_DEPS=(
scripts/sdk/gn/base/bin/fpave.sh
scripts/sdk/gn/base/bin/fuchsia-common.sh
scripts/sdk/gn/bash_tests/gn-bash-test-lib.sh
)
# shellcheck disable=SC2034
BT_MOCKED_TOOLS=(
scripts/sdk/gn/base/bin/gsutil
scripts/sdk/gn/base/images/image/pave.sh
scripts/sdk/gn/base/tools/device-finder
isolated_path_for/ssh
)
BT_SET_UP() {
mkdir -p "${BT_TEMP_DIR}/scripts/sdk/gn/testdata"
tar czf "${BT_TEMP_DIR}/scripts/sdk/gn/testdata/empty.tar.gz" -C "${BT_TEMP_DIR}/scripts/sdk/gn/base/images" "image"
}
BT_INIT_TEMP_DIR() {
mkdir -p \
"${BT_TEMP_DIR}/scripts/sdk/gn/base/meta" \
"${BT_TEMP_DIR}/scripts/sdk/gn/base/testdata" \
"${BT_TEMP_DIR}/scripts/sdk/gn/bash_tests/data"
# Create a stub SDK manifest.
cp "${BT_DEPS_ROOT}/scripts/sdk/gn/testdata/meta/manifest.json" \
"${BT_TEMP_DIR}/scripts/sdk/gn/base/meta/manifest.json"
}
BT_RUN_TESTS "$@"