| #!/bin/bash |
| # Copyright 2019 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. |
| |
| BT_FILE_DEPS=( |
| "tools/devshell/lib/fx-cmd-locator.sh" |
| "tools/devshell/lib/fx-optional-features.sh" |
| "tools/devshell/lib/vars.sh" |
| "tools/devshell/lib/platform.sh" |
| ) |
| |
| source "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/../../lib/vars.sh || exit $? |
| |
| # Replace fx-gen with stub. |
| unset -f fx-gen |
| |
| fx-gen() { |
| return 0 |
| } |
| |
| BT_SET_UP() { |
| local _BUILD_DIR="out/default" |
| echo "${_BUILD_DIR}" > "${BT_TEMP_DIR}/.fx-build-dir" |
| _create_build_dir "$_BUILD_DIR" |
| } |
| |
| _create_build_dir() { |
| local _BUILD_DIR="$1" |
| mkdir -p "${BT_TEMP_DIR}/${_BUILD_DIR}" |
| touch "${BT_TEMP_DIR}/${_BUILD_DIR}/args.gn" |
| touch "${BT_TEMP_DIR}/${_BUILD_DIR}/fx.config" |
| } |
| |
| TEST_environment() { |
| # This variable should be empty. |
| BT_EXPECT_EMPTY "${devshell_lib_dir}" |
| } |
| |
| TEST_fx-warn() { |
| BT_ASSERT_FUNCTION_EXISTS fx-warn |
| |
| # Capture stderr. |
| local result |
| result=$( fx-warn some warning 2>&1 ) |
| BT_EXPECT_STRING_CONTAINS_SUBSTRING "${result}" "some warning" |
| } |
| |
| TEST_fx-error() { |
| BT_ASSERT_FUNCTION_EXISTS fx-error |
| |
| # Capture stderr. |
| local result |
| result=$( fx-error some error 2>&1 ) |
| BT_EXPECT_STRING_CONTAINS_SUBSTRING "${result}" "some error" |
| } |
| |
| TEST_fx-change-build-dir() { |
| BT_ASSERT_FUNCTION_EXISTS fx-change-build-dir |
| |
| local -r BUILD_DIR="out/nondefault" |
| _create_build_dir "$BUILD_DIR" |
| fx-change-build-dir "${BUILD_DIR}" |
| |
| local -r EXPECTED_FILE="${FUCHSIA_DIR}/.fx-build-dir" |
| BT_EXPECT_FILE_CONTAINS "${EXPECTED_FILE}" "${BUILD_DIR}" |
| } |
| |
| TEST_fx-change-build-dir-links-artifacts() { |
| BT_ASSERT_FUNCTION_EXISTS fx-change-build-dir |
| |
| local -r BUILD_DIR="out/nondefault" |
| _create_build_dir "$BUILD_DIR" |
| |
| touch "${BT_TEMP_DIR}/${BUILD_DIR}/compile_commands.json" |
| touch "${BT_TEMP_DIR}/${BUILD_DIR}/rust-project.json" |
| |
| fx-change-build-dir "${BUILD_DIR}" |
| |
| local -r EXPECTED_FILE="${FUCHSIA_DIR}/.fx-build-dir" |
| BT_EXPECT_FILE_CONTAINS "${EXPECTED_FILE}" "${BUILD_DIR}" |
| |
| # The build directory's compile_commands.json and rust-project.json should |
| # now be symlinked to the source root. |
| BT_EXPECT_FILE_EXISTS "${FUCHSIA_DIR}/compile_commands.json" |
| BT_EXPECT_FILE_EXISTS "${FUCHSIA_DIR}/rust-project.json" |
| } |
| |
| TEST_fx-build-dir-if-present() { |
| BT_ASSERT_FUNCTION_EXISTS fx-build-dir-if-present |
| |
| FUCHSIA_BUILD_DIR="" |
| local -r FX_BUILD_DIR_FILE_PATH="${FUCHSIA_DIR}/.fx-build-dir" |
| local -r BUILD_DIR_PATH="out/mybuild" |
| echo "${BUILD_DIR_PATH}" > "${FX_BUILD_DIR_FILE_PATH}" |
| |
| BT_EXPECT fx-build-dir-if-present |
| |
| # Expect an absolute path. |
| BT_EXPECT_EQ "${FUCHSIA_BUILD_DIR}" "${FUCHSIA_DIR}/${BUILD_DIR_PATH}" |
| } |
| |
| TEST_fx-build-config-load() { |
| BT_ASSERT_FUNCTION_EXISTS fx-build-config-load |
| |
| FUCHSIA_BUILD_DIR="out" |
| local -r EXPECT_BUILD_DIR="${FUCHSIA_DIR}/${FUCHSIA_BUILD_DIR}" |
| mkdir -p "${EXPECT_BUILD_DIR}" |
| local -r FX_CONFIG_FILE_PATH="${EXPECT_BUILD_DIR}/fx.config" |
| |
| # Confirm testvar is not set before setting up the config file. |
| BT_EXPECT_EQ "${testvar}" "" |
| local -r TESTVAR_VALUE="my_value" |
| echo "testvar=${TESTVAR_VALUE}" > "${FX_CONFIG_FILE_PATH}" |
| |
| BT_EXPECT fx-build-config-load |
| |
| # fx-build-config-load ensures FUCHSIA_BUILD_DIR is an absolute path. |
| BT_EXPECT_EQ "${FUCHSIA_BUILD_DIR}" "${EXPECT_BUILD_DIR}" |
| |
| # fx-build-config-load should have loaded testvar from fx.config. |
| BT_EXPECT_EQ "${testvar}" "${TESTVAR_VALUE}" \ |
| "testvar has unexpected value (${testvar})" |
| } |
| |
| |
| # Test parsing valid and invalid device names passed to "fx -d" |
| TEST_fx-getdeviceraw-and-isvaliddevice() { |
| # Use subshells (parenthesis) in calls to get-device-raw to avoid premature exit |
| local valids=( |
| "127.0.0.1" "127.0.0.1:8022" |
| ":8122" |
| "strut-wind-ahead-turf" "strut-wind-ahead-turf:8111" |
| "[::1]:22" "[fe80::7:8%eth0]:222" "[fe80::7:8%eth0]" |
| "[fe80::4607:bff:fe68:41c9%zircon1-4]" |
| ) |
| for valid in "${valids[@]}"; do |
| BT_EXPECT is-valid-device "${valid}" |
| BT_EXPECT "(" FUCHSIA_DEVICE_NAME="$valid" get-device-raw ")" > /dev/null |
| done |
| local invalids=( |
| # no brackets: |
| "::1" "::1:22" "fe80::7:8%eth0" "fe80::7:8%eth0:222" |
| # invalid host names: |
| "AAbbb" "aa_bbb" "xyz@bla.com" |
| # more than 7 colons: |
| "[2001:db8:aaaa:bbbb:cccc:dddd:0:1:0]" "[2001:db8:aaaa:bbbb:cccc:dddd:0:1:44f%enx44070ba0044e]" |
| # invalid port numbers: |
| ":122333" ":232a" ":-1" |
| ) |
| for invalid in "${invalids[@]}"; do |
| BT_EXPECT_FAIL is-valid-device "${invalid}" |
| BT_EXPECT_FAIL "(" FUCHSIA_DEVICE_NAME="${invalid}" get-device-raw ")" 2> /dev/null |
| done |
| } |
| |
| # Test extracting port from device name passed to "fx -d" |
| TEST_fx-get-device-ssh-port() { |
| BT_EXPECT_EQ "$(FUCHSIA_DEVICE_NAME="127.0.0.1" get-device-ssh-port)" "" |
| BT_EXPECT_EQ "$(FUCHSIA_DEVICE_NAME="127.0.0.1:8811" get-device-ssh-port)" "8811" |
| BT_EXPECT_EQ "$(FUCHSIA_DEVICE_NAME=":8812" get-device-ssh-port)" "8812" |
| BT_EXPECT_EQ "$(FUCHSIA_DEVICE_NAME="[::1]" get-device-ssh-port)" "" |
| BT_EXPECT_EQ "$(FUCHSIA_DEVICE_NAME="[::1]:22" get-device-ssh-port)" "22" |
| BT_EXPECT_EQ "$(FUCHSIA_DEVICE_NAME="strut-wind-ahead-turf:822" get-device-ssh-port)" "822" |
| BT_EXPECT_EQ "$(FUCHSIA_DEVICE_NAME="[2001:db8:aaaa:bbbb:cccc:dddd:0:44f%enx44070ba0044e]" get-device-ssh-port)" "" |
| |
| # seven colons inside the brackets plus the one prefixing the port, so 8 total |
| BT_EXPECT_EQ "$(FUCHSIA_DEVICE_NAME="[2001:db8:aaaa:bbbb:cccc:dddd:0:44f%enx44070ba0044e]:22" get-device-ssh-port)" "22" |
| } |
| |
| TEST_fx-get-device-addr-resource() { |
| BT_EXPECT_EQ "$(FUCHSIA_DEVICE_NAME="127.0.0.1" get-device-addr-resource)" "127.0.0.1" |
| BT_EXPECT_EQ "$(FUCHSIA_DEVICE_NAME="127.0.0.1:8811" get-device-addr-resource)" "127.0.0.1" |
| BT_EXPECT_EQ "$(FUCHSIA_DEVICE_NAME="[::1]" get-device-addr-resource)" "[::1]" |
| BT_EXPECT_EQ "$(FUCHSIA_DEVICE_NAME="[::1]:22" get-device-addr-resource)" "[::1]" |
| BT_EXPECT_EQ "$(FUCHSIA_DEVICE_NAME="[2001:db8:aaaa:bbbb:cccc:dddd:0:44f%enx44070ba0044e]" get-device-addr-resource)" "[2001:db8:aaaa:bbbb:cccc:dddd:0:44f%enx44070ba0044e]" |
| } |
| |
| TEST_fx-get-device-addr-url() { |
| BT_EXPECT_EQ "$(FUCHSIA_DEVICE_NAME="127.0.0.1" get-device-addr-url)" "127.0.0.1" |
| BT_EXPECT_EQ "$(FUCHSIA_DEVICE_NAME="127.0.0.1:8811" get-device-addr-url)" "127.0.0.1" |
| BT_EXPECT_EQ "$(FUCHSIA_DEVICE_NAME="[::1]" get-device-addr-url)" "[::1]" |
| BT_EXPECT_EQ "$(FUCHSIA_DEVICE_NAME="[::1]:22" get-device-addr-url)" "[::1]" |
| BT_EXPECT_EQ "$(FUCHSIA_DEVICE_NAME="[2001:db8:aaaa:bbbb:cccc:dddd:0:44f%enx44070ba0044e]" get-device-addr-url)" "[2001:db8:aaaa:bbbb:cccc:dddd:0:44f%25enx44070ba0044e]" |
| } |
| |
| TEST_fx-export-device-address() { |
| unset FUCHSIA_DEVICE_NAME |
| unset FX_DEVICE_NAME |
| unset FX_DEVICE_ADDR |
| unset FX_SSH_ADDR |
| unset FX_SSH_PORT |
| |
| export FUCHSIA_DEVICE_NAME="[::2%lo0]:1234" |
| fx-export-device-address |
| |
| BT_EXPECT_EQ "${FX_DEVICE_NAME}" "[::2%lo0]" |
| BT_EXPECT_EQ "${FX_DEVICE_ADDR}" "::2%lo0" |
| BT_EXPECT_EQ "${FX_SSH_ADDR}" "[::2%lo0]" |
| BT_EXPECT_EQ "${FX_SSH_PORT}" "1234" |
| |
| unset -f fx-target-finder-resolve |
| fx-target-finder-resolve() { |
| echo "::3%lo0" |
| } |
| |
| export FUCHSIA_DEVICE_NAME="foo-bar-baz-quux:1234" |
| fx-export-device-address |
| |
| BT_EXPECT_EQ "${FX_DEVICE_NAME}" "foo-bar-baz-quux" |
| BT_EXPECT_EQ "${FX_DEVICE_ADDR}" "::3%lo0" |
| BT_EXPECT_EQ "${FX_SSH_ADDR}" "[::3%lo0]" |
| BT_EXPECT_EQ "${FX_SSH_PORT}" "1234" |
| } |
| |
| # Ensure that fx-zbi uses FUCHSIA_ZBI_COMPRESSION |
| TEST_fx-zbi() { |
| export FUCHSIA_ZBI_COMPRESSION="zstd.max" |
| export FUCHSIA_BUILD_DIR="${BT_TEMP_DIR}/out/default" |
| local zbi="${FUCHSIA_BUILD_DIR}/host/zbi" |
| btf::make_mock "${zbi}" |
| btf::make_mock "${BT_TEMP_DIR}/tools/devshell/list-build-artifacts" |
| cat > "${BT_TEMP_DIR}/tools/devshell/list-build-artifacts.mock_side_effects" << "EOF" |
| if [[ "$@" == "--name zbi --expect-one tools" ]] ; then |
| echo "host/zbi" |
| fi |
| EOF |
| |
| BT_EXPECT fx-zbi |
| source "${zbi}.mock_state" |
| BT_EXPECT_EQ "${BT_MOCK_ARGS[1]}" "--compressed=${FUCHSIA_ZBI_COMPRESSION}" \ |
| "Expected a --compressed=${FUCHSIA_ZBI_COMPRESSION} argument to zbi binary, got '${BT_MOCK_ARGS[@]:1}'" |
| } |
| |
| # Ensure that fx-zbi-default-compression doesn't use FUCHSIA_ZBI_COMPRESSION. |
| TEST_fx-zbi-default-compression() { |
| export FUCHSIA_ZBI_COMPRESSION="zstd.max" |
| export FUCHSIA_BUILD_DIR="${BT_TEMP_DIR}/out/default" |
| local zbi="${FUCHSIA_BUILD_DIR}/host/zbi" |
| btf::make_mock "${zbi}" |
| btf::make_mock "${BT_TEMP_DIR}/tools/devshell/list-build-artifacts" |
| cat > "${BT_TEMP_DIR}/tools/devshell/list-build-artifacts.mock_side_effects" << "EOF" |
| if [[ "$@" == "--name zbi --expect-one tools" ]] ; then |
| echo "host/zbi" |
| fi |
| EOF |
| |
| BT_EXPECT fx-zbi-default-compression |
| source "${zbi}.mock_state" |
| BT_EXPECT_EQ "${#BT_MOCK_ARGS[@]}" "1" \ |
| "Expected no args to zbi binary, got '${BT_MOCK_ARGS[@]:1}'" |
| } |
| |
| TEST_fx-is-bringup() { |
| export FUCHSIA_BUILD_DIR="${BT_TEMP_DIR}" |
| echo 'import("//products/bringup.gni")' > "${BT_TEMP_DIR}/args.gn" |
| BT_EXPECT fx-is-bringup |
| |
| echo ' import("//products/bringup.gni")' > "${BT_TEMP_DIR}/args.gn" |
| BT_EXPECT fx-is-bringup |
| |
| echo 'import("foo") import("//products/bringup.gni")' > "${BT_TEMP_DIR}/args.gn" |
| BT_EXPECT fx-is-bringup |
| |
| echo 'import("//products/core.gni")' > "${BT_TEMP_DIR}/args.gn" |
| BT_EXPECT_FAIL fx-is-bringup |
| |
| echo '#import("//products/bringup.gni")' > "${BT_TEMP_DIR}/args.gn" |
| BT_EXPECT_FAIL fx-is-bringup |
| |
| echo 'import("//products/core.gni") #import("//products/bringup.gni")' > "${BT_TEMP_DIR}/args.gn" |
| BT_EXPECT_FAIL fx-is-bringup |
| } |
| |
| # Ensure that fx-command-run can find and execute a command defined in a |
| # metadata (*.fx) file. |
| TEST_fx-command-run() { |
| local mycmd="${BT_TEMP_DIR}/prebuilt/third_party/mycmdexec" |
| btf::make_mock "${mycmd}" |
| local mymetadata="${BT_TEMP_DIR}/tools/devshell/mycmd.fx" |
| echo "#### EXECUTABLE=\${PREBUILT_3P_DIR}/mycmdexec" > "${mymetadata}" |
| BT_EXPECT fx-command-run mycmd myarg1 |
| source "${mycmd}.mock_state" |
| BT_EXPECT_EQ "${BT_MOCK_ARGS[1]}" "myarg1" \ |
| "Expected a single argument 'myarg1' to mycmd, got '${BT_MOCK_ARGS[@]:1}'" |
| } |
| |
| # Ensure that FX_CALLER is set as expected |
| TEST_fx-caller() { |
| local called_cmd="${BT_TEMP_DIR}/tools/devshell/called_cmd" |
| btf::make_mock "${called_cmd}" |
| { |
| echo "#!/bin/bash" |
| echo 'echo $FX_CALLER' |
| } > "${called_cmd}.mock_side_effects" |
| BT_EXPECT_EQ "$($called_cmd)" "" |
| |
| local caller_run_cmd="${BT_TEMP_DIR}/tools/devshell/caller_run_cmd" |
| btf::make_mock "${caller_run_cmd}" |
| { |
| echo "#!/bin/bash" |
| echo "source ${BT_TEMP_DIR}/tools/devshell/lib/vars.sh || exit \$?" |
| echo "fx-command-run called_cmd" |
| } > "${caller_run_cmd}.mock_side_effects" |
| BT_EXPECT_EQ "$($caller_run_cmd)" "$caller_run_cmd" |
| |
| local caller_exec_cmd="${BT_TEMP_DIR}/tools/devshell/caller_exec_cmd" |
| btf::make_mock "${caller_exec_cmd}" |
| { |
| echo "#!/bin/bash" |
| echo "source ${BT_TEMP_DIR}/tools/devshell/lib/vars.sh || exit \$?" |
| echo "fx-command-exec called_cmd" |
| } > "${caller_exec_cmd}.mock_side_effects" |
| |
| BT_EXPECT_EQ "$($caller_exec_cmd)" "$caller_exec_cmd" |
| } |
| |
| TEST_get-ssh-components() { |
| local manifest="${BT_TEMP_DIR}/.fx-ssh-path" |
| # no manifest |
| BT_EXPECT_FILE_DOES_NOT_EXIST "${manifest}" |
| BT_EXPECT_FAIL get-ssh-privkey 2>/dev/null |
| |
| # invalid manifest |
| touch "${manifest}" |
| BT_EXPECT_FAIL get-ssh-privkey 2>/dev/null |
| |
| local privkey="${BT_TEMP_DIR}/custom_ssh_privkey" |
| local authkey="${BT_TEMP_DIR}/custom_ssh_authkey" |
| |
| # manifest points to non-existent file |
| echo -e "${privkey}\n${authkey}" > "${manifest}" |
| |
| # should fail |
| BT_EXPECT_FAIL get-ssh-privkey >/dev/null 2>&1 |
| |
| # but even failing because files don't exist, it should still print the filenames |
| BT_EXPECT_EQ "$(get-ssh-privkey 2>/dev/null)" "${privkey}" |
| BT_EXPECT_EQ "$(get-ssh-authkeys 2>/dev/null)" "${authkey}" |
| |
| # should succeed when the files exist (regardless of the content of the files) |
| touch "${privkey}" "${authkey}" |
| BT_EXPECT_EQ "$(get-ssh-privkey)" "${privkey}" |
| BT_EXPECT_EQ "$(get-ssh-authkeys)" "${authkey}" |
| } |
| |
| BT_RUN_TESTS "$@" |