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"