-
Notifications
You must be signed in to change notification settings - Fork 48
/
Copy pathnmos-testing-facade.py
123 lines (101 loc) · 4.86 KB
/
nmos-testing-facade.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# Copyright (C) 2021 Advanced Media Workflow Association
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import random
import requests
import json
import time
from flask import Flask, render_template, make_response, request
from flask_socketio import SocketIO
from testingfacade.DataStore import data
from nmostesting import Config as CONFIG
app = Flask(__name__, static_folder="testingfacade/static", template_folder="testingfacade/templates")
socketio = SocketIO(app)
CACHEBUSTER = random.randint(1, 10000)
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'GET':
if data.getStatus() == 'Test':
r = make_response(render_template("index.html", test_type=data.getTest(), question=data.getQuestion(),
answers=data.getAnswers(), name=data.getName(),
description=data.getDescription(), response_url=data.getUrl(),
time_received=data.getTime(), timeout=data.getTimeout(),
all_data=data.getJson(), cachebuster=CACHEBUSTER))
else:
r = make_response(render_template("index.html", question=None, answers=None,
name=None, description=None, cachebuster=CACHEBUSTER))
r.headers['Cache-Control'] = 'no-cache, no-store'
return r
else:
form = request.form.to_dict()
json_data = json.loads(form['all_data'])
answer_json = {'question_id': json_data['question_id'], 'answer_response': None}
if 'answer' in form:
if json_data['test_type'] == 'multi_choice':
answer_json['answer_response'] = request.form.getlist('answer')
elif json_data['test_type'] == 'single_choice':
answer_json['answer_response'] = form['answer']
if 'answer' in form or 'Next' in form or 'all_data' in form:
# POST to test suite to confirm answer available
valid, response = do_request('POST', form['response_url'], json=answer_json)
return response.reason, response.status_code
return 'Unexpected form data', 400
@app.route('/x-nmos/testquestion/<version>', methods=['POST'], strict_slashes=False)
def testing_facade_post(version):
# Should be json from Test Suite with questions
json_list = ['test_type', 'question_id', 'name', 'description', 'question', 'answers', 'answer_uri']
json_data = request.json
json_data['time_received'] = time.time()
if 'clear' in json_data and json_data['clear'] == 'True':
# End of current tests, clear data store
data.clear()
else:
# Should be a new question
for entry in json_list:
if entry not in request.json:
return "Missing {}".format(entry), 400
# All required entries are present so update data
data.setJson(json_data)
socketio.emit('update', json_data)
return '', 202
def do_request(method, url, headers=None, **kwargs):
"""Perform a basic HTTP request with appropriate error handling"""
try:
s = requests.Session()
if not headers:
headers = {}
# all requests must have Origin to qualify as CORS requests
headers["Origin"] = "null"
req = requests.Request(method, url, headers=headers, **kwargs)
prepped = s.prepare_request(req)
settings = s.merge_environment_settings(prepped.url, {}, None, None, None)
response = s.send(prepped, timeout=1, **settings)
if prepped.url.startswith("https://"):
if not response.url.startswith("https://"):
return False, "Redirect changed protocol"
if response.history is not None:
for res in response.history:
if not res.url.startswith("https://"):
return False, "Redirect changed protocol"
return True, response
except requests.exceptions.Timeout:
return False, "Connection timeout"
except requests.exceptions.TooManyRedirects:
return False, "Too many redirects"
except requests.exceptions.ConnectionError as e:
return False, str(e)
except requests.exceptions.RequestException as e:
return False, str(e)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=CONFIG.TESTING_FACADE_PORT)
socketio.run(app)