Skip to content

Add integration tests #1

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

Merged
merged 1 commit into from
Feb 8, 2023
Merged
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: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM registry.access.redhat.com/ubi8/ubi:8.1

WORKDIR /tests

COPY main.sh .
COPY testcases/smoke_test.sh ./testcases/

RUN yum -y install wget
RUN yum -y install jq

RUN wget https://github.com/mingrammer/flog/releases/download/v0.4.3/flog_0.4.3_linux_amd64.tar.gz \
&& tar -xvf flog_0.4.3_linux_amd64.tar.gz \
&& cp flog /usr/local/bin

ENTRYPOINT ["./main.sh"]
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## Quest

This repository contains integration tests and load generation tests for Parseable server. Tests are written in shell script and bundled in a container.

### Build test container locally

```
docker build . -t parseable/test:edge
```

### Running tests

Use the below format to run tests against a Parseable server. The first argument is the test name, the second argument is the server URL, the third argument is the username and the fourth argument is the password.

```
docker run parseable/test:edge smoke http://demo.parseable.io parseable parseable
```
33 changes: 33 additions & 0 deletions main.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/sh
#
# Parseable Server (C) 2023 Cloudnatively Pvt. Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

mode=$1
endpoint=$2
username=$3
password=$4

run_smoke_test () {
stream_name=$(head /dev/urandom | tr -dc a-z | head -c10)
./testcases/smoke_test.sh "$endpoint" "$stream_name" "$username" "$password"
return $?
}

case "$mode" in
"smoke") run_smoke_test
;;
esac
300 changes: 300 additions & 0 deletions testcases/smoke-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
#!/bin/sh
#
# Parseable Server (C) 2023 Cloudnatively Pvt. Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

parseable_url=$1
stream_name=$2
username=$3
password=$4

events=50
input_file=$PWD/input.json

curl_std_opts=( -sS --header 'Content-Type: application/json' -w '\n\n%{http_code}' -u "$username":"$password" )

alert_body='{"alerts":[{"name":"server-fail-alert1","message":"server reported error status","rule":{"field":"http_status","contains":"500","repeats":5,"within":"10m"},"target":[{"name":"slack-target","server_url":"http://mailgun.com","api_key":"xxxx"}]}]}'

schema_body='{"fields":[{"name":"host","data_type":"Utf8","nullable":true,"dict_id":0,"dict_is_ordered":false},{"name":"user-identifier","data_type":"Utf8","nullable":true,"dict_id":0,"dict_is_ordered":false},{"name":"datetime","data_type":"Utf8","nullable":true,"dict_id":0,"dict_is_ordered":false},{"name":"method","data_type":"Utf8","nullable":true,"dict_id":0,"dict_is_ordered":false},{"name":"request","data_type":"Utf8","nullable":true,"dict_id":0,"dict_is_ordered":false},{"name":"protocol","data_type":"Utf8","nullable":true,"dict_id":0,"dict_is_ordered":false},{"name":"status","data_type":"Int64","nullable":true,"dict_id":0,"dict_is_ordered":false},{"name":"bytes","data_type":"Int64","nullable":true,"dict_id":0,"dict_is_ordered":false},{"name":"referer","data_type":"Utf8","nullable":true,"dict_id":0,"dict_is_ordered":false},{"name":"labels","data_type":"Utf8","nullable":true,"dict_id":0,"dict_is_ordered":false}]}'

# Generate events using flog (https://github.com/mingrammer/flog) and store it in input.json file
create_input_file () {
flog -f json -n "$events" -t log -o "$input_file"
sleep 2
sed -i '1s/^/[/;$!s/$/,/;$s/$/]/' "$input_file"
return $?
}

# Create stream
create_stream () {
response=$(curl "${curl_std_opts[@]}" --request PUT "$parseable_url"/api/v1/logstream/"$stream_name")

if [ $? -ne 0 ]; then
printf "Failed to create log stream %s with exit code: %s\n" "$stream_name" "$?"
printf "Test create_stream: failed\n"
exit 1
fi

http_code=$(tail -n1 <<< "$response")
if [ "$http_code" -ne 200 ]; then
printf "Failed to create log stream %s with http code: %s and response: %s\n" "$stream_name" "$http_code" "$content"
printf "Test create_stream: failed\n"
exit 1
fi

content=$(sed '$ d' <<< "$response")
if [ "$content" != "Created log stream $stream_name" ]; then
printf "Failed to create log stream $stream_name with response: %s\n" "$content"
printf "Test create_stream: failed\n"
exit 1
fi

printf "Test create_stream: successful\n"
return 0
}

