Skip to content

Commit

Permalink
Merge 437738e into 0f924bb
Browse files Browse the repository at this point in the history
  • Loading branch information
davisusanibar committed Sep 10, 2021
2 parents 0f924bb + 437738e commit 2312cd6
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 6 deletions.
29 changes: 28 additions & 1 deletion conbench/api/runs.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import flask_login

from ..api import rule
from ..api._endpoint import ApiEndpoint, maybe_login_required
from ..entities._entity import NotFound
from ..entities.run import Run, RunSerializer
from ..entities.summary import Summary


class RunEntityAPI(ApiEndpoint):
Expand Down Expand Up @@ -34,6 +37,30 @@ def get(self, run_id):
run = self._get(run_id)
return self.serializer.one.dump(run)

@flask_login.login_required
def delete(self, run_id):
"""
---
description: Delete a run.
responses:
"204": "204"
"401": "401"
"404": "404"
parameters:
- name: run_id
in: path
schema:
type: string
tags:
- Runs
"""
summaries = Summary.all(run_id=run_id)
for summarie in summaries:
summarie.delete()
run = self._get(run_id)
run.delete()
return self.response_204_no_content()


class RunListAPI(ApiEndpoint):
serializer = RunSerializer()
Expand Down Expand Up @@ -64,5 +91,5 @@ def get(self):
rule(
"/runs/<run_id>/",
view_func=run_entity_view,
methods=["GET"],
methods=["GET", "DELETE"],
)
36 changes: 33 additions & 3 deletions conbench/app/runs.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import flask as f
import flask_login
import flask_wtf
import wtforms as w

from ..app import rule
from ..app._endpoint import AppEndpoint
Expand All @@ -8,7 +11,7 @@


class RunPlot(AppEndpoint, ContextMixin, RunMixin):
def page(self, benchmarks, baseline_run, contender_run):
def page(self, benchmarks, baseline_run, contender_run, form):
compare_runs_url = None
if baseline_run and contender_run:
compare = f'{baseline_run["id"]}...{contender_run["id"]}'
Expand All @@ -20,13 +23,17 @@ def page(self, benchmarks, baseline_run, contender_run):
title="Run",
benchmarks=benchmarks,
compare_runs_url=compare_runs_url,
form=form,
)

def get(self, run_id):
if self.public_data_off():
return self.redirect("app.login")

contender_run, baseline_run = self.get_display_run(run_id), None
if contender_run is None:
self.flash("Error getting run.")
return self.redirect("app.index")
if contender_run:
baseline_url = contender_run["links"].get("baseline")
if baseline_url:
Expand All @@ -41,15 +48,38 @@ def get(self, run_id):
for benchmark in benchmarks:
augment(benchmark, contexts)

return self.page(benchmarks, baseline_run, contender_run)
return self.page(benchmarks, baseline_run, contender_run, DeleteForm())

def _get_benchmarks(self, run_id):
response = self.api_get("api.benchmarks", run_id=run_id)
return response.json, response

def post(self, run_id):
if not flask_login.current_user.is_authenticated:
return self.redirect("app.login")
form, response = DeleteForm(), None
if form.delete.data:
if form.validate_on_submit():
response = self.api_delete(
"api.run",
run_id=run_id,
)
if response.status_code == 204:
self.flash("Run deleted.")
else:
self.flash("Error deleting runs.")
csrf = {"csrf_token": ["The CSRF token is missing."]}
if form.errors == csrf:
self.flash("The CSRF token is missing.")
return self.redirect("app.index")


class DeleteForm(flask_wtf.FlaskForm):
delete = w.SubmitField("Delete")


rule(
"/runs/<run_id>/",
view_func=RunPlot.as_view("run"),
methods=["GET"],
methods=["GET", "POST"],
)
8 changes: 8 additions & 0 deletions conbench/templates/run.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{% extends "app.html" %}
{% import 'bootstrap/wtf.html' as wtf %}

{% block app_content %}
<nav aria-label="breadcrumb">
Expand Down Expand Up @@ -51,6 +52,7 @@
{% endfor %}
</tbody>
</table>
{{ wtf.quick_form(form, id="run-form", button_map={'delete': 'primary'}) }}
</div>

