Skip to content

Implement Request Delay and Retry #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- <HEADER> // IGNORE IT -->
<p align="center">
<img src="./api-test.png" height="200px" alt="api-test log">

</p>

<div align="center">
Expand Down Expand Up @@ -104,6 +104,10 @@ Example:
},
"header": {
"X-per": "1"
},
"retry": {
"count": 1,
"delay": 2000
}
},
"test_case_2": {
Expand All @@ -112,7 +116,8 @@ Example:
"description": "Best GET api",
"query": {
"value": 1
}
},
"delay": 5000
},
"test_case_3": {
"path": "/path_1",
Expand All @@ -132,6 +137,12 @@ Example:

The test cases are present in the `testCases` object. The main url for the api is store in `url` string. If the test cases share common headers add them in root `header` key.

If a test case needs a delay before it is executed add the optional `delay` key with the number of milliseconds to wait as value.

To compansate for random errors or if the API endpoint needs an unknown time to be ready to successfully process the request
a test case can provide the optional `retry` object containing the maximum number of retries as `count` and an optional
`delay` in milliseconds before attempting the next retry.

To pull the `template.json`

```sh
Expand Down
121 changes: 84 additions & 37 deletions api-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ call_api() {
parse_header() {
local RESPONSE=($(echo "$header" | tr '\r' ' ' | sed -n 1p))
local header=$(echo "$header" | sed '1d;$d' | sed 's/: /" : "/' | sed 's/^/"/' | tr '\r' ' ' | sed 's/ $/",/' | sed '1 s/^/{/' | sed '$ s/,$/}/')
RESPONSE_HEADER=$(echo "$header" "{ \"http_version\": \"${RESPONSE[0]}\",
RESPONSE_HEADER=$(echo "$header" "{ \"http_version\": \"${RESPONSE[0]}\",
\"http_status\": \"${RESPONSE[1]}\",
\"http_message\": \"${RESPONSE[@]:2}\",
\"http_response\": \"${RESPONSE[@]:0}\" }" | jq -c -s add)
Expand Down Expand Up @@ -209,12 +209,33 @@ display_results() {

api_factory() {
for TEST_CASE in $@; do
API_ERROR=0
INIT_DELAY_MS="$(jq -r ".testCases.\"$TEST_CASE\".delay | try tonumber catch 0" $FILE)"
INIT_DELAY=$(echo "scale=3; $INIT_DELAY_MS/1000" | bc)
RETRY_COUNT="$(jq -r ".testCases.\"$TEST_CASE\".retry.count | try tonumber catch 0" $FILE)"
RETRY_DELAY_MS="$(jq -r ".testCases.\"$TEST_CASE\".retry.delay | try tonumber catch 0" $FILE)"
RETRY_DELAY=$(echo "scale=3; $RETRY_DELAY_MS/1000" | bc)
echo "${BOLD}Running Case:${RESET} $TEST_CASE"
echo_v "${BOLD}Description: ${RESET}$(jq -r ".testCases.\"$TEST_CASE\".description" $FILE)"
echo_v "${BOLD}Action: ${RESET}$(jq -r ".testCases.\"$TEST_CASE\".method //\"GET\" | ascii_upcase" $FILE) $(jq -r ".testCases.\"$TEST_CASE\".path" $FILE)"
call_api $TEST_CASE
display_results
API_ERROR=1
if [[ $INIT_DELAY_MS -gt 0 ]]; then
echo " ${BOLD}Delaying '$TEST_CASE' for ${INIT_DELAY_MS}ms${RESET}"
sleep $INIT_DELAY
fi
try=0
while [[ $API_ERROR -ne 0 && $try -le $RETRY_COUNT ]]; do
if [[ $try -ne 0 ]]; then
echo " ${BOLD}Retrying Case '$TEST_CASE': ${try}/${RETRY_COUNT}${RESET}"
if [[ RETRY_DELAY_MS -gt 0 ]]; then
echo " ${BOLD}Retry Delay: ${RETRY_DELAY_MS}ms${RESET}"
sleep $RETRY_DELAY
fi
fi
try=$((try + 1))
API_ERROR=0
call_api $TEST_CASE
display_results
done
echo ""
echo ""
done
Expand All @@ -236,43 +257,69 @@ test_factory() {
echo ""
continue
fi
call_api $TEST_CASE
if [[ $API_ERROR == 1 ]]; then
ANY_API_ERROR=1
tput cuf 2
echo -e "${BOLD}${RED}Error running tests after failed api request for '$TEST_CASE' ${RESET}"
echo -e "\n"
continue
fi

local TEST_SCENARIO=$(jq -r ".testCases.\"$TEST_CASE\".expect.header? | select(. !=null and . != {})" $FILE)
if [[ ! -z $TEST_SCENARIO ]]; then
tput cuf 2
echo "${UNDERLINE}Checking condition for header${RESET}"
test_runner $TEST_CASE "header" "$RESPONSE_HEADER"
echo ""
echo ""
INIT_DELAY_MS="$(jq -r ".testCases.\"$TEST_CASE\".delay | try tonumber catch 0" $FILE)"
INIT_DELAY=$(echo "scale=3; $INIT_DELAY_MS/1000" | bc)
RETRY_COUNT="$(jq -r ".testCases.\"$TEST_CASE\".retry.count | try tonumber catch 0" $FILE)"
RETRY_DELAY_MS="$(jq -r ".testCases.\"$TEST_CASE\".retry.delay | try tonumber catch 0" $FILE)"
RETRY_DELAY=$(echo "scale=3; $RETRY_DELAY_MS/1000" | bc)
if [[ $INIT_DELAY_MS -gt 0 ]]; then
echo " ${BOLD}Delaying '$TEST_CASE' for ${INIT_DELAY_MS}ms${RESET}"
sleep $INIT_DELAY
fi
try=0
SAVED_TOTAL_TEST_CASE=-1
SAVED_TOTAL_FAIL_CASE=-1
while [[ $SAVED_TOTAL_FAIL_CASE -lt $TOTAL_FAIL_CASE && $try -le $RETRY_COUNT ]]; do
if [[ $try -eq 0 ]] ; then
SAVED_TOTAL_TEST_CASE=$TOTAL_TEST_CASE
SAVED_TOTAL_FAIL_CASE=$TOTAL_FAIL_CASE
else
TOTAL_TEST_CASE=$SAVED_TOTAL_TEST_CASE
TOTAL_FAIL_CASE=$SAVED_TOTAL_FAIL_CASE
echo "${BOLD}Retrying Case '$TEST_CASE': ${try}/${RETRY_COUNT}${RESET}"
if [[ RETRY_DELAY_MS -gt 0 ]]; then
echo "${BOLD}Retry Delay: ${RETRY_DELAY_MS}ms${RESET}"
sleep $RETRY_DELAY
fi
fi
call_api $TEST_CASE
try=$((try + 1))
if [[ $API_ERROR == 1 ]]; then
ANY_API_ERROR=1
tput cuf 2
echo -e "${BOLD}${RED}Error running tests after failed api request for '$TEST_CASE' ${RESET}"
echo -e "\n"
continue
fi

TEST_SCENARIO=$(jq -r ".testCases.\"$TEST_CASE\".expect.body? | select(. !=null and . != {})" $FILE)
if [[ ! -z $TEST_SCENARIO ]]; then
tput cuf 2
echo "${UNDERLINE}Checking condition for body${RESET}"
test_runner $TEST_CASE "body" "$RESPONSE_BODY"
echo ""
echo ""
fi
local TEST_SCENARIO=$(jq -r ".testCases.\"$TEST_CASE\".expect.header? | select(. !=null and . != {})" $FILE)
if [[ ! -z $TEST_SCENARIO ]]; then
tput cuf 2
echo "${UNDERLINE}Checking condition for header${RESET}"
test_runner $TEST_CASE "header" "$RESPONSE_HEADER"
echo ""
echo ""
fi

TEST_SCENARIO=$(jq -r ".testCases.\"$TEST_CASE\".expect.external? | select(. !=null and . != \"\")" $FILE)
if [[ ! -z $TEST_SCENARIO ]]; then
tput cuf 2
echo "${UNDERLINE}Checking condition from external program${RESET}"
external_script "$TEST_SCENARIO" "$TEST_CASE" "$RESPONSE_BODY" "$RESPONSE_HEADER"
TOTAL_TEST_CASE=$((TOTAL_TEST_CASE + 1))
echo ""
echo ""
fi
TEST_SCENARIO=$(jq -r ".testCases.\"$TEST_CASE\".expect.body? | select(. !=null and . != {})" $FILE)
if [[ ! -z $TEST_SCENARIO ]]; then
tput cuf 2
echo "${UNDERLINE}Checking condition for body${RESET}"
test_runner $TEST_CASE "body" "$RESPONSE_BODY"
echo ""
echo ""
fi

TEST_SCENARIO=$(jq -r ".testCases.\"$TEST_CASE\".expect.external? | select(. !=null and . != \"\")" $FILE)
if [[ ! -z $TEST_SCENARIO ]]; then
tput cuf 2
echo "${UNDERLINE}Checking condition from external program${RESET}"
external_script "$TEST_SCENARIO" "$TEST_CASE" "$RESPONSE_BODY" "$RESPONSE_HEADER"
TOTAL_TEST_CASE=$((TOTAL_TEST_CASE + 1))
echo ""
echo ""
fi
done
done
echo -e "${BOLD}Total tests:\t$TOTAL_TEST_CASE"
if [[ $(($TOTAL_TEST_CASE - $TOTAL_FAIL_CASE)) != 0 ]]; then
Expand Down