blob: 553918ebb07a8f907cee01fda982e4fae13e5965 [file] [log] [blame]
#!/usr/bin/env bash
#
# Copyright (C) 2022 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
readlink -f / &> /dev/null || readlink() { greadlink "$@" ; } # for MacOS
MYDIR=$(dirname -- "$(readlink -f -- "$0")")
MYPROG=$(basename -- "$0")
source "$MYDIR/lib/lib_helper.sh"
# Visibility tests cases are described using a markdown file.
# Each file has a list of config files specified by file
# markers. The initial state of task configs is created using
# them. Only one of the config file has an inline diff. Gerrit
# change is created by applying that diff to the specified file
# marker and the expected json is asserted by using that change
# as an input to the '--task-preview' switch.
# The syntax for inline diff is similar to diff --unified=MAX_INT.
# All lines start with a leading space and if a specific line is
# part of diff, we use diff indicators (+/-) instead of a leading
# space.
# Example markdown file:
# (Using block comment to better understand the file syntax.)
: <<'END'
# Test case description header
file: `All-Projects.git:refs/meta/config:task.config`
```
[root "Test root"]
applicable = "is:open"
pass = True
```
file: `All-Users:refs/users/some_ref:task/sample.config`
```
[task "NON-SECRET task"]
applicable = is:open
pass = Fail
+ subtasks-external = SECRET
+[external "SECRET"]
+ user = {secret_user}
+ file = secret.config
```
json:
```
{
{
"some": "example"
}
}
END
# (For example above)
# out:
# `All-Projects.git:refs/meta/config:task.config`
# `All-Users:refs/users/some_ref:task/sample.config`
get_file_markers() {
echo "$TEST_DOC" | grep -o "^file: .*" | cut -f2 -d'`'
}
# (For example above)
# in: `All-Projects.git:refs/meta/config:task.config`
# out:
#[root "Test root"]
# applicable = "is:open"
# pass = True
#
# in: json:
# out :
# {
# {
# "some": "example"
# }
# }
get_marker_content() { # marker
local start_line=$(echo "$TEST_DOC" | grep -n "$1" | cut -f1 -d':')
echo "$TEST_DOC" | tail -n+"$start_line" | \
sed '1,/```/d;/```/,$d' | grep -v '```'
}
# file_marker > project
# in: `All-Projects.git:refs/meta/config:task/task.config`
# out: All-Projects.git
get_project_from_marker() {
echo "$WORKSPACE_DIR/$(echo "$1" | cut -f1 -d':')"
}
# file_marker > ref
# in: `All-Projects.git:refs/meta/config:task/task.config`
# out: refs/meta/config
get_ref_from_marker() {
echo "$1" | cut -f2 -d':'
}
# file_marker > file
# in: `All-Projects.git:refs/meta/config:task/task.config`
#out: task/task.config
get_file_from_marker() {
echo "$1" | cut -f3 -d':'
}
# Example input for all diff functions:
#
# [root "Root Preview SECRET external"]
# applicable = is:open
# pass = True
# - subtask = Subtask APPLICABLE
# + subtasks-external = SECRET external
#
# +[external "SECRET external"]
# + user = {secret_user}
# + file = secret.config
# Returns if a config has inline diff or not.
diff_indicators_present() { # file_content
echo "$1" | grep -q "^-\|^+"
}
# file_content_with_diff_indicators > file_content_with_diff_applied
# out:
#[root "Root Preview SECRET external"]
# applicable = is:open
# pass = True
# subtask = Subtask APPLICABLE
diff_apply() {
sed -e '/^-/d' -e 's/^.//'
}
# file_content_with_diff_indicators > file_content_with_diff_reverted
# out:
#[root "Root Preview SECRET external"]
# applicable = is:open
# pass = True
# subtasks-external = SECRET external
#
#[external "SECRET external"]
# user = {secret_user}
# file = secret.config
diff_revert() {
sed -e '/^+/d' -e 's/^.//'
}
config_ensure() { # config_file_path
q git config --list -f "$1" || err "Invalid config file: $1"
}
get_remote() { # project > remote_url
echo "ssh://$SERVER:$PORT/$(basename "$1")"
}
# Gets json from the preview doc and creates
# expected json in workspace to assert later.
create_expected_json() {
local json=$(get_marker_content "json:")
echo "$json" | remove_suites "non-secret" | \
testdoc_2_pjson | ensure json_pp > "$EXPECTED_SECRET"
echo "$json" | remove_suites "secret" | \
testdoc_2_pjson | ensure json_pp > "$EXPECTED_NON_SECRET"
}
test_preview() { # preview_change_number
query --task--all --task--preview "$1,1" "change:1" \
| change_plugins 1 > "$ACTUAL_SECRET"
query -l "$NON_SECRET_USER" --task--all --task--preview "$1,1" "change:1" \
| change_plugins 1 > "$ACTUAL_NON_SECRET"
ROOTS=$(jq -r '.plugins[].roots | .[].name' < "$EXPECTED_SECRET")
results_suite "Visibility Secret Test" "$EXPECTED_SECRET" "$( < "$ACTUAL_SECRET" )"
ROOTS=$(jq -r '.plugins[].roots | .[].name' < "$EXPECTED_NON_SECRET")
results_suite "Visibility Non-Secret Test" "$EXPECTED_NON_SECRET" "$( < "$ACTUAL_NON_SECRET" )"
}
init_configs() {
for marker in $(get_file_markers) ; do
local project="$(get_project_from_marker "$marker")"
local ref="$(get_ref_from_marker "$marker")"
local file="$(get_file_from_marker "$marker")"
local content="$(get_marker_content "$marker")"
local tip_content
q_setup setup_repo "$project" "$(get_remote "$project")" "$ref"
mkdir -p "$(dirname "$project/$file")"
if diff_indicators_present "$content" ; then
CHANGE_FILE_MARKER=$marker
CHANGE_CONTENT=$(echo "$content" | diff_apply)
tip_content=$(echo "$content" | diff_revert)
else
tip_content=$content
fi
echo "$tip_content" > "$project/$file"
config_ensure "$project/$file"
q_setup update_repo "$project" "$(get_remote "$project")" "$ref"
done
}
test_change() {
local project="$(get_project_from_marker "$CHANGE_FILE_MARKER")"
local ref="$(get_ref_from_marker "$CHANGE_FILE_MARKER")"
local file="$(get_file_from_marker "$CHANGE_FILE_MARKER")"
q_setup setup_repo "$project" "$(get_remote "$project")" "$ref"
echo "$CHANGE_CONTENT" > "$project/$file"
config_ensure "$project/$file"
local cnum=$(create_repo_change "$project" "$(get_remote "$project")" "$ref")
create_expected_json
test_preview "$cnum"
}
usage() { # [error_message]
cat <<-EOF
Usage:
"$MYPROG" --server <gerrit_host> --non-secret-user <non-secret user>
--help|-h help text
--server|-s gerrit host
--non-secret-user user who doesn't have permission
to view other user refs.
EOF
[ -n "$1" ] && { echo "Error: $1" ; exit 1 ; }
exit 0
}
while (( "$#" )) ; do
case "$1" in
--help|-h) usage ;;
--server|-s) shift ; SERVER=$1 ;;
--non-secret-user) shift ; NON_SECRET_USER=$1 ;;
*) usage "invalid argument $1" ;;
esac
shift
done
[ -z "$SERVER" ] && usage "You must specify --server"
[ -z "$NON_SECRET_USER" ] && usage "You must specify --non-secret-user"
RESULT=0
PORT=29418
HTTP_PORT=8080
WORKSPACE_DIR=$MYDIR/../target/preview
EXPECTED_SECRET="$WORKSPACE_DIR/expected-secret"
EXPECTED_NON_SECRET="$WORKSPACE_DIR/expected-non-secret"
ACTUAL_SECRET="$WORKSPACE_DIR/actual-secret"
ACTUAL_NON_SECRET="$WORKSPACE_DIR/actual-non-secret"
TEST_DOC_DIR="$MYDIR/../src/main/resources/Documentation/test/task-preview/"
declare -A USERS
declare -A USER_REFS
USERS["{secret_user}"]="$USER"
USER_REFS["{secret_user_ref}"]="$(get_user_ref "$USER")"
USERS["{non_secret_user}"]="$NON_SECRET_USER"
USER_REFS["{non_secret_user_ref}"]="$(get_user_ref "$NON_SECRET_USER")"
mkdir -p "$WORKSPACE_DIR"
trap 'rm -rf "$WORKSPACE_DIR"' EXIT
TESTS=(
"new_root_with_original_with_external_secret_ref.md"
"non-secret_ref_with_external_secret_ref.md"
"root_with_external_non-secret_ref_with_external_secret_ref.md"
"root_with_external_secret_ref.md")
for test in "${TESTS[@]}" ; do
TEST_DOC="$(replace_user_refs < "$TEST_DOC_DIR/$test" | replace_users)"
init_configs
test_change
done
exit $RESULT