Update for test related operations.
Set finished to true when test completed. Implement delete tests. Add place holders for show test status and report. Remove label field from test web page. Enhance error handling for invalid test_id. Change-Id: I0b3a81871867cd5e5c3ab8a1dd8f63911926a0e9
This commit is contained in:
parent
5c05c7609a
commit
84c0057204
@ -29,25 +29,25 @@
|
||||
</button>
|
||||
<button type="button"
|
||||
class="btn btn-default btn-xs"
|
||||
rel="tooltip"
|
||||
rel="tooltip"
|
||||
title="Edit Cloud"
|
||||
data-placement="top"
|
||||
onclick="window.location='/edit-cloud/{{ cloud.id }}'">
|
||||
<span class="glyphicon glyphicon-pencil"></span>
|
||||
<span class="glyphicon glyphicon-pencil"></span>
|
||||
</button>
|
||||
<button type="button"
|
||||
<button type="button"
|
||||
class="btn btn-default btn-xs"
|
||||
rel="tooltip"
|
||||
rel="tooltip"
|
||||
title="Delete Cloud"
|
||||
data-placement="top"
|
||||
onclick="confirm_delete_cloud('{{ cloud.id }}','{{ cloud.label}}')">
|
||||
<span class="glyphicon glyphicon-trash"></span>
|
||||
<span class="glyphicon glyphicon-trash"></span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default unit one-of-two">
|
||||
@ -66,29 +66,29 @@
|
||||
{% if test.finished %}
|
||||
<button type="button"
|
||||
class="btn btn-default btn-xs"
|
||||
rel="tooltip"
|
||||
rel="tooltip"
|
||||
title="Show Report"
|
||||
data-placement="top"
|
||||
onclick="window.location='/show-report/{{ test.id }}'">
|
||||
<span class="glyphicon glyphicon-file"></span>
|
||||
<span class="glyphicon glyphicon-file"></span>
|
||||
</button>
|
||||
{% else %}
|
||||
<button type="button"
|
||||
class="btn btn-default btn-xs"
|
||||
rel="tooltip"
|
||||
rel="tooltip"
|
||||
title="Test In Progress..."
|
||||
data-placement="top"
|
||||
onclick="window.location='/show-status/{{ test.id }}'">
|
||||
<span class="glyphicon glyphicon-refresh"></span>
|
||||
<span class="glyphicon glyphicon-refresh"></span>
|
||||
</button>
|
||||
{% endif %}
|
||||
<button type="button"
|
||||
<button type="button"
|
||||
class="btn btn-default btn-xs"
|
||||
rel="tooltip"
|
||||
rel="tooltip"
|
||||
title="Delete Test"
|
||||
data-placement="top"
|
||||
onclick="confirm_delete_test('{{ test.id }}','{{ cloud.label}}')">
|
||||
<span class="glyphicon glyphicon-trash"></span>
|
||||
<span class="glyphicon glyphicon-trash"></span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
|
8
refstack/templates/show_report.html
Executable file
8
refstack/templates/show_report.html
Executable file
@ -0,0 +1,8 @@
|
||||
{% extends "layout.html" %}
|
||||
{% block title %}Test Report{% endblock %}
|
||||
{% block body %}
|
||||
<h2>Test Report</h2>
|
||||
Test ID: {{ test.id }}
|
||||
<br>
|
||||
<input type='button' value="Back" onclick="location.href='{{ next_url }}'">
|
||||
{% endblock %}
|
8
refstack/templates/show_status.html
Executable file
8
refstack/templates/show_status.html
Executable file
@ -0,0 +1,8 @@
|
||||
{% extends "layout.html" %}
|
||||
{% block title %}Test Status{% endblock %}
|
||||
{% block body %}
|
||||
<h2>Test Status</h2>
|
||||
Test ID: {{ test.id }}
|
||||
<br>
|
||||
<input type='button' value="Back" onclick="location.href='{{ next_url }}'">
|
||||
{% endblock %}
|
@ -1,19 +1,16 @@
|
||||
{% extends "layout.html" %}
|
||||
{% block title %}Test Cloud{% endblock %}
|
||||
{% extends "layout.html" %}
|
||||
{% block title %}Test Cloud{% endblock %}
|
||||
{% block body %}
|
||||
<h2>Test Cloud</h2>
|
||||
<form action = "" method = 'post'>
|
||||
<h2>Test Cloud</h2>
|
||||
<form action="" method='post'>
|
||||
<dl>
|
||||
<dt>Test Run Name:</dt>
|
||||
<dd><input type = 'text' name = 'label' size = '30' value = "{{ request.values.label }}"></dd>
|
||||
<dt>Test User ({{ names.user }}) Password:</dt>
|
||||
<dd><input type = 'password' name = 'pw_user' size = '30' value = "{{ request.values.pw_user }}"></dd>
|
||||
<dt>Admin User ({{ names.admin }}) Password:</dt>
|
||||
<dd><input type = 'password' name = 'pw_admin' size = '30' value = "{{ request.values.pw_admin }}"></dd>
|
||||
<dt>Test User ({{ names.user }}) Password:</dt>
|
||||
<dd><input type='password' name='pw_user' size='30' value="{{ request.values.pw_user }}"></dd>
|
||||
<dt>Admin User ({{ names.admin }}) Password:</dt>
|
||||
<dd><input type='password' name='pw_admin' size='30' value="{{ request.values.pw_admin }}"></dd>
|
||||
</dl>
|
||||
<p>
|
||||
<input type = 'button' value = "Cancel" onclick = "location.href = '/'">
|
||||
<input type = 'submit' value = "Run">
|
||||
<input type = 'hidden' name = 'next' value = "{{ next }}">
|
||||
</form>
|
||||
<input type='button' value="Cancel" onclick="location.href='{{ next_url }}'">
|
||||
<input type='submit' value="Run">
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
@ -17,12 +17,10 @@
|
||||
from docker_buildfile import DockerBuildFile
|
||||
import json
|
||||
import os
|
||||
from refstack.extensions import db
|
||||
from refstack.models import Cloud
|
||||
from refstack.models import Test
|
||||
from refstack.refstack_config import RefStackConfig
|
||||
|
||||
configData = RefStackConfig()
|
||||
config_data = RefStackConfig()
|
||||
|
||||
# Common tempest conf values to be used for all tests
|
||||
# - Image user and password can be set to any value for testing purpose
|
||||
@ -47,38 +45,33 @@ class TempestTester(object):
|
||||
'''Utility class to handle tempest test.'''
|
||||
|
||||
test_id = None
|
||||
testObj = None
|
||||
cloudObj = None
|
||||
test_obj = None
|
||||
|
||||
def __init__(self, test_id=None):
|
||||
'''Init method loads specified id.
|
||||
|
||||
If test_id exists, this is an existing test.
|
||||
Otherwise, this is a new test, and test_id will be created later.
|
||||
'''
|
||||
def __init__(self, test_id):
|
||||
'''Extract the corresponding test object from the db.'''
|
||||
if test_id:
|
||||
self.test_id = test_id
|
||||
self.testObj = Test.query.filter_by(id=test_id).first()
|
||||
if self.testObj is not None:
|
||||
self.cloudObj = Cloud.query.filter_by(
|
||||
id=self.testObj.cloud_id).first()
|
||||
self.test_obj = Test.query.filter_by(id=test_id).first()
|
||||
if self.test_obj:
|
||||
self.test_id = test_id
|
||||
return
|
||||
raise ValueError('Invalid test id %s' % (test_id))
|
||||
|
||||
def generate_miniconf(self):
|
||||
'''Return a JSON object representing the mini tempest conf.'''
|
||||
|
||||
# Get custom tempest config from config file
|
||||
custom_tempest_conf = configData.get_tempest_config()
|
||||
custom_tempest_conf = config_data.get_tempest_config()
|
||||
|
||||
# Construct cloud specific tempest config from db
|
||||
if self.cloudObj:
|
||||
if self.test_obj.cloud:
|
||||
cloud_tempest_conf = {
|
||||
"identity":
|
||||
{
|
||||
"uri": self.cloudObj.endpoint,
|
||||
"uri_v3": self.cloudObj.endpoint_v3,
|
||||
"username": self.cloudObj.test_user,
|
||||
"alt_username": self.cloudObj.test_user,
|
||||
"admin_username": self.cloudObj.admin_user
|
||||
"uri": self.test_obj.cloud.endpoint,
|
||||
"uri_v3": self.test_obj.cloud.endpoint_v3,
|
||||
"username": self.test_obj.cloud.test_user,
|
||||
"alt_username": self.test_obj.cloud.test_user,
|
||||
"admin_username": self.test_obj.cloud.admin_user
|
||||
}
|
||||
}
|
||||
else:
|
||||
@ -112,7 +105,7 @@ class TempestTester(object):
|
||||
'''Return a JSON array of the tempest testcases to be executed.'''
|
||||
|
||||
# Set to full tempest test unless it is specified in the config file
|
||||
testcases = configData.get_tempest_testcases()
|
||||
testcases = config_data.get_tempest_testcases()
|
||||
if not testcases:
|
||||
testcases = {"testcases": ["tempest"]}
|
||||
|
||||
@ -127,27 +120,6 @@ class TempestTester(object):
|
||||
print f.read()
|
||||
f.close()
|
||||
|
||||
def test_cloud(self, cloud_id, extraConfJSON=None):
|
||||
'''Create and execute a new test with the provided extraConfJSON.'''
|
||||
|
||||
# Retrieve the cloud obj from DB
|
||||
self.cloudObj = Cloud.query.filter_by(id=cloud_id).first()
|
||||
|
||||
if not self.cloudObj:
|
||||
return
|
||||
|
||||
# Create new test object in DB and get the real unique test_id
|
||||
self.testObj = Test()
|
||||
self.testObj.cloud_id = self.cloudObj.id
|
||||
self.testObj.cloud = self.cloudObj
|
||||
db.session.add(self.testObj)
|
||||
db.session.commit()
|
||||
|
||||
self.test_id = self.testObj.id
|
||||
|
||||
# Invoke execute_test
|
||||
self.execute_test(extraConfJSON)
|
||||
|
||||
def execute_test(self, extraConfJSON=None):
|
||||
'''Execute the tempest test with the provided extraConfJSON.'''
|
||||
|
||||
@ -157,8 +129,8 @@ class TempestTester(object):
|
||||
|
||||
''' TODO: Initial test status in DB '''
|
||||
|
||||
if configData.get_test_mode():
|
||||
test_mode = configData.get_test_mode().upper()
|
||||
if config_data.get_test_mode():
|
||||
test_mode = config_data.get_test_mode().upper()
|
||||
else:
|
||||
# Default to use docker if not specified in the config file
|
||||
test_mode = 'DOCKER'
|
||||
@ -174,19 +146,19 @@ class TempestTester(object):
|
||||
'''Execute the tempest test in a docker container.'''
|
||||
|
||||
''' Create the docker build file '''
|
||||
dockerFile = os.path.join(configData.get_working_dir(),
|
||||
dockerFile = os.path.join(config_data.get_working_dir(),
|
||||
'test_%s.dockerFile' % self.test_id)
|
||||
fileBuilder = DockerBuildFile()
|
||||
fileBuilder.test_id = self.test_id
|
||||
fileBuilder.api_server_address = configData.get_app_address()
|
||||
fileBuilder.api_server_address = config_data.get_app_address()
|
||||
''' TODO: Determine tempest URL based on the cloud version '''
|
||||
''' ForNow: Use the Tempest URL in the config file '''
|
||||
fileBuilder.tempest_code_url = configData.get_tempest_url()
|
||||
fileBuilder.tempest_code_url = config_data.get_tempest_url()
|
||||
fileBuilder.confJSON = extraConfJSON
|
||||
fileBuilder.build_docker_buildfile(dockerFile)
|
||||
|
||||
''' Execute the docker build file '''
|
||||
outFile = os.path.join(configData.get_working_dir(),
|
||||
outFile = os.path.join(config_data.get_working_dir(),
|
||||
'test_%s.dockerOutput' % self.test_id)
|
||||
|
||||
cmd = 'nohup docker build - < %s > %s &' % (dockerFile, outFile)
|
||||
|
200
refstack/web.py
200
refstack/web.py
@ -22,9 +22,9 @@ from refstack import app as base_app
|
||||
from refstack.extensions import db
|
||||
from refstack.extensions import oid
|
||||
from refstack.models import Cloud
|
||||
from refstack.models import Test
|
||||
from refstack.models import User
|
||||
from refstack.models import Vendor
|
||||
from refstack.models import Test
|
||||
from refstack.tools.tempest_tester import TempestTester
|
||||
|
||||
app = base_app.create_app()
|
||||
@ -35,7 +35,7 @@ public_routes = ['/post-result', '/get-miniconf']
|
||||
@app.before_request
|
||||
def before_request():
|
||||
"""Runs before the request itself."""
|
||||
if not request.path in public_routes:
|
||||
if request.path not in public_routes:
|
||||
g.user = None
|
||||
if 'openid' in session:
|
||||
flask.g.user = User.query.\
|
||||
@ -113,14 +113,34 @@ def create_profile():
|
||||
@app.route('/delete-cloud/<int:cloud_id>', methods=['GET', 'POST'])
|
||||
def delete_cloud(cloud_id):
|
||||
"""Delete function for clouds."""
|
||||
c = Cloud.query.filter_by(id=cloud_id).first()
|
||||
cloud = Cloud.query.filter_by(id=cloud_id).first()
|
||||
|
||||
if not c:
|
||||
if not cloud:
|
||||
flash(u'Not a valid Cloud ID!')
|
||||
elif not c.user_id == g.user.id:
|
||||
elif not cloud.user_id == g.user.id:
|
||||
flash(u"This isn't your cloud!")
|
||||
else:
|
||||
db.session.delete(c)
|
||||
# Delete all the tests associated with the cloud from DB
|
||||
for test in cloud.tests:
|
||||
db.session.delete(test)
|
||||
# Delete the cloud from DB
|
||||
db.session.delete(cloud)
|
||||
db.session.commit()
|
||||
|
||||
return redirect('/')
|
||||
|
||||
|
||||
@app.route('/delete-test/<int:test_id>', methods=['GET', 'POST'])
|
||||
def delete_test(test_id):
|
||||
"""Delete function for tests."""
|
||||
test = Test.query.filter_by(id=test_id).first()
|
||||
|
||||
if not test:
|
||||
flash(u'Not a valid Test ID!')
|
||||
elif not test.cloud.user_id == g.user.id:
|
||||
flash(u"This isn't your test!")
|
||||
else:
|
||||
db.session.delete(test)
|
||||
db.session.commit()
|
||||
|
||||
return redirect('/')
|
||||
@ -128,12 +148,12 @@ def delete_cloud(cloud_id):
|
||||
|
||||
@app.route('/edit-cloud/<int:cloud_id>', methods=['GET', 'POST'])
|
||||
def edit_cloud(cloud_id):
|
||||
c = Cloud.query.filter_by(id=cloud_id).first()
|
||||
cloud = Cloud.query.filter_by(id=cloud_id).first()
|
||||
|
||||
if not c:
|
||||
if not cloud:
|
||||
flash(u'Not a valid Cloud ID!')
|
||||
return redirect('/')
|
||||
elif not c.user_id == g.user.id:
|
||||
elif not cloud.user_id == g.user.id:
|
||||
flash(u"This isn't your cloud!")
|
||||
|
||||
if request.method == 'POST':
|
||||
@ -150,26 +170,26 @@ def edit_cloud(cloud_id):
|
||||
elif not request.form['admin_user']:
|
||||
flash(u'Error: All fields are required')
|
||||
else:
|
||||
c.label = request.form['label']
|
||||
c.endpoint = request.form['endpoint']
|
||||
c.test_user = request.form['test_user']
|
||||
c.admin_endpoint = request.form['admin_endpoint']
|
||||
c.endpoint_v3 = request.form['endpoint_v3']
|
||||
c.version = request.form['version']
|
||||
c.admin_user = request.form['admin_user']
|
||||
cloud.label = request.form['label']
|
||||
cloud.endpoint = request.form['endpoint']
|
||||
cloud.test_user = request.form['test_user']
|
||||
cloud.admin_endpoint = request.form['admin_endpoint']
|
||||
cloud.endpoint_v3 = request.form['endpoint_v3']
|
||||
cloud.version = request.form['version']
|
||||
cloud.admin_user = request.form['admin_user']
|
||||
|
||||
db.session.commit()
|
||||
|
||||
flash(u'Cloud Saved!')
|
||||
return redirect('/')
|
||||
|
||||
form = dict(label=c.label,
|
||||
endpoint=c.endpoint,
|
||||
endpoint_v3=c.endpoint_v3,
|
||||
admin_endpoint=c.admin_endpoint,
|
||||
admin_user=c.admin_user,
|
||||
version=c.version,
|
||||
test_user=c.test_user)
|
||||
form = dict(label=cloud.label,
|
||||
endpoint=cloud.endpoint,
|
||||
endpoint_v3=cloud.endpoint_v3,
|
||||
admin_endpoint=cloud.admin_endpoint,
|
||||
admin_user=cloud.admin_user,
|
||||
version=cloud.version,
|
||||
test_user=cloud.test_user)
|
||||
|
||||
return render_template('edit_cloud.html', form=form)
|
||||
|
||||
@ -192,17 +212,17 @@ def create_cloud():
|
||||
elif not request.form['admin_user']:
|
||||
flash(u'Error: All fields are required')
|
||||
else:
|
||||
c = Cloud()
|
||||
c.user_id = g.user.id
|
||||
c.label = request.form['label']
|
||||
c.endpoint = request.form['endpoint']
|
||||
c.test_user = request.form['test_user']
|
||||
c.admin_endpoint = request.form['admin_endpoint']
|
||||
c.endpoint_v3 = request.form['endpoint_v3']
|
||||
c.version = request.form['version']
|
||||
c.admin_user = request.form['admin_user']
|
||||
new_cloud = Cloud()
|
||||
new_cloud.user_id = g.user.id
|
||||
new_cloud.label = request.form['label']
|
||||
new_cloud.endpoint = request.form['endpoint']
|
||||
new_cloud.test_user = request.form['test_user']
|
||||
new_cloud.admin_endpoint = request.form['admin_endpoint']
|
||||
new_cloud.endpoint_v3 = request.form['endpoint_v3']
|
||||
new_cloud.version = request.form['version']
|
||||
new_cloud.admin_user = request.form['admin_user']
|
||||
|
||||
db.session.add(c)
|
||||
db.session.add(new_cloud)
|
||||
db.session.commit()
|
||||
return redirect('/')
|
||||
|
||||
@ -258,32 +278,47 @@ def logout():
|
||||
def test_cloud(cloud_id):
|
||||
"""Handler for creating a new test."""
|
||||
|
||||
c = Cloud.query.filter_by(id=cloud_id).first()
|
||||
cloud = Cloud.query.filter_by(id=cloud_id).first()
|
||||
|
||||
if not c:
|
||||
if not cloud:
|
||||
flash(u'Not a valid Cloud ID!')
|
||||
return redirect('/')
|
||||
elif not c.user_id == g.user.id:
|
||||
elif not cloud.user_id == g.user.id:
|
||||
flash(u"This isn't your cloud!")
|
||||
return redirect('/')
|
||||
|
||||
if request.method == 'POST':
|
||||
REQUIRED_FIELDS = ('label', 'pw_admin', 'pw_user')
|
||||
|
||||
# Check for required fields
|
||||
REQUIRED_FIELDS = ('pw_admin', 'pw_user')
|
||||
if not all(request.form[field] for field in REQUIRED_FIELDS):
|
||||
flash(u'Error: All fields are required')
|
||||
else:
|
||||
''' Construct confJSON with the passwords provided '''
|
||||
# Create new test object in db
|
||||
new_test = Test()
|
||||
new_test.cloud = cloud
|
||||
new_test.cloud_id = cloud.id
|
||||
db.session.add(new_test)
|
||||
db.session.commit()
|
||||
|
||||
# Construct confJSON with the passwords provided
|
||||
# and using the same user for alt_user
|
||||
pw_admin = request.form['pw_admin']
|
||||
pw_user = request.form['pw_user']
|
||||
# Using the same user for alt_user
|
||||
pw_alt = request.form['pw_user']
|
||||
jstr = '{"identity":{"password":"%s","admin_password":"%s",\
|
||||
json_str = '{"identity":{"password":"%s","admin_password":"%s",\
|
||||
"alt_password":"%s"}}' % (pw_user, pw_admin, pw_alt)
|
||||
TempestTester().test_cloud(cloud_id, jstr)
|
||||
flash(u'Test Started!')
|
||||
|
||||
# Excute the test
|
||||
try:
|
||||
TempestTester(new_test.id).execute_test(json_str)
|
||||
flash(u'Test started!')
|
||||
except ValueError:
|
||||
flash(u'Fail to start test!')
|
||||
|
||||
return redirect('/')
|
||||
|
||||
names = dict(user=c.test_user, admin=c.admin_user)
|
||||
names = dict(user=cloud.test_user, admin=cloud.admin_user)
|
||||
|
||||
return render_template('test_cloud.html', next_url='/', names=names)
|
||||
|
||||
@ -300,10 +335,13 @@ def get_miniconf():
|
||||
"""Return a JSON of mini tempest conf to a remote test runner."""
|
||||
|
||||
test_id = request.args.get('test_id', '')
|
||||
response = make_response(TempestTester(test_id).generate_miniconf())
|
||||
response.headers["Content-Disposition"] = \
|
||||
"attachment; filename=miniconf.json"
|
||||
return response
|
||||
try:
|
||||
response = make_response(TempestTester(test_id).generate_miniconf())
|
||||
response.headers["Content-Disposition"] = \
|
||||
"attachment; filename=miniconf.json"
|
||||
return response
|
||||
except ValueError:
|
||||
return make_response('Invalid test ID')
|
||||
|
||||
|
||||
@app.route('/get-testcases', methods=['GET'])
|
||||
@ -311,10 +349,13 @@ def get_testcases():
|
||||
"""Return a JSON of tempest test cases to a remote test runner."""
|
||||
|
||||
test_id = request.args.get('test_id', '')
|
||||
response = make_response(TempestTester(test_id).generate_testcases())
|
||||
response.headers["Content-Disposition"] = \
|
||||
"attachment; filename=testcases.json"
|
||||
return response
|
||||
try:
|
||||
response = make_response(TempestTester(test_id).generate_testcases())
|
||||
response.headers["Content-Disposition"] = \
|
||||
"attachment; filename=testcases.json"
|
||||
return response
|
||||
except ValueError:
|
||||
return make_response('Invalid test ID')
|
||||
|
||||
|
||||
@app.route('/post-result', methods=['POST'])
|
||||
@ -329,17 +370,64 @@ def post_result():
|
||||
if request.args.get('test_id', ''):
|
||||
# this data is for a specific test triggered by the gui and we
|
||||
# want to relate it
|
||||
_test = Test.query.\
|
||||
new_test = Test.query.\
|
||||
filter_by(id=request.args.get('test_id', '')).first()
|
||||
_test.subunit = f.read()
|
||||
new_test.subunit = f.read()
|
||||
new_test.finished = True
|
||||
|
||||
else:
|
||||
# anonymous data .. we still want to capture it
|
||||
_test = Test()
|
||||
_test.subunit = f.read()
|
||||
db.session.add(_test)
|
||||
new_test = Test()
|
||||
new_test.subunit = f.read()
|
||||
new_test.finished = True
|
||||
db.session.add(new_test)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
# todo .. set up error handling with correct response codes
|
||||
return make_response('')
|
||||
|
||||
|
||||
@app.route('/show-status/<int:test_id>', methods=['GET', 'POST'])
|
||||
def show_status(test_id):
|
||||
"""Handler for showing test status."""
|
||||
|
||||
test = Test.query.filter_by(id=test_id).first()
|
||||
|
||||
if not test:
|
||||
flash(u'Not a valid Test ID!')
|
||||
return redirect('/')
|
||||
elif not test.cloud.user_id == g.user.id:
|
||||
flash(u"This isn't your test!")
|
||||
return redirect('/')
|
||||
|
||||
# This is a place holder for now
|
||||
''' TODO: Generate the appropriate status page '''
|
||||
|
||||
return render_template('show_status.html', next_url='/', test=test)
|
||||
|
||||
|
||||
@app.route('/show-report/<int:test_id>', methods=['GET', 'POST'])
|
||||
def show_report(test_id):
|
||||
"""Handler for showing test report."""
|
||||
|
||||
test = Test.query.filter_by(id=test_id).first()
|
||||
|
||||
if not test:
|
||||
flash(u'Not a valid Test ID!')
|
||||
return redirect('/')
|
||||
elif not test.cloud.user_id == g.user.id:
|
||||
flash(u"This isn't your test!")
|
||||
return redirect('/')
|
||||
|
||||
# This is a place holder for now
|
||||
''' TODO: Generate the appropriate report page '''
|
||||
''' ForNow: send back the subunit data stream for debugging '''
|
||||
|
||||
response = make_response(test.subunit)
|
||||
response.headers["Content-Disposition"] = \
|
||||
"attachment; filename=subunit.txt"
|
||||
response.content_type = "text/plain"
|
||||
return response
|
||||
|
||||
# return render_template('show_report.html', next_url='/', test=test)
|
||||
|
Loading…
x
Reference in New Issue
Block a user