# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 OR ISC source tests/ci/common_posix_setup.sh if [ -v CODEBUILD_FUZZING_ROOT ]; then CORPUS_ROOT="${CODEBUILD_FUZZING_ROOT}/fuzzing" else CORPUS_ROOT="${BUILD_ROOT}/mock_efs/fuzzing" fi echo "$CORPUS_ROOT" if [ -v CODEBUILD_BUILD_ID ]; then BUILD_ID=$CODEBUILD_BUILD_ID else # Generate a random string in bash https://unix.stackexchange.com/questions/230673/how-to-generate-a-random-string BUILD_ID=$(tr -dc A-Za-z0-9 &1 | tee "$SUMMARY_LOG" # This gets the status of the fuzz run which determines if we want to fail the build or not, otherwise we'd get the results of tee if [ "${PIPESTATUS[0]}" == 1 ]; then FUZZ_RUN_FAILURE=1 fi # The libfuzzer logs are written to the current working directory and need to be moved after the test is done mv ./*.log "${LOCAL_FUZZ_RUN_LOGS}/." if [ "$FUZZ_RUN_FAILURE" == 1 ]; then FUZZ_TEST_FAILURE_ROOT="${SHARED_FAILURE_ROOT}/${FUZZ_NAME}" mkdir -p "$FUZZ_TEST_FAILURE_ROOT" if [[ "$FUZZ_NAME" == "cryptofuzz" ]]; then for ARTIFACT in "$LOCAL_ARTIFACTS_FOLDER"/*; do base64 $ARTIFACT ARTIFACT_NAME=$(basename "$ARTIFACT") "${FUZZ_TEST_PATH}" --debug "$ARTIFACT" | tee "${LOCAL_FUZZ_RUN_LOGS}/${ARTIFACT_NAME}.log" done fi cp -r "$LOCAL_FUZZ_TEST_ROOT" "$SHARED_FAILURE_ROOT" cp "$FUZZ_TEST_PATH" "${FUZZ_TEST_FAILURE_ROOT}/${FUZZ_NAME}" # If this fuzz run has failed the below metrics won't make a lot of sense, it could fail on the first input and # publish a TestCount of 1 which makes all the metrics look weird echo "${FUZZ_NAME} failed, see the above output for details. For all the logs see ${SHARED_FAILURE_ROOT} in EFS" exit 1 else echo "Fuzz test ${FUZZ_NAME} finished successfully, not copying run logs and run corpus" fi set -e # Step 2 merge any new files from the run corpus and GitHub src corpus into the shared corpus, the first folder is # where to merge the new corpus (SHARED_FUZZ_TEST_CORPUS), the second two are where to read new inputs from # (LOCAL_RUN_CORPUS and SRC_CORPUS). time "${FUZZ_TEST_PATH}" -merge=1 "$SHARED_FUZZ_TEST_CORPUS" "$LOCAL_RUN_CORPUS" "$SRC_CORPUS" # Calculate interesting metrics and post results to CloudWatch, this checks the shared (EFS) corpus after the new test # run corpus has been merged in FINAL_SHARED_CORPUS_FILE_COUNT=$(find "$SHARED_FUZZ_TEST_CORPUS" -type f | wc -l) put_metric_count --metric-name SharedCorpusFileCount --value "$FINAL_SHARED_CORPUS_FILE_COUNT" --dimensions "FuzzTest=$FUZZ_NAME" RUN_CORPUS_FILE_COUNT=$(find "$LOCAL_RUN_CORPUS" -type f | wc -l) put_metric_count --metric-name RunCorpusFileCount --value "$RUN_CORPUS_FILE_COUNT" --dimensions "FuzzTest=$FUZZ_NAME,Platform=$PLATFORM" TEST_COUNT=$(grep -o "stat::number_of_executed_units: [0-9]*" "$SUMMARY_LOG" | awk '{test_count += $2} END {print test_count}') put_metric_count --metric-name TestCount --value "$TEST_COUNT" --dimensions "FuzzTest=$FUZZ_NAME,Platform=$PLATFORM" TESTS_PER_SECOND=$((TEST_COUNT/TIME_FOR_EACH_FUZZ)) put_metric --metric-name TestRate --value "$TESTS_PER_SECOND" --unit Count/Second --dimensions "FuzzTest=$FUZZ_NAME,Platform=$PLATFORM" FEATURE_COVERAGE=$(grep -o "ft: [0-9]*" "$SUMMARY_LOG" | awk '{print $2}' | sort -n | tail -1) put_metric_count --metric-name FeatureCoverage --value "$FEATURE_COVERAGE" --dimensions "FuzzTest=$FUZZ_NAME,Platform=$PLATFORM" BLOCK_COVERAGE=$(grep -o "cov: [0-9]*" "$SUMMARY_LOG" | awk '{print $2}' | sort -n | tail -1) put_metric_count --metric-name BlockCoverage --value "$BLOCK_COVERAGE" --dimensions "FuzzTest=$FUZZ_NAME,Platform=$PLATFORM" echo "${FUZZ_NAME} starting shared ${ORIGINAL_CORPUS_FILE_COUNT} final shared ${FINAL_SHARED_CORPUS_FILE_COUNT} new files ${RUN_CORPUS_FILE_COUNT} total test count ${TEST_COUNT} test rate ${TESTS_PER_SECOND} code coverage ${BLOCK_COVERAGE} feature coverage ${FEATURE_COVERAGE}" }