{% endblock %}
Expand All @@ -66,6 +68,12 @@

$(document).ready(function() {
$('#unit-tooltip').tooltip()
$("#run-form").find("#delete").attr("type", "button");
$("#run-form").find("#delete").attr("data-toggle", "modal");
$("#run-form").find("#delete").attr("data-target", "#confirm-delete");
$("#run-form").find("#delete").attr("data-form-id", "#run-form");
$("#run-form").find("#delete").attr("data-href", "{{ url_for('app.run', run_id=benchmarks[0].run_id) }}");
$("#run-form").find("#delete").attr("data-message", "<ul><li>Delete run: <strong>{{ benchmarks[0].run_id }}</strong></li></ul>");
});
</script>
{% endblock %}
19 changes: 18 additions & 1 deletion conbench/tests/api/_expected_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1261,6 +1261,23 @@
}
},
"/api/runs/{run_id}/": {
"delete": {
"description": "Delete a run.",
"parameters": [
{
"in": "path",
"name": "run_id",
"required": True,
"schema": {"type": "string"},
}
],
"responses": {
"204": {"$ref": "#/components/responses/204"},
"401": {"$ref": "#/components/responses/401"},
"404": {"$ref": "#/components/responses/404"},
},
"tags": ["Runs"],
},
"get": {
"description": "Get a run.",
"parameters": [
Expand All @@ -1277,7 +1294,7 @@
"404": {"$ref": "#/components/responses/404"},
},
"tags": ["Runs"],
}
},
},
"/api/users/": {
"get": {
Expand Down
12 changes: 12 additions & 0 deletions conbench/tests/api/test_runs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import urllib

from ...api._examples import _api_run_entity
from ...entities.summary import Summary
from ...tests.api import _asserts, _fixtures
from ...tests.helpers import _uuid

Expand Down Expand Up @@ -76,3 +77,14 @@ def test_run_list_filter_by_sha_and_machine_no_match(self, client):
args = urllib.parse.urlencode(args)
response = client.get(f"/api/runs/?{args}")
self.assert_200_ok(response, [])


class TestRunDelete(_asserts.DeleteEnforcer):
url = "api/runs/{}/"

def test_delete_run(self, client):
self.authenticate(client)
summary = _fixtures.create_benchmark_summary()
Summary.one(id=summary.id)
response = client.delete(f"/api/runs/{summary.run_id}/")
self.assert_204_no_content(response)
38 changes: 37 additions & 1 deletion conbench/tests/app/test_runs.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,44 @@
class TestRunGet(_asserts.GetEnforcer):
url = "/runs/{}/"
title = "Run"
redirect_on_unknown = False

def _create(self, client):
self.create_benchmark(client)
return _fixtures.VALID_PAYLOAD["run_id"]


class TestRunDelete(_asserts.DeleteEnforcer):
def test_authenticated(self, client):
self.create_benchmark(client)
run_id = _fixtures.VALID_PAYLOAD["run_id"]
self.authenticate(client)
response = client.get(f"/runs/{run_id}/")
self.assert_page(response, "Run")
assert f"{run_id}</li>".encode() in response.data

data = {"delete": ["Delete"], "csrf_token": self.get_csrf_token(response)}
response = client.post(f"/runs/{run_id}/", data=data, follow_redirects=True)
self.assert_page(response, "Home")
assert b"Run deleted." in response.data

response = client.get(f"/runs/{run_id}/", follow_redirects=True)
print(response.data)
self.assert_index_page(response)
assert b"Error getting run." in response.data

def test_unauthenticated(self, client):
self.create_benchmark(client)
run_id = _fixtures.VALID_PAYLOAD["run_id"]
self.logout(client)
data = {"delete": ["Delete"]}
response = client.post(f"/runs/{run_id}/", data=data, follow_redirects=True)
self.assert_login_page(response)

def test_no_csrf_token(self, client):
self.create_benchmark(client)
run_id = _fixtures.VALID_PAYLOAD["run_id"]
self.authenticate(client)
data = {"delete": ["Delete"]}
response = client.post(f"/runs/{run_id}/", data=data, follow_redirects=True)
self.assert_page(response, "Home")
assert b"The CSRF token is missing." in response.data

0 comments on commit 2312cd6

Please sign in to comment.