diff --git a/tests/controller.testing.ini b/tests/controller.testing.ini new file mode 100644 index 0000000..d3577f6 --- /dev/null +++ b/tests/controller.testing.ini @@ -0,0 +1,65 @@ +[controller] +name = new emgauwa device + +: 4422 for testing; 4421 for dev-env; 4420 for testing-env; 4419 for prod-env +discovery-port = 4422 +: 1886 for testing; 1885 for dev-env; 1884 for testing-env; 1883 for prod-env +mqtt-port = 1886 +mqtt-host = localhost + +relay-count = 10 +database = controller.sqlite +log-level = debug +log-file = stdout + +[relay-0] +driver = piface +pin = 0 +inverted = 0 + +[relay-1] +driver = piface +pin = 1 +inverted = 0 + +[relay-2] +driver = gpio +pin = 5 +inverted = 1 + +[relay-3] +driver = gpio +pin = 4 +inverted = 1 + +[relay-4] +driver = gpio +pin = 3 +inverted = 1 + +[relay-5] +driver = gpio +pin = 2 +inverted = 1 + +[relay-6] +driver = gpio +pin = 1 +inverted = 1 +pulse-duration = 3 + +[relay-7] +driver = gpio +pin = 0 +inverted = 1 +pulse-duration = 3 + +[relay-8] +driver = gpio +pin = 16 +inverted = 1 + +[relay-9] +driver = gpio +pin = 15 +inverted = 1 diff --git a/tests/core.testing.ini b/tests/core.testing.ini new file mode 100644 index 0000000..c3710a1 --- /dev/null +++ b/tests/core.testing.ini @@ -0,0 +1,16 @@ +[core] +server-port = 5000 +database = core.sqlite +content-dir = /usr/share/webapps/emgauwa +not-found-file = 404.html +not-found-file-mime = text/html +not-found-content = 404 - NOT FOUND +not-found-content-type = text/plain + +: 4422 for testing; 4421 for dev-env; 4420 for testing-env; 4419 for prod-env +discovery-port = 4422 +: 1886 for testing; 1885 for dev-env; 1884 for testing-env; 1883 for prod-env +mqtt-port = 1886 + +log-level = debug +log-file = stdout diff --git a/tests/run_tests.sh b/tests/run_tests.sh new file mode 100755 index 0000000..cbfbdb1 --- /dev/null +++ b/tests/run_tests.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env sh + +source_dir=$PWD +working_dir=$PWD/testing_latest +working_bak=$PWD/testing_bak + +alias valgrind_emgauwa="valgrind $2 --log-file=$working_dir/valgrind.log" + + +rm -rf $working_bak +[ -d $working_dir ] && mv $working_dir $working_bak + +mkdir -p $working_dir +cd $working_dir + +target_branch=$(git rev-parse --abbrev-ref HEAD) + +if [ -z "$EMGAUWA_CONTROLLER_EXE" ] +then + git clone --quiet ssh://git@git.serguzim.me:3022/emgauwa/controller.git controller || exit + cd ./controller + + git checkout dev >/dev/null 2>&1 + git checkout $target_branch >/dev/null 2>&1 + git checkout $2 >/dev/null 2>&1 + + echo "Building controller on branch $(git rev-parse --abbrev-ref HEAD)" + mkdir build + cd build + + cmake -DWIRING_PI_DEBUG=on .. >/dev/null + make >/dev/null + EMGAUWA_CONTROLLER_EXE=./controller +fi + +echo "Emgauwa controller: $($EMGAUWA_CONTROLLER_EXE --version)" + +$EMGAUWA_CONTROLLER_EXE start -c $source_dir/controller.testing.ini >$working_dir/controller.log 2>&1 & +controller_id=$! + +cd $working_dir + +cp $1 $working_dir/core +cp $source_dir/core.testing.ini $working_dir/core.ini + +echo "=== invalids start (must exit) ===" >$working_dir/core.log +$working_dir/core >>$working_dir/core.log 2>&1 +$working_dir/core INVALID_ACTION >>$working_dir/core.log 2>&1 + +echo "=== valid start ===" >>$working_dir/core.log +valgrind_emgauwa $working_dir/core start >>$working_dir/core.log 2>&1 & +core_id=$! + + +# wait for start +if [ -x "$(command -v wait-for-it)" ] +then + wait-for-it localhost:5000 -t 15 +else + echo "waiting 5 seconds for server" + sleep 5; +fi + +export PYTHONPATH=$PYTHONPATH:$source_dir/tavern_utils +tavern-ci --disable-warnings $source_dir/tavern_tests +test_result=$? + +kill $core_id +kill $controller_id + +exit $test_result diff --git a/tests/tavern_tests/0.0.get_all.tavern.yaml b/tests/tavern_tests/0.0.get_all.tavern.yaml new file mode 100644 index 0000000..9d28bf0 --- /dev/null +++ b/tests/tavern_tests/0.0.get_all.tavern.yaml @@ -0,0 +1,23 @@ +test_name: "[get_all] Test basic get all requests" + +stages: +- name: "[get_all] get all schedules" + request: + url: "http://localhost:5000/api/v1/schedules/" + method: GET + response: + status_code: 200 + +- name: "[get_all] get all relays" + request: + url: "http://localhost:5000/api/v1/relays/" + method: GET + response: + status_code: 200 + +- name: "[get_all] get all controllers" + request: + url: "http://localhost:5000/api/v1/controllers/" + method: GET + response: + status_code: 200 diff --git a/tests/tavern_tests/1.0.controllers_basic.tavern.yaml b/tests/tavern_tests/1.0.controllers_basic.tavern.yaml new file mode 100644 index 0000000..a48ea17 --- /dev/null +++ b/tests/tavern_tests/1.0.controllers_basic.tavern.yaml @@ -0,0 +1,116 @@ +test_name: Test basic controller functions + +stages: +- name: "[controllers_basic] discover controllers" + request: + method: POST + url: "http://localhost:5000/api/v1/controllers/discover/" + response: + status_code: 200 + verify_response_with: + function: validate_controller:multiple + save: + json: + returned_name: "[0].name" + returned_id: "[0].id" + returned_ip: "[0].ip" + +- name: "[controllers_basic] get controller, check name" + request: + method: GET + url: "http://localhost:5000/api/v1/controllers/{returned_id}" + response: + status_code: 200 + verify_response_with: + function: validate_controller:single + function: validate_controller:check_id + extra_kwargs: + id: "{returned_id}" + function: validate_controller:check_name + extra_kwargs: + name: "{returned_name}" + +- name: "[controllers_basic] put controller, check name" + request: + method: PUT + url: "http://localhost:5000/api/v1/controllers/{returned_id}" + json: + name: "renamed_controller" + response: + status_code: 200 + verify_response_with: + function: validate_controller:single + function: validate_controller:check_id + extra_kwargs: + id: "{returned_id}" + function: validate_controller:check_name + extra_kwargs: + name: "{tavern.request_vars.json.name}" + save: + json: + changed_name: "name" + +#- name: "[controllers_basic] put controller, check name and ip" +# request: +# method: PUT +# url: "http://localhost:5000/api/v1/controllers/{returned_id}" +# json: +# ip: "203.0.113.17" +# response: +# status_code: 200 +# verify_response_with: +# function: validate_controller:single +# function: validate_controller:check_id +# extra_kwargs: +# id: "{returned_id}" +# function: validate_controller:check_ip +# extra_kwargs: +# ip: "{tavern.request_vars.json.ip}" +# save: +# json: +# changed_ip: "ip" + +- name: "[controllers_basic] delete controller" + request: + method: DELETE + url: "http://localhost:5000/api/v1/controllers/{returned_id}" + response: + status_code: 200 + +- name: "[controllers_basic] get controller, expect 404" + request: + method: GET + url: "http://localhost:5000/api/v1/controllers/{returned_id}" + response: + status_code: 404 + +- name: "[controllers_basic] discover controllers again" + request: + method: POST + url: "http://localhost:5000/api/v1/controllers/discover/" + response: + status_code: 200 + verify_response_with: + function: validate_controller:multiple + function: validate_controller:find + extra_kwargs: + id: "{returned_id}" + name: "{changed_name}" + +- name: "[controllers_basic] get controller again, check name" + request: + method: GET + url: "http://localhost:5000/api/v1/controllers/{returned_id}" + response: + status_code: 200 + verify_response_with: + function: validate_controller:single + function: validate_controller:check_id + extra_kwargs: + id: "{returned_id}" + function: validate_controller:check_name + extra_kwargs: + name: "{changed_name}" + function: validate_controller:check_ip + extra_kwargs: + ip: "{returned_ip}" diff --git a/tests/tavern_tests/1.1.controller_relays_basic.tavern.yaml b/tests/tavern_tests/1.1.controller_relays_basic.tavern.yaml new file mode 100644 index 0000000..f0d1750 --- /dev/null +++ b/tests/tavern_tests/1.1.controller_relays_basic.tavern.yaml @@ -0,0 +1,42 @@ +test_name: Test basic controller relays functions + +stages: +- name: "[controller_relays_basic] get controllers" + request: + method: GET + url: "http://localhost:5000/api/v1/controllers/" + response: + status_code: 200 + verify_response_with: + function: validate_controller:multiple + save: + json: + returned_id: "[0].id" + returned_relay_count: "[0].relay_count" + +- name: "[controller_relays_basic] get controller relays, check length" + request: + method: GET + url: "http://localhost:5000/api/v1/controllers/{returned_id}/relays" + response: + status_code: 200 + verify_response_with: + function: validate_relay:multiple + function: validate_relay:relay_count + extra_kwargs: + relay_count: !int "{returned_relay_count:d}" + +- name: "[controller_relays_basic] get controller relays, check length" + request: + method: GET + url: "http://localhost:5000/api/v1/controllers/{returned_id}/relays/5" + response: + status_code: 200 + verify_response_with: + function: validate_relay:single + function: validate_relay:check_controller_id + extra_kwargs: + name: "{returned_id}" + function: validate_relay:check_number + extra_kwargs: + number: 5 diff --git a/tests/tavern_tests/1.2.controllers_bad.tavern.yaml b/tests/tavern_tests/1.2.controllers_bad.tavern.yaml new file mode 100644 index 0000000..cf7e663 --- /dev/null +++ b/tests/tavern_tests/1.2.controllers_bad.tavern.yaml @@ -0,0 +1,99 @@ +test_name: Test bad controller functions + +stages: +- name: "[controllers_bad] get controller with bad id" + request: + method: GET + url: "http://localhost:5000/api/v1/controllers/this_id_is_invalid" + response: + status_code: 400 + +- name: "[controllers_bad] put controller with bad id" + request: + method: PUT + url: "http://localhost:5000/api/v1/controllers/this_id_is_invalid" + json: + name: "unknown_controller" + response: + status_code: 400 + +- name: "[controllers_bad] delete controller with bad id" + request: + method: DELETE + url: "http://localhost:5000/api/v1/controllers/this_id_is_invalid" + json: + name: "unknown_controller" + response: + status_code: 400 + +- name: "[controllers_bad] get controller with unknown id" + request: + method: GET + url: "http://localhost:5000/api/v1/controllers/00000000-0000-0000-0000-000000000000" + response: + status_code: 404 + +- name: "[controllers_bad] put controller with unknown id" + request: + method: PUT + url: "http://localhost:5000/api/v1/controllers/00000000-0000-0000-0000-000000000000" + json: + name: "unknown_controller" + response: + status_code: 404 + +- name: "[controllers_bad] delete controller with unknown id" + request: + method: DELETE + url: "http://localhost:5000/api/v1/controllers/00000000-0000-0000-0000-000000000000" + json: + name: "unknown_controller" + response: + status_code: 404 + +- name: "[controllers_bad] get controllers to save valid id" + request: + method: GET + url: "http://localhost:5000/api/v1/controllers/" + response: + status_code: 200 + verify_response_with: + function: validate_controller:multiple + save: + json: + returned_id: "[0].id" + +- name: "[controllers_bad] put controller with bad body (invalid name)" + request: + method: PUT + url: "http://localhost:5000/api/v1/controllers/{returned_id}" + json: + name: NULL + response: + status_code: 400 + +- name: "[controllers_bad] put controller with bad body (invalid ip)" + request: + method: PUT + url: "http://localhost:5000/api/v1/controllers/{returned_id}" + json: + ip: 123 + response: + status_code: 400 + +- name: "[controllers_bad] put controller with bad body (invalid IPv4)" + request: + method: PUT + url: "http://localhost:5000/api/v1/controllers/{returned_id}" + json: + ip: "10.0.0.300" + response: + status_code: 400 + +- name: "[controllers_bad] put controller with bad body (no json)" + request: + method: PUT + url: "http://localhost:5000/api/v1/controllers/{returned_id}" + data: "not jsonbut html" + response: + status_code: 400 diff --git a/tests/tavern_tests/2.0.schedules_basic.tavern.yaml b/tests/tavern_tests/2.0.schedules_basic.tavern.yaml new file mode 100644 index 0000000..121013b --- /dev/null +++ b/tests/tavern_tests/2.0.schedules_basic.tavern.yaml @@ -0,0 +1,89 @@ +test_name: Test basic schedule requests + +stages: +- name: "[schedules_basic] Make sure we get any response" + request: + url: "http://localhost:5000/api/v1/schedules/" + method: GET + response: + status_code: 200 + verify_response_with: + function: validate_schedule:multiple + +- name: "[schedules_basic] post schedule with no periods, expect it to be echoed back" + request: + method: POST + url: "http://localhost:5000/api/v1/schedules/" + json: + name: "same as off" + periods: [] + tags: [] + response: + status_code: 201 + verify_response_with: + function: validate_schedule:single + function: validate_schedule:check_name + extra_kwargs: + name: "{tavern.request_vars.json.name}" + function: validate_schedule:check_periods + extra_kwargs: + periods: "{tavern.request_vars.json.periods}" + +- name: "[schedules_basic] post schedule, expect it to be echoed back" + request: + method: POST + url: "http://localhost:5000/api/v1/schedules/" + json: + name: "hello" + periods: + - start: "00:10" + end: "00:20" + - start: "00:30" + end: "00:40" + - start: "00:50" + end: "01:00" + tags: [] + response: + status_code: 201 + verify_response_with: + function: validate_schedule:single + function: validate_schedule:check_name + extra_kwargs: + name: "{tavern.request_vars.json.name}" + function: validate_schedule:check_periods + extra_kwargs: + periods: "{tavern.request_vars.json.periods}" + save: + json: + returned_name: "name" + returned_id: "id" + returned_periods: "periods" + +- name: "[schedules_basic] get schedule, check name and some periods" + request: + method: GET + url: "http://localhost:5000/api/v1/schedules/{returned_id}" + response: + status_code: 200 + verify_response_with: + function: validate_schedule:single + function: validate_schedule:check_name + extra_kwargs: + name: "{returned_name}" + function: validate_schedule:check_periods + extra_kwargs: + periods: "{returned_periods}" + +- name: "[schedules_basic] delete schedule" + request: + method: DELETE + url: "http://localhost:5000/api/v1/schedules/{returned_id}" + response: + status_code: 200 + +- name: "[schedules_basic] get deleted schedule, expect 404" + request: + method: GET + url: "http://localhost:5000/api/v1/schedules/{returned_id}" + response: + status_code: 404 diff --git a/tests/tavern_tests/2.1.schedules_protected.tavern.yaml b/tests/tavern_tests/2.1.schedules_protected.tavern.yaml new file mode 100644 index 0000000..dd62064 --- /dev/null +++ b/tests/tavern_tests/2.1.schedules_protected.tavern.yaml @@ -0,0 +1,72 @@ +test_name: Test protected schedules requests + +stages: +- name: "[schedules_protected] delete protected off schedule; expect forbidden/fail" + request: + method: DELETE + url: "http://localhost:5000/api/v1/schedules/off" + response: + status_code: 403 + +- name: "[schedules_protected] get protected off schedule" + request: + method: GET + url: "http://localhost:5000/api/v1/schedules/off" + response: + status_code: 200 + verify_response_with: + function: validate_schedule:single + function: validate_schedule:compare_off + +- name: "[schedules_protected] overwrite protected off schedule" + request: + method: PUT + url: "http://localhost:5000/api/v1/schedules/off" + json: + name: "turned_off" + periods: + - start: "00:10" + end: "00:20" + response: + status_code: 200 + verify_response_with: + function: validate_schedule:single + function: validate_schedule:compare_off + function: validate_schedule:check_name + extra_kwargs: + name: "{tavern.request_vars.json.name}" + +- name: "[schedules_protected] delete protected on schedule; expect forbidden/fail" + request: + method: DELETE + url: "http://localhost:5000/api/v1/schedules/on" + response: + status_code: 403 + +- name: get protected on schedule + request: + method: GET + url: "http://localhost:5000/api/v1/schedules/on" + response: + status_code: 200 + verify_response_with: + function: validate_schedule:single + function: validate_schedule:compare_on + +- name: "[schedules_protected] overwrite protected on schedule" + request: + method: PUT + url: "http://localhost:5000/api/v1/schedules/on" + json: + name: "turned_on" + periods: + - start: "16:10" + end: "17:20" + response: + status_code: 200 + verify_response_with: + function: validate_schedule:single + function: validate_schedule:compare_on + function: validate_schedule:check_name + extra_kwargs: + name: "{tavern.request_vars.json.name}" diff --git a/tests/tavern_tests/2.2.schedules_bad.tavern.yaml b/tests/tavern_tests/2.2.schedules_bad.tavern.yaml new file mode 100644 index 0000000..2e34410 --- /dev/null +++ b/tests/tavern_tests/2.2.schedules_bad.tavern.yaml @@ -0,0 +1,169 @@ +test_name: Test bad schedule requests + +stages: +- name: "[schedules_bad] get schedule with bad id" + request: + method: GET + url: "http://localhost:5000/api/v1/schedules/this_id_is_invalid" + response: + status_code: 400 + +- name: "[schedules_bad] post schedule with bad body (no json)" + request: + method: POST + url: "http://localhost:5000/api/v1/schedules/" + data: "not jsonbut html" + response: + status_code: 400 + +- name: "[schedules_bad] post schedule with bad body (no name)" + request: + method: POST + url: "http://localhost:5000/api/v1/schedules/" + json: + periods: + - start: "00:10" + end: "00:20" + - start: "00:30" + end: "00:40" + - start: "00:50" + end: "01:00" + tags: [] + response: + status_code: 400 + +- name: "[schedules_bad] post schedule with bad body (name as number)" + request: + method: POST + url: "http://localhost:5000/api/v1/schedules/" + json: + name: 42 + periods: + - start: "00:10" + end: "00:20" + - start: "00:30" + end: "00:40" + - start: "00:50" + end: "01:00" + tags: [] + response: + status_code: 400 + +- name: "[schedules_bad] post schedule with bad period (no start)" + request: + method: POST + url: "http://localhost:5000/api/v1/schedules/" + json: + name: "i am invalid" + periods: + - end: "00:20" + - start: "00:30" + end: "00:40" + tags: [] + response: + status_code: 400 + +- name: "[schedules_bad] post schedule with bad period (no end)" + request: + method: POST + url: "http://localhost:5000/api/v1/schedules/" + json: + name: "i am invalid" + periods: + - start: "00:20" + - start: "00:30" + end: "00:40" + tags: [] + response: + status_code: 400 + +- name: "[schedules_bad] post schedule with bad period (invalid start)" + request: + method: POST + url: "http://localhost:5000/api/v1/schedules/" + json: + name: "i am invalid" + periods: + - start: "hello" + end: "00:20" + - start: "00:30" + end: "00:40" + tags: [] + response: + status_code: 400 + +- name: "[schedules_bad] post schedule with bad period (invalid end)" + request: + method: POST + url: "http://localhost:5000/api/v1/schedules/" + json: + name: "i am invalid" + periods: + - start: "12:10" + end: 1215 + - start: "00:30" + end: "00:40" + tags: [] + response: + status_code: 400 + +- name: "[schedules_bad] post schedule with bad period (invalid end 2)" + request: + method: POST + url: "http://localhost:5000/api/v1/schedules/" + json: + name: "i am invalid" + periods: + - start: "12:10" + end: "25:90" + - start: "00:30" + end: "00:40" + tags: [] + response: + status_code: 400 + +- name: "[schedules_bad] post schedule with bad periods (invalid list)" + request: + method: POST + url: "http://localhost:5000/api/v1/schedules/" + json: + name: "i am nvalid" + periods: "not a list" + tags: [] + response: + status_code: 400 + +- name: "[schedules_bad] post schedule with bad tags (one invalid)" + request: + method: POST + url: "http://localhost:5000/api/v1/schedules/" + json: + name: "hello" + periods: + - start: "00:10" + end: "00:20" + - start: "00:30" + end: "00:40" + - start: "00:50" + end: "01:00" + tags: + - "valid_tag" + - 123 + response: + status_code: 400 + +- name: "[schedules_bad] post schedule without tags" + request: + method: POST + url: "http://localhost:5000/api/v1/schedules/" + json: + name: "hello" + periods: + - start: "00:10" + end: "00:20" + - start: "00:30" + end: "00:40" + - start: "00:50" + end: "01:00" + response: + status_code: 400 diff --git a/tests/tavern_tests/3.0.tags.tavern.yaml b/tests/tavern_tests/3.0.tags.tavern.yaml new file mode 100644 index 0000000..d4ef67f --- /dev/null +++ b/tests/tavern_tests/3.0.tags.tavern.yaml @@ -0,0 +1,108 @@ +test_name: "[tags] Test tagging of schedules and relays" + +stages: +- name: "[tags] post schedule, expect it to be echoed back by tag" + request: + method: POST + url: "http://localhost:5000/api/v1/schedules/" + json: + name: "test tagging schedule" + periods: + - start: "00:50" + end: "01:00" + tags: + - "test_tag_1" + response: + status_code: 201 + verify_response_with: + function: validate_schedule:single + function: validate_schedule:check_name + extra_kwargs: + name: "{tavern.request_vars.json.name}" + function: validate_schedule:check_periods + extra_kwargs: + periods: "{tavern.request_vars.json.periods}" + function: validate_schedule:check_tag + extra_kwargs: + tag: "{tavern.request_vars.json.tags[0]}" + save: + json: + returned_name: "name" + returned_id: "id" + returned_periods: "periods" + +- name: "[tags] get schedule, check name and some periods" + request: + method: GET + url: "http://localhost:5000/api/v1/schedules/tag/test_tag_1" + response: + status_code: 200 + verify_response_with: + function: validate_schedule:multiple + function: validate_schedule:find + extra_kwargs: + id: "{returned_id}" + name: "{returned_name}" + periods: "{returned_periods}" + +- name: "[tags] get controllers" + request: + method: GET + url: "http://localhost:5000/api/v1/controllers/" + response: + status_code: 200 + verify_response_with: + function: validate_controller:multiple + save: + json: + returned_id: "[0].id" + +- name: "[tags] set relay tag" + request: + method: PUT + url: "http://localhost:5000/api/v1/controllers/{returned_id}/relays/3" + json: + tags: + - "test_tag_1" + response: + status_code: 200 + verify_response_with: + function: validate_relay:single + function: validate_relay:check_controller_id + extra_kwargs: + name: "{returned_id}" + function: validate_relay:check_number + extra_kwargs: + number: 3 + function: validate_relay:check_tag + extra_kwargs: + tag: "{tavern.request_vars.json.tags[0]}" + save: + json: + returned_name: "name" + returned_number: "number" + returned_tag: "tags[0]" + +- name: "[tags] get relay, check name and number" + request: + method: GET + url: "http://localhost:5000/api/v1/relays/tag/{returned_tag}" + response: + status_code: 200 + verify_response_with: + function: validate_relay:multiple + function: validate_relay:find + extra_kwargs: + name: "{returned_name}" + number: !int "{returned_number:d}" + controller_id: "{returned_id}" + tag: "{returned_tag}" + +- name: "[tags] get tags" + request: + method: GET + url: "http://localhost:5000/api/v1/tags/" + response: + status_code: 200 + verify_response_with: + function: validate_tag:multiple diff --git a/tests/tavern_utils/validate_controller.py b/tests/tavern_utils/validate_controller.py new file mode 100644 index 0000000..db0fb25 --- /dev/null +++ b/tests/tavern_utils/validate_controller.py @@ -0,0 +1,45 @@ +import json +import validate_relay + +def _verify_single(controller): + assert isinstance(controller.get("id"), str), "controller id is not a string" + assert isinstance(controller.get("name"), str), "controller name is not a string" + assert isinstance(controller.get("relay_count"), int), "controller relay_count is not an integer" + + assert isinstance(controller.get("relays"), list), "controller relays is not a list" + assert len(controller.get("relays")) == controller.get("relay_count"), "controller relay have a length unequal to relay_count" + for relay in controller.get("relays"): + assert isinstance(relay, dict), "controller relays contain a relay which is not a dict" + validate_relay._verify_single(relay) + assert relay.get("controller_id") == controller.get("id") + +def single(response): + _verify_single(response.json()) + +def multiple(response): + assert isinstance(response.json(), list), "response is not a list" + for controller in response.json(): + _verify_single(controller) + +def check_id(response, id): + assert response.json().get("id") == id, "controller id check failed" + +def check_name(response, name): + assert response.json().get("name") == name, "controller name check failed" + +def check_ip(response, ip): + assert response.json().get("ip") == ip, "controller ip check failed" + +def find(response, id=None, name=None): + print(response.json()) + for controller in response.json(): + if id != None and id != controller.get("id"): + print(controller.get("id")) + continue + + if name != None and name != controller.get("name"): + print(controller.get("name")) + continue + return + assert False, "controller not found in list" + diff --git a/tests/tavern_utils/validate_relay.py b/tests/tavern_utils/validate_relay.py new file mode 100644 index 0000000..39f3811 --- /dev/null +++ b/tests/tavern_utils/validate_relay.py @@ -0,0 +1,68 @@ +import json +import validate_schedule + +def _verify_single(relay): + assert isinstance(relay.get("number"), int), "relay number is not an integer" + assert isinstance(relay.get("name"), str), "relay name is not a string" + assert isinstance(relay.get("controller_id"), str), "relay controller_id is not a string" + + assert isinstance(relay.get("active_schedule"), dict), "relay active_schedule is not a dict" + validate_schedule._verify_single(relay.get("active_schedule")) + + assert isinstance(relay.get("schedules"), list), "relay schedules is not a list" + assert len(relay.get("schedules")) == 7, "relay schedule have a length unequal to 7" + for schedule in relay.get("schedules"): + assert isinstance(relay, dict), "relay schedules contain a schedule which is not a dict" + validate_schedule._verify_single(schedule) + + assert isinstance(relay.get("tags"), list), "relay tags is not a list" + for tag in relay.get("tags"): + assert isinstance(tag, str), "relay tags contain a tag which is not a string" + +def single(response): + _verify_single(response.json()) + +def multiple(response): + assert isinstance(response.json(), list), "response is not a list" + for relay in response.json(): + _verify_single(relay) + +def relay_count(response, relay_count): + assert len(response.json()) == relay_count, "response has invalid length" + +def check_number(response, number): + assert response.json().get("number") == number, "relay number check failed" + +def check_name(response, name): + assert response.json().get("name") == name, "relay name check failed" + +def check_controller_id(response, controller_id): + assert response.json().get("controller_id") == controller_id, "relay controller_id check failed" + +def check_tag(response, tag): + for response_tag in response.json().get("tags"): + if response_tag == tag: + return + assert False, "tag not found in relay," + +def find(response, name=None, number=None, controller_id=None, tag=None): + print(response.json()) + for relay in response.json(): + if number != None and number != relay.get("number"): + continue + + if name != None and name != relay.get("name"): + continue + + if controller_id != None and controller_id != relay.get("controller_id"): + continue + + if tag != None: + found_in_response = False + for response_tag in relay.get("tags"): + if response_tag == tag: + found_in_response = True + if not found_in_response: + continue + return + assert False, "relay not found in list" diff --git a/tests/tavern_utils/validate_schedule.py b/tests/tavern_utils/validate_schedule.py new file mode 100644 index 0000000..79d1ca6 --- /dev/null +++ b/tests/tavern_utils/validate_schedule.py @@ -0,0 +1,96 @@ +import json + +def _verify_single(schedule): + assert isinstance(schedule.get("id"), str), "schedule ID is not a string" + assert isinstance(schedule.get("name"), str), "schedule name is not a string" + + assert isinstance(schedule.get("periods"), list), "schedule periods is not a list" + for period in schedule.get("periods"): + assert isinstance(period, dict), "schedule periods contain a periods which is not a dict" + assert isinstance(period.get("start"), str), "schedule periods contain a periods with start not being a string" + assert isinstance(period.get("end"), str), "schedule periods contain a periods with end not being a string" + + assert isinstance(schedule.get("tags"), list), "schedule tags is not a list" + for tag in schedule.get("tags"): + assert isinstance(tag, str), "schedule tags contain a tag which is not a string" + +def single(response): + _verify_single(response.json()) + +def multiple(response): + assert isinstance(response.json(), list), "response is not a list" + for schedule in response.json(): + _verify_single(schedule) + +def check_name(response, name): + assert response.json().get("name") == name, "schedule name check failed" + +def check_id(response, id): + assert response.json().get("id") == id, "schedule id check failed" + +def check_periods(response, periods): + periods_json = json.loads(periods.replace("'", "\"")) + assert len(periods_json) == len(response.json().get("periods")), "periods in response and request have different lengths" + for request_period in periods_json: + found_in_response = False + for response_period in response.json().get("periods"): + if response_period.get("start") != request_period.get("start"): + continue + if response_period.get("end") != request_period.get("end"): + continue + found_in_response = True + if not found_in_response: + print(request_period) + assert False, "a period from the request was missing from the response" + +def check_tag(response, tag): + for response_tag in response.json().get("tags"): + if response_tag == tag: + return + assert False, "tag not found in schedule," + +def compare_off(response): + assert response.json().get("id") == "off", "schedule off did not return id off" + assert len(response.json().get("periods")) == 0, "schedule off has periods" + +def compare_on(response): + assert response.json().get("id") == "on", "schedule on did not return id on" + assert len(response.json().get("periods")) == 1, "schedule on has unexpected amount of periods" + assert response.json().get("periods")[0].get("start") == "00:00", "Schedule on has unexpected start" + assert response.json().get("periods")[0].get("end") == "23:59", "Schedule on has unexpected start" + +def find(response, id=None, name=None, periods=None, tag=None): + if periods != None: + periods_json = json.loads(periods.replace("'", "\"")) + for schedule in response.json(): + if id != None and id != schedule.get("id"): + print(schedule.get("id")) + continue + + if name != None and name != schedule.get("name"): + print(schedule.get("name")) + continue + + if periods != None: + if len(periods_json) != len(schedule.get("periods")): + continue + for request_period in periods_json: + found_in_response = False + for response_period in schedule.get("periods"): + if response_period.get("start") != request_period.get("start"): + continue + if response_period.get("end") != request_period.get("end"): + continue + found_in_response = True + if not found_in_response: + continue + + if tag != None: + found_in_response = False + for response_tag in schedule.get("tags"): + if response_tag == tag: + found_in_response = True + if not found_in_response: + continue + return + assert False, "schedule not found in list" diff --git a/tests/tavern_utils/validate_tag.py b/tests/tavern_utils/validate_tag.py new file mode 100644 index 0000000..1e907e5 --- /dev/null +++ b/tests/tavern_utils/validate_tag.py @@ -0,0 +1,34 @@ +import json + +def _verify_single(tag): + assert isinstance(tag, str), "tag is not a string" + +def single(response): + _verify_single(response.json()) + +def multiple(response): + assert isinstance(response.json(), list), "response is not a list" + for tag in response.json(): + _verify_single(tag) + +#def find(response, name=None, number=None, controller_id=None, tag=None): +# print(response.json()) +# for tag in response.json(): +# if number != None and number != tag.get("number"): +# continue +# +# if name != None and name != tag.get("name"): +# continue +# +# if controller_id != None and controller_id != tag.get("controller_id"): +# continue +# +# if tag != None: +# found_in_response = False +# for response_tag in tag.get("tags"): +# if response_tag == tag: +# found_in_response = True +# if not found_in_response: +# continue +# return +# assert False, "tag not found in list"