| #!/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. | |
| # | |
| # Common helpers specific for Fuchsia in-tree testing. | |
| btf::setup_fx() { | |
| if [[ -z "${BT_TEMP_DIR}" ]]; then | |
| echo "Cannot proceed, BT_TEMP_DIR is unset" 1>&2 | |
| exit 1 | |
| fi | |
| local with_metrics=0 | |
| if [[ $# -gt 0 && "$1" == "1" ]]; then | |
| with_metrics=1 | |
| fi | |
| local _HOST_OUT_DIR="host_x64" | |
| local _REL_BUILD_DIR="out/default" | |
| local _FUCHSIA_DIR="${BT_TEMP_DIR}" | |
| local _FUCHSIA_BUILD_DIR="${_FUCHSIA_DIR}/${_REL_BUILD_DIR}" | |
| # Fake fuchsia dir configuration. | |
| local _FX="${_FUCHSIA_DIR}/scripts/fx" | |
| BT_ASSERT_FILE_EXISTS "${_FX}" | |
| BT_ASSERT_FILE_EXISTS "${_FUCHSIA_DIR}/tools/devshell/lib/vars.sh" | |
| BT_ASSERT_FILE_EXISTS "${_FUCHSIA_DIR}/tools/devshell/lib/platform.sh" | |
| BT_ASSERT_FILE_EXISTS "${_FUCHSIA_DIR}/tools/devshell/lib/fx-optional-features.sh" | |
| # Fake a build directory with the minimal content so that fx work | |
| mkdir -p "${_FUCHSIA_BUILD_DIR}" "${_FUCHSIA_BUILD_DIR}/${_HOST_OUT_DIR}" \ | |
| "${_FUCHSIA_DIR}/.jiri_root/bin" "${_FUCHSIA_DIR}/.ssh" | |
| ln -s "${_FX}" "${_FUCHSIA_DIR}/.jiri_root/bin/fx" | |
| echo "${_REL_BUILD_DIR}" > "${_FUCHSIA_DIR}/.fx-build-dir" | |
| touch "${_FUCHSIA_BUILD_DIR}/args.gn" | |
| touch "${_FUCHSIA_DIR}/.ssh/fuchsia_ed25519" "${_FUCHSIA_DIR}/.ssh/fuchsia_authorized_keys" | |
| echo -e "${_FUCHSIA_DIR}/.ssh/fuchsia_ed25519\n${_FUCHSIA_DIR}/.ssh/fuchsia_authorized_keys" > "${_FUCHSIA_DIR}/.fx-ssh-path" | |
| cat > "${_FUCHSIA_BUILD_DIR}/fx.config" << EOF | |
| # Generated by fuchsia-mock.sh. | |
| FUCHSIA_BUILD_DIR='${_REL_BUILD_DIR}' | |
| FUCHSIA_ARCH='x64' | |
| FUCHSIA_BOARD_NAME=pc | |
| FUCHSIA_ZBI_COMPRESSION=zstd | |
| HOST_OUT_DIR='${_HOST_OUT_DIR}' | |
| EOF | |
| if (( with_metrics )); then | |
| BT_ASSERT_FILE_EXISTS "${_FUCHSIA_DIR}/tools/devshell/lib/metrics.sh" | |
| else | |
| btf::make_mock "${_FUCHSIA_DIR}/tools/devshell/lib/metrics.sh" | |
| cat > "${_FUCHSIA_DIR}/tools/devshell/lib/metrics.sh.mock_side_effects" <<EOF | |
| function track-command-execution { | |
| : | |
| } | |
| function track-command-finished { | |
| : | |
| } | |
| EOF | |
| fi | |
| echo "${_FX}" | |
| } | |
| btf::setup_fx_with_metrics() { | |
| btf::setup_fx 1 | |
| } | |
| btf::_make_buildtool_mock() { | |
| local rel_path="$1" | |
| local path="${BT_TEMP_DIR}/${rel_path}" | |
| btf::make_mock "${path}" | |
| echo "${path}" | |
| } | |
| btf::make_installed_hosttools_mock() { | |
| local hosttool_name="$1" | |
| btf::_make_buildtool_mock "out/default/host-tools/${hosttool_name}" | |
| } | |
| btf::make_hosttools_mock() { | |
| local hosttool_name="$1" | |
| btf::_make_buildtool_mock "out/default/host_x64/${hosttool_name}" | |
| } | |
| btf::make_zircontools_mock() { | |
| local zircontool_name="$1" | |
| btf::_make_buildtool_mock "out/default.zircon/tools/${zircontool_name}" | |
| } | |
| btf::make_mock_binary() { | |
| local -r _BIN_PATH="$(mktemp -d "${BT_TEMP_DIR}/binpath.XXXXXX")" | |
| local tool_name="$1" | |
| local tool_path="${_BIN_PATH}/${tool_name}" | |
| btf::make_mock "${tool_path}" | |
| echo "${tool_path}" | |
| } | |
| btf::add_binary_to_path() { | |
| local tool_path="$(dirname "$1")" | |
| export PATH="${tool_path}:$PATH" | |
| } | |
| # Verifies that the arguments in BT_MOCK_ARGS match the arguments to this function. | |
| # The number and order of arguments must match, or non-zero is returned. | |
| # If a value of an argument is un-important it can be marked with the string | |
| # _ANY_. This allows for matching arguments that may have unique values, such as temp | |
| # filenames. | |
| # Args: toolname|mock_state_file arg [arg] [arg] ... | |
| # Returns: 0 if found; 1 if not found. | |
| btf::expect-mock-args() { | |
| local tool="$1" | |
| if [[ ! "${tool}" =~ \.mock_state(\.[0-9]+)?$ ]]; then | |
| tool="${tool}.mock_state" | |
| fi | |
| BT_ASSERT_FILE_EXISTS "${tool}" | |
| shift | |
| source "${tool}" | |
| local expected=("$@") | |
| local actual=("${BT_MOCK_ARGS[@]:1}") # ignore the first arg, the mocked command | |
| if [[ ${#actual[@]} -ne ${#expected[@]} ]]; then | |
| btf::_fail 1 "Unexpected number of arguments to ${tool}.\n Expected ${#expected[@]}: ${expected[*]}\n Actual ${#actual[@]}: ${actual[*]}" | |
| return | |
| fi | |
| for (( i=0; i<"${#expected[@]}"; i++ )); do | |
| if [[ "${expected[$i]}" != "_ANY_" ]]; then | |
| if [[ "${actual[$i]}" != "${expected[$i]}" ]]; then | |
| btf::_fail 1 "Unexpected arguments to ${tool}.\n Expected: ${expected[*]}\n Actual: ${actual[*]}" | |
| return | |
| fi | |
| fi | |
| done | |
| return 0 | |
| } | |
| btf::does-mock-args-contain() { | |
| local state_file="$1" | |
| BT_ASSERT_FILE_EXISTS "${state_file}" | |
| shift | |
| source "${state_file}" | |
| local expected=("$@") | |
| local actual=("${BT_MOCK_ARGS[@]}") | |
| local al=${#actual[@]} | |
| local el=${#expected[@]} | |
| if [[ $el -gt $al ]]; then | |
| return 1 | |
| fi | |
| for (( a=1; a<"$(( al - el + 1 ))"; a++ )); do | |
| for (( e=0; e<"${el}"; e++ )); do | |
| local shifted="$((a + e))" | |
| if [[ "${expected[$e]}" != "_ANY_" && "${actual[$shifted]}" != "${expected[$e]}" ]]; then | |
| continue 2 # continue the outer loop | |
| fi | |
| done | |
| # if we got here, we went through all the expected arguments, so success | |
| return 0 | |
| done | |
| return 1 | |
| } | |
| btf::does-mock-args-not-contain() { | |
| local state_file="$1" | |
| BT_ASSERT_FILE_EXISTS "${state_file}" | |
| shift | |
| source "${state_file}" | |
| local expected=("$@") | |
| local actual=("${BT_MOCK_ARGS[@]}") | |
| local al=${#actual[@]} | |
| local el=${#expected[@]} | |
| if [[ $el -gt $al ]]; then | |
| return 0 | |
| fi | |
| for (( a=1; a<"$(( al - el + 1 ))"; a++ )); do | |
| for (( e=0; e<"${el}"; e++ )); do | |
| local shifted="$((a + e))" | |
| if [[ "${expected[$e]}" != "_ANY_" && "${actual[$shifted]}" != "${expected[$e]}" ]]; then | |
| continue 2 # continue the outer loop | |
| fi | |
| done | |
| # if we got here, we went through all the expected arguments, so we found it | |
| return 1 | |
| done | |
| } |