# Post log data to the stream
post_event_data () {
create_input_file
if [ $? -ne 0 ]; then
printf "Failed to create log data to be posted to %s with exit code: %s\n" "$stream_name" "$?"
printf "Test post_event_data: failed\n"
exit 1
fi

content=$(cat "$input_file")
response=$(curl "${curl_std_opts[@]}" --request POST "$parseable_url"/api/v1/logstream/"$stream_name" --data-raw "$content")
if [ $? -ne 0 ]; then
printf "Failed to post log data to %s with exit code: %s\n" "$stream_name" "$?"
printf "Test post_event_data: failed\n"
exit 1
fi

http_code=$(tail -n1 <<< "$response")
if [ "$http_code" -ne 200 ]; then
printf "Failed to create log stream %s with http code: %s and response: %s\n" "$stream_name" "$http_code" "$content"
printf "Test post_event_data: failed\n"
exit 1
fi

content=$(sed '$ d' <<< "$response")
if [ "$content" != "Successfully posted $events events" ]; then
printf "Failed to post log data to %s with response: %s\n" "$stream_name" "$content"
printf "Test post_event_data: failed\n"
exit 1
fi

printf "Test post_event_data: successful\n"
return 0
}

# List all log stream and [TODO] verify if the stream is created
list_log_streams () {
response=$(curl "${curl_std_opts[@]}" --request GET "$parseable_url"/api/v1/logstream)
if [ $? -ne 0 ]; then
printf "Failed to list log streams with exit code: %s\n" "$?"
printf "Test list_log_streams: failed\n"
exit 1
fi

http_code=$(tail -n1 <<< "$response")
if [ "$http_code" -ne 200 ]; then
printf "Failed to list all log streams with http code: %s and response: %s" "$http_code" "$content"
printf "Test list_log_streams: failed\n"
exit 1
fi

content=$(sed '$ d' <<< "$response")
echo "$content" > "$PWD/log_streams.json"

if [ "$(jq < $PWD/log_streams.json '[.[].name | select(. == "'"$stream_name"'")] | length')" -ne 1 ]; then
printf "Failed to find new log stream %s in list stream result: %s\n" "$stream_name" "$content"
printf "Test list_log_streams: failed\n"
exit 1
fi

printf "Test list_log_streams: successful\n"
return 0
}

# Get Stream's schema and [TODO] validate its schema
get_streams_schema () {
response=$(curl "${curl_std_opts[@]}" --request GET "$parseable_url"/api/v1/logstream/"$stream_name"/schema)
if [ $? -ne 0 ]; then
printf "Failed to fetch stream schema with exit code: %s\n" "$?"
printf "Test get_streams_schema: failed\n"
exit 1
fi

http_code=$(tail -n1 <<< "$response")
if [ "$http_code" -ne 200 ]; then
printf "Failed to get schema for stream %s with http code: %s and response: %s" "$stream_name" "$http_code" "$content"
printf "Test get_streams_schema: failed\n"
exit 1
fi

content=$(sed '$ d' <<< "$response")
if [ "$content" != "$schema_body" ]; then
printf "Get schema response doesn't match with expected schema.\n"
printf "Schema expected: %s\n" "$schema_body"
printf "Schema returned: %s\n" "$content"
printf "Test get_streams_schema: failed\n"
exit 1
fi

printf "Test get_streams_schema: successful\n"
return 0
}

