blob: edbc5e19473776fef1eaaf397e7c0d15e2556e42 [file]
#!/bin/bash
# Copyright 2026 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 expected behavior of fx sync
BT_FILE_DEPS=(
"scripts/fx"
"scripts/fx-env.sh"
"tools/devshell/sync"
"tools/devshell/lib/agents.txt"
"tools/devshell/lib/fx-cmd-locator.sh"
"tools/devshell/lib/fx-optional-features.sh"
"tools/devshell/lib/generate-ssh-config.sh"
"tools/devshell/lib/is_invoked_by_agent.sh"
"tools/devshell/lib/platform.sh"
"tools/devshell/lib/vars.sh"
)
declare fx
BT_SET_UP() {
source "${BT_TEMP_DIR}/tools/devshell/tests/lib/fuchsia-mock.sh"
fx="$(btf::setup_fx)"
}
TEST_sync_help() {
local out="${BT_TEMP_DIR}/sync_help.out"
BT_EXPECT _FX_PROC_STATUS="${BT_TEMP_DIR}/nonexistent" "${fx}" sync --help > "${out}"
BT_EXPECT_FILE_CONTAINS_SUBSTRING "${out}" "usage: fx sync"
}
TEST_sync_short_help() {
local out="${BT_TEMP_DIR}/sync_short_help.out"
BT_EXPECT _FX_PROC_STATUS="${BT_TEMP_DIR}/nonexistent" "${fx}" sync -h > "${out}"
BT_EXPECT_FILE_CONTAINS_SUBSTRING "${out}" "usage: fx sync"
}
TEST_sync_unknown_argument() {
local out="${BT_TEMP_DIR}/sync_unknown_arg.out"
BT_EXPECT_FAIL _FX_PROC_STATUS="${BT_TEMP_DIR}/nonexistent" "${fx}" sync --unknown-arg > "${out}" 2>&1
BT_EXPECT_FILE_CONTAINS_SUBSTRING "${out}" "Unknown argument: --unknown-arg"
}
TEST_sync_skips_existing_jiri_root() {
mkdir -p "${BT_TEMP_DIR}/.git" "${BT_TEMP_DIR}/manifests"
touch "${BT_TEMP_DIR}/manifests/platform"
# btf::setup_fx creates a real .jiri_root directory by default.
BT_EXPECT _FX_PROC_STATUS="${BT_TEMP_DIR}/nonexistent" "${fx}" sync
BT_EXPECT_FILE_DOES_NOT_EXIST "${BT_TEMP_DIR}/.fxsync/manifest_state"
}
TEST_sync_fails_without_git_checkout() {
rm -rf "${BT_TEMP_DIR}/.jiri_root"
local out="${BT_TEMP_DIR}/sync_no_git.out"
BT_EXPECT_FAIL _FX_PROC_STATUS="${BT_TEMP_DIR}/nonexistent" "${fx}" sync > "${out}" 2>&1
BT_EXPECT_FILE_CONTAINS_SUBSTRING "${out}" "is not a fuchsia.git checkout"
}
TEST_sync_bootstraps_and_updates_fxsync() {
rm -rf "${BT_TEMP_DIR}/.jiri_root"
mkdir -p "${BT_TEMP_DIR}/.git" "${BT_TEMP_DIR}/manifests"
touch "${BT_TEMP_DIR}/manifests/platform"
local curl_mock
curl_mock="$(btf::make_mock_binary curl)"
cat >"${curl_mock}.mock_side_effects" <<EOF
cat <<'EOS' | base64
mkdir -p "\$1/.jiri_root/bin"
cat >"\$1/.jiri_root/bin/jiri" <<'EOJ'
#!/bin/bash
echo "\$@" >> "${BT_TEMP_DIR}/jiri_calls.txt"
if [[ "\$1" == "update" ]]; then
mkdir -p "${BT_TEMP_DIR}/.jiri_root/update_history"
touch "${BT_TEMP_DIR}/.jiri_root/update_history/latest"
fi
EOJ
chmod +x "\$1/.jiri_root/bin/jiri"
EOS
EOF
btf::add_binary_to_path "${curl_mock}"
local git_mock
git_mock="$(btf::make_mock_binary git)"
cat >"${git_mock}.mock_side_effects" <<'EOF'
if [[ "$*" == *"HEAD:manifests"* ]]; then
printf "%s\ncobalt_rev_123\ncobalt_config_rev_456\n" "${MOCK_MANIFEST_TREE:-manifests_tree_1}"
elif [[ "$*" == *"HEAD:third_party/cobalt_config"* ]]; then
echo "cobalt_config_rev_456"
elif [[ "$*" == *"HEAD:third_party/cobalt"* ]]; then
echo "cobalt_rev_123"
elif [[ "$*" == *"rev-parse HEAD"* ]]; then
echo "${MOCK_HEAD_REV:-head_rev_789}"
fi
EOF
btf::add_binary_to_path "${git_mock}"
# First invocation: initializes stub integration and .fxsync, and runs jiri init + jiri update.
BT_EXPECT _FX_PROC_STATUS="${BT_TEMP_DIR}/nonexistent" "${fx}" sync
BT_EXPECT_FILE_EXISTS "${BT_TEMP_DIR}/integration/MILESTONE"
BT_EXPECT_FILE_EXISTS "${BT_TEMP_DIR}/integration/ctf/all"
BT_EXPECT_FILE_EXISTS "${BT_TEMP_DIR}/.fxsync/manifest_state"
BT_EXPECT_FILE_EXISTS "${BT_TEMP_DIR}/.jiri_manifest"
BT_EXPECT_FILE_CONTAINS_SUBSTRING "${BT_TEMP_DIR}/.jiri_manifest" "cobalt_rev_123"
BT_EXPECT_FILE_CONTAINS_SUBSTRING "${BT_TEMP_DIR}/.jiri_manifest" "cobalt_config_rev_456"
BT_EXPECT_FILE_CONTAINS_SUBSTRING "${BT_TEMP_DIR}/.git/jiri/metadata.v2" "head_rev_789"
BT_EXPECT_FILE_CONTAINS_SUBSTRING "${BT_TEMP_DIR}/.git/JIRI_HEAD" "head_rev_789"
BT_EXPECT_FILE_CONTAINS_SUBSTRING "${BT_TEMP_DIR}/jiri_calls.txt" "init -analytics-opt=false -rewrite-sso-to-https=true -keep-git-hooks=true"
BT_EXPECT_FILE_CONTAINS_SUBSTRING "${BT_TEMP_DIR}/jiri_calls.txt" "project-config -no-update=true"
BT_EXPECT_FILE_CONTAINS_SUBSTRING "${BT_TEMP_DIR}/jiri_calls.txt" "update"
# Second invocation (same manifest state): does not re-run jiri update.
rm -f "${BT_TEMP_DIR}/jiri_calls.txt"
BT_EXPECT _FX_PROC_STATUS="${BT_TEMP_DIR}/nonexistent" "${fx}" sync
BT_EXPECT_FILE_DOES_NOT_EXIST "${BT_TEMP_DIR}/jiri_calls.txt"
# Third invocation (new commit with changed manifests tree): re-syncs jiri to new HEAD.
BT_EXPECT MOCK_MANIFEST_TREE=manifests_tree_2 MOCK_HEAD_REV=head_rev_new _FX_PROC_STATUS="${BT_TEMP_DIR}/nonexistent" "${fx}" sync
BT_EXPECT_FILE_CONTAINS_SUBSTRING "${BT_TEMP_DIR}/.git/jiri/metadata.v2" "head_rev_new"
BT_EXPECT_FILE_CONTAINS_SUBSTRING "${BT_TEMP_DIR}/.git/JIRI_HEAD" "head_rev_new"
BT_EXPECT_FILE_CONTAINS_SUBSTRING "${BT_TEMP_DIR}/jiri_calls.txt" "update"
}
BT_RUN_TESTS "$@"