blob: 7a66fd99ab4d73e57087f73ff6ebd85467b674d7 [file]
#!/bin/bash -x
# http://g3doc/wireless/android/build_tools/g3doc/public/buildbot#environment-variables
BUILD_NUMBER="${BUILD_NUMBER:-SNAPSHOT}"
# Ensure the distribution directory for artifacts exists
DIST_DIR="${DIST_DIR:-/tmp/dist_directory}"
mkdir -p "${DIST_DIR}"
# Get temp directory
TMP_DIR="${TMPDIR:-/tmp}"
# Get absolute paths
readonly script_dir="$(cd "$(dirname "$0")" && pwd)"
readonly WORKSPACE="$(cd "${script_dir}/../../../.." && pwd)"
readonly bazel_wrapper="${WORKSPACE}/tools/base/bazel/bazel"
readonly script_name="$(basename "$0")"
# Set output dir for mutation testing and other files, files written to dist_dir will be present under artifacts
readonly mutation_testing_dir="${DIST_DIR}/mutation_testing"
readonly mutated_file_metadata_path="${mutation_testing_dir}/mutation-metadata-${BUILD_NUMBER}.txtpb"
readonly impacted_targets_filepath="${mutation_testing_dir}/impacted-targets.txt"
# Set temp dir for mutation testing
readonly temp_mutation_testing_dir="${TMP_DIR}/mutation_testing"
readonly start_hashes_filepath="${temp_mutation_testing_dir}/start-hashes.json"
readonly final_hashes_filepath="${temp_mutation_testing_dir}/final-hashes.json"
# Create mutation testing directory if it does not exist
mkdir -p "${mutation_testing_dir}"
# Create mutation testing temp directory if it does not exist
mkdir -p "${temp_mutation_testing_dir}"
# Bazel configuration for CI builds
readonly config_options="--config=ci --config=remote-exec"
# Common Functions
print_file_as_escaped_string() {
if [[ -f "$1" ]]; then
awk '{printf "%s\\n", $0}' "$1"
else
echo "Error: File not found: $1" >&2
return 1
fi
}
# --- Generate Starting Hashes ---
readonly empty_file="${TMP_DIR}/empty.txt"
echo "" > "${empty_file}"
"${bazel_wrapper}" run //tools/base/bazel:bazel-diff generate-hashes -- \
-w "${WORKSPACE}" \
--includeTargetType \
--modified-filepaths="${empty_file}" \
"${start_hashes_filepath}"
readonly start_generate_hashes_status=$?
if [[ ${start_generate_hashes_status} -ne 0 ]]; then
echo "Error while generating starting hashes, aborting..."
exit 1
fi
# --- 1. Run Mutation Script ---
echo "Running mutation script to prepare for testing..."
"${bazel_wrapper}" \
--max_idle_secs=60 \
run \
${config_options} \
--tool_tag="${script_name}" \
--build_metadata="ab_build_id=${BUILD_NUMBER}" \
//tools/base/bazel/mutation:mutation \
-- \
--metadata_file_path="${mutated_file_metadata_path}"
readonly bazel_mutation_status=$?
if [[ ${bazel_mutation_status} -ne 0 ]]; then
echo "Mutation script failed! Aborting build."
exit 1
fi
echo "Mutation script finished successfully."
# --- Generate Final Hashes ---
# File contains the path of mutated files
mutated_files_filepath="${TMP_DIR}/mutated-files.txt"
# Read mutated-metadata file to get mutated filepath
grep "file_path:" "${mutated_file_metadata_path}" | sed -re "s/file_path: \"(.*)\"/\1/" > "${mutated_files_filepath}"
# Generate final hashes
"${bazel_wrapper}" run //tools/base/bazel:bazel-diff generate-hashes -- \
-w "${WORKSPACE}" \
--includeTargetType \
--modified-filepaths="${mutated_files_filepath}" \
"${final_hashes_filepath}"
readonly final_generate_hashes_status=$?
if [[ ${final_generate_hashes_status} -ne 0 ]]; then
echo "Error while generating final hashes, aborting..."
exit 1
fi
# --- Get Impacted Targets ---
"${bazel_wrapper}" run //tools/base/bazel:bazel-diff get-impacted-targets -- \
--startingHashes="${start_hashes_filepath}" \
--finalHashes="${final_hashes_filepath}" \
--output="${impacted_targets_filepath}" \
--targetType=Rule
# -- Check if Impacted Target File is non-empty ---
if [[ ! -s "${impacted_targets_filepath}" ]]; then
echo "Mutation did not impact any test targets. Marking Mutation Testing as failed."
exit 1
fi
# --- 2. Run Impacted Android Studio Targets ---
echo "Running impacted Android Studio targets..."
# Bazel Command to run all tests
"${bazel_wrapper}" \
test \
${config_options} \
--tool_tag="${script_name}" \
--test_tag_filters="-noci:studio-linux" \
--build_metadata="ab_build_id=${BUILD_NUMBER}" \
--build_metadata="ab_target=studio-mutation-tests" \
--build_metadata="mutated_file=$(print_file_as_escaped_string "${mutated_files_filepath}")" \
--build_metadata="mutated_file_metadata=$(print_file_as_escaped_string "${mutated_file_metadata_path}")" \
--flaky_test_attempts=3 \
--nocache_test_results \
--bes_keywords=ab-postsubmit \
--target_pattern_file="${impacted_targets_filepath}" \
--bes_keywords="cinder_autopush" \
--build_metadata="cinder_pipelines=mutation-testing"
readonly bazel_test_status=$?
readonly BAZEL_EXITCODE_TEST_FAILURES=3
if [[ ${bazel_test_status} -eq ${BAZEL_EXITCODE_TEST_FAILURES} ]]; then
# Mutation-testing plugin documentation: go/adt-cinder/plugins/mutation_testing.md
echo "Tests failed, mutation-testing cinder plugin will process failed target logs."
exit 0
elif [[ ${bazel_test_status} -eq 0 ]]; then
echo "Mutation testing failed: All tests passed, mutation was not caught by any test. Mutation-testing cinder plugin will handle post-processing"
exit 0
else
echo "ERROR: Bazel exited with an unexpected status: ${bazel_test_status}."
exit ${bazel_test_status}
fi