# Query the log stream and verify if count of events is equal to the number of events posted
query_log_stream() {
# Query last two minutes of data only
end_time=$(date "+%Y-%m-%dT%H:%M:%S%:z")
start_time=$(date --date="@$(($(date +%s)-120))" "+%Y-%m-%dT%H:%M:%S%:z")

response=$(curl "${curl_std_opts[@]}" --request POST "$parseable_url"/api/v1/query --data-raw '{
"query": "select count(*) from '$stream_name'",
"startTime": "'$start_time'",
"endTime": "'$end_time'"
}')
if [ $? -ne 0 ]; then
printf "Failed to query log data from %s with exit code: %s\n" "$stream_name" "$?"
printf "Test query_log_stream: failed\n"
exit 1
fi

http_code=$(tail -n1 <<< "$response")
if [ "$http_code" -ne 200 ]; then
printf "Failed to query stream %s with http code: %s and response: %s" "$stream_name" "$http_code" "$content"
printf "Test query_log_stream: failed\n"
exit 1
fi

content=$(sed '$ d' <<< "$response")
queryResult=$(echo "$content" | cut -d ':' -f2 | cut -d '}' -f1)
if [ "$queryResult" != $events ]; then
printf "Validation failed. Count of events returned from query does not match with the ones posted.\n"
printf "Test query_log_stream: failed\n"
exit 1
fi
printf "Test query_log_stream: successful\n"
return 0
}

# Set Alert
set_alert () {
response=$(curl "${curl_std_opts[@]}" --request PUT "$parseable_url"/api/v1/logstream/"$stream_name"/alert --data-raw "$alert_body")
if [ $? -ne 0 ]; then
printf "Failed to set alert for %s with exit code: %s\n" "$stream_name" "$?"
printf "Test set_alert: failed\n"
exit 1
fi

http_code=$(tail -n1 <<< "$response")
if [ "$http_code" -ne 200 ]; then
printf "Failed to set alert for %s with http code: %s and response: %s\n" "$stream_name" "$http_code" "$content"
printf "Test set_alert: failed\n"
exit 1
fi

content=$(sed '$ d' <<< "$response")
if [ "$content" != "Set alert configuration for log stream $stream_name" ]; then
printf "Failed to set alert on log stream %s with response: %s\n" "$stream_name" "$content"
printf "Test set_alert: failed\n"
exit 1
fi

printf "Test set_alert: successful\n"
return 0
}

# Get Alert
get_alert () {
response=$(curl "${curl_std_opts[@]}" --request GET "$parseable_url"/api/v1/logstream/"$stream_name"/alert)
if [ $? -ne 0 ]; then
printf "Failed to get alert for %s with exit code: %s\n" "$stream_name" "$?"
printf "Test get_alert: failed\n"
exit 1
fi

http_code=$(tail -n1 <<< "$response")
if [ "$http_code" -ne 200 ]; then
printf "Failed to get alert for %s with http code: %s and response: %s" "$stream_name" "$http_code" "$content"
printf "Test get_alert: failed\n"
exit 1
fi

content=$(sed '$ d' <<< "$response")
if [ "$content" != "$alert_body" ]; then
printf "Get alert response doesn't match with Alert config returned.\n"
printf "Alert set: %s\n" "$alert_body"
printf "Alert returned: %s\n" "$content"
printf "Test get_alert: failed\n"
exit 1
fi

printf "Test get_alert: successful\n"
return 0
}

# Delete stream
delete_stream () {
response=$(curl "${curl_std_opts[@]}" --request DELETE "$parseable_url"/api/v1/logstream/"$stream_name")

if [ $? -ne 0 ]; then
printf "Failed to delete stream for %s with exit code: %s\n" "$stream_name" "$?"
printf "Test delete_stream: failed\n"
exit 1
fi

http_code=$(tail -n1 <<< "$response")
if [ "$http_code" -ne 200 ]; then
printf "Failed to delete log stream %s with http code: %s and response: %s\n" "$stream_name" "$http_code" "$content"
printf "Test delete_stream: failed\n"
exit 1
fi

content=$(sed '$ d' <<< "$response")
if [ "$content" != "log stream $stream_name deleted" ]; then
printf "Failed to delete log stream %s with response: %s" "$stream_name" "$content"
printf "Test delete_stream: failed\n"
exit 1
fi

printf "Test delete_stream: successful\n"
return 0
}

cleanup () {
rm -rf "$input_file"
rm -rf "$PWD/logstream_test.json"
return $?
}

printf "======= Starting smoke tests =======\n"
printf "** Log stream name: %s **\n" "$stream_name"
printf "** Event count: %s **\n" "$events"
printf "====================================\n"
create_stream
post_event_data
list_log_streams
get_streams_schema
query_log_stream
set_alert
get_alert
delete_stream
cleanup
printf "======= Smoke tests completed ======\n"