blob: 275f619714ad44900979782f6d6b37e612824fe5 [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.
### Test fx verify_default_keys library
BT_FILE_DEPS=(
"tools/devshell/lib/verify-default-keys.sh"
)
declare ssh_mock scp_mock local_gensshkeys_mock sync_remote_keys_intree_mock \
compare_remote_and_local_mock normalize_local_intree_key_mock \
normalize_remote_intree_key_mock
export HOME="${BT_TEMP_DIR}/HOME"
fx-warn() {
echo "$@"
}
fx-error() {
echo "$@"
}
BT_SET_UP() {
source "${BT_TEMP_DIR}/tools/devshell/tests/lib/fuchsia-mock.sh"
ssh_mock=$(btf::make_mock_binary "ssh")
btf::add_binary_to_path "$ssh_mock"
scp_mock=$(btf::make_mock_binary "scp")
btf::add_binary_to_path "$scp_mock"
local_gensshkeys_mock="${BT_TEMP_DIR}/tools/ssh-keys/gen-ssh-keys.sh"
btf::make_mock "${local_gensshkeys_mock}"
# make mock scripts of relevant methods, so that we can play around with
# its inputs/outputs
sync_remote_keys_intree_mock="${BT_TEMP_DIR}/tools/ssh-keys/sync_remote_keys_intree.sh"
compare_remote_and_local_mock="${BT_TEMP_DIR}/tools/ssh-keys/compare_remote_and_local.sh"
normalize_remote_intree_key_mock="${BT_TEMP_DIR}/tools/ssh-keys/normalize_remote_intree_key.sh"
normalize_local_intree_key_mock="${BT_TEMP_DIR}/tools/ssh-keys/normalize_local_intree_key.sh"
btf::make_mock "${sync_remote_keys_intree_mock}"
btf::make_mock "${compare_remote_and_local_mock}"
btf::make_mock "${normalize_remote_intree_key_mock}"
btf::make_mock "${normalize_local_intree_key_mock}"
{
echo "function sync_remote_keys_intree { ${sync_remote_keys_intree_mock} --description \"\$@\"; }"
echo "function compare_remote_and_local { ${compare_remote_and_local_mock} \"\$@\"; }"
echo "function normalize_remote_intree_key { ${normalize_remote_intree_key_mock} \"\$@\"; }"
echo "function normalize_local_intree_key { ${normalize_local_intree_key_mock} \"\$@\"; }"
} >> "${BT_TEMP_DIR}/tools/devshell/lib/verify-default-keys.sh"
source "${BT_TEMP_DIR}/tools/devshell/lib/verify-default-keys.sh"
}
# test if local keys are copied to remote if necessary
TEST_sshkeys-localhas-remotedoesnt() {
# key exists in local
echo 0 > "${normalize_local_intree_key_mock}.mock_status"
# key does not exist in remote
echo 1 > "${normalize_remote_intree_key_mock}.mock_status"
local out="${BT_TEMP_DIR}/output.log"
mkdir -p "$HOME/.ssh"
echo "myauthkeys mock" > "$HOME/.ssh/fuchsia_authorized_keys"
# check if verify_default_keys executes with success status
BT_EXPECT verify_default_keys "$BT_TEMP_DIR" "myhost" "fuchsia" >>${out} 2>&1
# check if scp was executed as expected
btf::expect-mock-args "${scp_mock}" -q -p \
"$HOME/.ssh/fuchsia_ed25519" "$HOME/.ssh/fuchsia_ed25519.pub" "myhost:.ssh/"
# check if ssh was executed as expected
btf::expect-mock-args "${ssh_mock}" myhost "cat >> .ssh/fuchsia_authorized_keys"
}
# test if remote keys are copied to local if necessary
TEST_sshkeys-remotehas-localdoesnt() {
# key exists in remote
echo 0 > "${normalize_remote_intree_key_mock}.mock_status"
# key does not exist in local
echo 1 > "${normalize_local_intree_key_mock}.mock_status"
local out="${BT_TEMP_DIR}/output.log"
# check if verify_default_keys executes with success status
BT_EXPECT verify_default_keys "$BT_TEMP_DIR" "myhost" "fuchsia" >>${out} 2>&1
# check if scp was executed as expected
btf::expect-mock-args "${scp_mock}" -q -p \
"myhost:.ssh/fuchsia_ed25519" "myhost:.ssh/fuchsia_ed25519.pub" "$HOME/.ssh"
# check if ssh was executed as expected
btf::expect-mock-args "${ssh_mock}" myhost cat .ssh/fuchsia_authorized_keys
}
# test if verify-default-keys fail if keys exist on remote and local but differ
TEST_sshkeys-remotehas-localhas-mismatch() {
# key exists in remote
echo 0 > "${normalize_remote_intree_key_mock}.mock_status"
# key exists in local
echo 0 > "${normalize_local_intree_key_mock}.mock_status"
# keys don't match
echo 1 > "${compare_remote_and_local_mock}.mock_status"
local out="${BT_TEMP_DIR}/output.log"
# check if verify_default_keys executes with fail status
# a subshell is needed because of 'exit' statements inside verify_default_keys
BT_EXPECT_FAIL "( verify_default_keys \"$BT_TEMP_DIR\" myhost fuchsia )" >>${out} 2>&1
}
# test if verify-default-keys succeeds if keys exist on remote and local and are
# the same
TEST_sshkeys-remotehas-localhas() {
# key exists in remote
echo 0 > "${normalize_remote_intree_key_mock}.mock_status"
# key exists in local
echo 0 > "${normalize_local_intree_key_mock}.mock_status"
# keys match
echo 0 > "${compare_remote_and_local_mock}.mock_status"
local out="${BT_TEMP_DIR}/output.log"
# check if verify_default_keys executes with success status
BT_EXPECT verify_default_keys "$BT_TEMP_DIR" myhost fuchsia >>${out} 2>&1
}
# test if a new key is generated in remote if no keys exist anywhere
# and if the key is copied to local after being generated
TEST_sshkeys-nokeys() {
# no key in remote
echo 1 > "${normalize_remote_intree_key_mock}.mock_status"
# no key in local
echo 1 > "${normalize_local_intree_key_mock}.mock_status"
local out="${BT_TEMP_DIR}/output.log"
# check if verify_default_keys executes with success status
BT_EXPECT verify_default_keys "$BT_TEMP_DIR" myhost fuchsia >>${out} 2>&1
# check if remote gen-ssh-keys was executed
btf::expect-mock-args "${sync_remote_keys_intree_mock}" "--description" _ANY_
# check if scp was executed as expected
btf::expect-mock-args "${scp_mock}" -q -p \
"myhost:.ssh/fuchsia_ed25519" "myhost:.ssh/fuchsia_ed25519.pub" "$HOME/.ssh"
# check if ssh was executed as expected
btf::expect-mock-args "${ssh_mock}" myhost cat .ssh/fuchsia_authorized_keys
}
# test if scp is executed with the expected "-o ControlPath" if "-S" is
# specified in the ssh_args argument. "-S" is the equivalent of
# "-o ControlPath" for "ssh", but it is not supported in "scp", so
# verify_default_keys converts it.
TEST_sshkeys-controlpath-scp() {
# key exists in remote
echo 0 > "${normalize_remote_intree_key_mock}.mock_status"
# key does not exist in local
echo 1 > "${normalize_local_intree_key_mock}.mock_status"
local out="${BT_TEMP_DIR}/output.log"
# check if verify_default_keys executes with success status
BT_EXPECT verify_default_keys "$BT_TEMP_DIR" myhost fuchsia -S mycontrolfile >>${out} 2>&1
# check if scp was executed as expected, with "-o ControlPath" instead of "-S"
btf::expect-mock-args "${scp_mock}" -o ControlPath=mycontrolfile -q -p \
"myhost:.ssh/fuchsia_ed25519" "myhost:.ssh/fuchsia_ed25519.pub" "$HOME/.ssh"
# check if ssh was executed as expected, with "-o ControlPath" instead of "-S"
btf::expect-mock-args "${ssh_mock}" -o ControlPath=mycontrolfile myhost cat .ssh/fuchsia_authorized_keys
}
# test if the code path executes fine with an empty ssh_args. If not
# handled properly, empty arrays crash the old bash version that comes
# with Mac if "set -u" is used, like it is used by GN SDK, so if this
# test passes, the ssh_args array is being handled correctly.
TEST_sshkeys-empty-ssharg() {
# key exists in remote
echo 0 > "${normalize_remote_intree_key_mock}.mock_status"
# key exists in local
echo 0 > "${normalize_local_intree_key_mock}.mock_status"
# keys match
echo 0 > "${compare_remote_and_local_mock}.mock_status"
local out="${BT_TEMP_DIR}/output.log"
# check if verify_default_keys executes with success status
(
set -u
verify_default_keys "$BT_TEMP_DIR" myhost fuchsia >>${out} 2>&1
status=$?
)
BT_EXPECT_GOOD_STATUS $status "verify_default_keys failed"
# no output is expected. If empty ssh_args is not handled properly,
# on old Bash scripts the code above will print an error ("Unbound variable")
# although the exit code will still be valid.
BT_EXPECT_FILE_CONTAINS ${out} ""
}
BT_RUN_TESTS "$@"