From f9e07bf7a3ba792a2a934cf051f0895cf1870066 Mon Sep 17 00:00:00 2001 From: Sarah Date: Thu, 9 May 2019 11:22:39 +0100 Subject: [PATCH 01/53] ignore my PyCharm files --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 04d30b1a5..0bd223e76 100644 --- a/.gitignore +++ b/.gitignore @@ -113,3 +113,6 @@ weblab/data/ # media directory weblab/media/ + +#PyCharm files +weblab/.idea/ \ No newline at end of file From 01969b882bc1c4cf06b4df5bb868446fa9598011 Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 13 May 2019 12:56:49 +0100 Subject: [PATCH 02/53] Finally sorted the url and getting a new page displayed --- weblab/entities/templatetags/entities.py | 5 ++++ weblab/entities/urls.py | 6 +++++ weblab/entities/views.py | 26 +++++++++++++++++++ weblab/templates/entities/entity_version.html | 14 +++++++--- .../entities/model_runexperiments.html | 18 +++++++++++++ 5 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 weblab/templates/entities/model_runexperiments.html diff --git a/weblab/entities/templatetags/entities.py b/weblab/entities/templatetags/entities.py index 24d4a1cab..81b7fe0c9 100644 --- a/weblab/entities/templatetags/entities.py +++ b/weblab/entities/templatetags/entities.py @@ -198,3 +198,8 @@ def can_delete_entity(context, entity): def can_manage_entity(context, entity): user = context['user'] return entity.is_managed_by(user) + + +@register.filter +def url_runexperiments(entity): + return reverse('entities:runexperiments', args=[entity.entity_type, entity.id]) diff --git a/weblab/entities/urls.py b/weblab/entities/urls.py index abb5c8979..4653b607d 100644 --- a/weblab/entities/urls.py +++ b/weblab/entities/urls.py @@ -135,4 +135,10 @@ views.EntityDiffView.as_view(), name='diff', ), + + url( + r'^%s/(?P\d+)/runexperiments/$' % _ENTITY_TYPE, + views.ModelRunExperimentView.as_view(), + name='runexperiments', + ), ] diff --git a/weblab/entities/views.py b/weblab/entities/views.py index a4b348b99..006eb98a6 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1013,3 +1013,29 @@ def get(self, request, *args, **kwargs): return JsonResponse({ task: result }) + + +class ModelRunExperimentView(EntityTypeMixin, VisibilityMixin, DetailView): + """ + Base class for listing versions of an entity + """ + context_object_name = 'entity' + template_name = 'entities/model_runexperiments.html' + + def get_context_data(self, **kwargs): + entity = self.object + + # versions = entity.cachedentity.versions + # if self.request.user not in entity.viewers: + # versions = versions.filter(visibility=Visibility.PUBLIC) + # + # kwargs.update(**{ + # 'versions': list( + # (list(version.tags.values_list('tag', flat=True)), + # entity.repo.get_commit(version.sha)) + # for version in versions.prefetch_related('tags') + # ) + # }) + return super().get_context_data(**kwargs) + + diff --git a/weblab/templates/entities/entity_version.html b/weblab/templates/entities/entity_version.html index 274d61560..150450a2d 100644 --- a/weblab/templates/entities/entity_version.html +++ b/weblab/templates/entities/entity_version.html @@ -9,6 +9,7 @@ {% include "./includes/entity_header.html" %} {% can_create_version entity as permission %} +
@@ -40,12 +41,17 @@

Add tag.
Change visibility: {{ form.visibility }} - help. + help -
- {% else %} + + Run experiments: + + Run experiments: + + + {% else %} Visibility: {{ visibility }} - help. + help {% endif %} diff --git a/weblab/templates/entities/model_runexperiments.html b/weblab/templates/entities/model_runexperiments.html new file mode 100644 index 000000000..0f607bb04 --- /dev/null +++ b/weblab/templates/entities/model_runexperiments.html @@ -0,0 +1,18 @@ +{% extends "base.html" %} +{% load staticfiles %} + +{% block title %}Experiment run specific - {% endblock title %} + +{% block body_id %}experiment-run{% endblock %} + +{% block content %} + +

Run experiments using

+ + + + +{% endblock %} From f274d1ca254180507a603fcd038203fe8c68c668 Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 13 May 2019 14:22:27 +0100 Subject: [PATCH 03/53] corrected name as can use run experiments with either models/protocols --- weblab/entities/views.py | 2 +- .../{model_runexperiments.html => entity_runexperiments.html} | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) rename weblab/templates/entities/{model_runexperiments.html => entity_runexperiments.html} (73%) diff --git a/weblab/entities/views.py b/weblab/entities/views.py index 006eb98a6..79bb2f698 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1020,7 +1020,7 @@ class ModelRunExperimentView(EntityTypeMixin, VisibilityMixin, DetailView): Base class for listing versions of an entity """ context_object_name = 'entity' - template_name = 'entities/model_runexperiments.html' + template_name = 'entities/entity_runexperiments.html' def get_context_data(self, **kwargs): entity = self.object diff --git a/weblab/templates/entities/model_runexperiments.html b/weblab/templates/entities/entity_runexperiments.html similarity index 73% rename from weblab/templates/entities/model_runexperiments.html rename to weblab/templates/entities/entity_runexperiments.html index 0f607bb04..0ee35a88b 100644 --- a/weblab/templates/entities/model_runexperiments.html +++ b/weblab/templates/entities/entity_runexperiments.html @@ -7,10 +7,8 @@ {% block content %} -

Run experiments using

+

Run experiments using {{ entity.name }}

From c2aade3cb45d1b98b1cb7d762e0824fd5fed9877 Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 13 May 2019 14:29:32 +0100 Subject: [PATCH 04/53] change name model -> entity --- weblab/entities/urls.py | 2 +- weblab/entities/views.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/weblab/entities/urls.py b/weblab/entities/urls.py index 4653b607d..abb54f8ea 100644 --- a/weblab/entities/urls.py +++ b/weblab/entities/urls.py @@ -138,7 +138,7 @@ url( r'^%s/(?P\d+)/runexperiments/$' % _ENTITY_TYPE, - views.ModelRunExperimentView.as_view(), + views.EntityRunExperimentView.as_view(), name='runexperiments', ), ] diff --git a/weblab/entities/views.py b/weblab/entities/views.py index 79bb2f698..21c947032 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1015,7 +1015,7 @@ def get(self, request, *args, **kwargs): }) -class ModelRunExperimentView(EntityTypeMixin, VisibilityMixin, DetailView): +class EntityRunExperimentView(EntityTypeMixin, VisibilityMixin, DetailView): """ Base class for listing versions of an entity """ From bf4174b07101fde34c1ab7ff81d67a70df42f4ae Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 14 May 2019 14:47:47 +0100 Subject: [PATCH 05/53] page no lists the appropriate things - tackling version next --- weblab/entities/tests/test_views.py | 24 +++++++++++++ weblab/entities/views.py | 25 ++++++------- .../entities/entity_runexperiments.html | 35 ++++++++++++++++--- 3 files changed, 65 insertions(+), 19 deletions(-) diff --git a/weblab/entities/tests/test_views.py b/weblab/entities/tests/test_views.py index ff5c47886..5d145e272 100644 --- a/weblab/entities/tests/test_views.py +++ b/weblab/entities/tests/test_views.py @@ -1958,3 +1958,27 @@ def test_nonexistent_entity_redirects_anonymous_to_login(self, client, helpers, def test_nonexistent_entity_generates_404_for_user(self, client, logged_in_user, helpers, recipe, url): response = client.get(url % 10000) assert response.status_code == 404 + + +@pytest.mark.django_db +class TestEntityRunExperiment: + def test_view_run_experiment(self, client, helpers, logged_in_user): + models = recipes.model.make(_quantity=2, author=logged_in_user) + protocols = recipes.protocol.make(_quantity=2, author=logged_in_user) + # model/1 + response = client.get('/entities/models/1/runexperiments/') + assert response.status_code == 200 + assert list(response.context['object_list']) == protocols + # model/2 + response = client.get('/entities/models/2/runexperiments/') + assert response.status_code == 200 + assert list(response.context['object_list']) == protocols + # protocol/3 + response = client.get('/entities/protocols/3/runexperiments/') + assert response.status_code == 200 + assert list(response.context['object_list']) == models + # protocol/4 + response = client.get('/entities/protocols/4/runexperiments/') + assert response.status_code == 200 + assert list(response.context['object_list']) == models + diff --git a/weblab/entities/views.py b/weblab/entities/views.py index 21c947032..76f448fa0 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1015,9 +1015,9 @@ def get(self, request, *args, **kwargs): }) -class EntityRunExperimentView(EntityTypeMixin, VisibilityMixin, DetailView): +class EntityRunExperimentView(LoginRequiredMixin, EntityTypeMixin, DetailView): """ - Base class for listing versions of an entity + Class for listing the possible experiment combinations """ context_object_name = 'entity' template_name = 'entities/entity_runexperiments.html' @@ -1025,17 +1025,14 @@ class EntityRunExperimentView(EntityTypeMixin, VisibilityMixin, DetailView): def get_context_data(self, **kwargs): entity = self.object - # versions = entity.cachedentity.versions - # if self.request.user not in entity.viewers: - # versions = versions.filter(visibility=Visibility.PUBLIC) - # - # kwargs.update(**{ - # 'versions': list( - # (list(version.tags.values_list('tag', flat=True)), - # entity.repo.get_commit(version.sha)) - # for version in versions.prefetch_related('tags') - # ) - # }) - return super().get_context_data(**kwargs) + context = super().get_context_data(**kwargs) + + # preposition to use in sentence You may run this entity on/under the following entities + context['preposition'] = 'under' + if entity.entity_type == 'protocol': + context['preposition'] = 'on' + context['object_list'] = Entity.objects.filter(entity_type=entity.other_type) + + return context diff --git a/weblab/templates/entities/entity_runexperiments.html b/weblab/templates/entities/entity_runexperiments.html index 0ee35a88b..4b80e89f4 100644 --- a/weblab/templates/entities/entity_runexperiments.html +++ b/weblab/templates/entities/entity_runexperiments.html @@ -1,16 +1,41 @@ {% extends "base.html" %} {% load staticfiles %} +{% load entities %} -{% block title %}Experiment run specific - {% endblock title %} +{% block title %}Experiment: run specific combinations - {% endblock title %} {% block body_id %}experiment-run{% endblock %} {% block content %} -

Run experiments using {{ entity.name }}

- + +
+ {% csrf_token %} + + {{ form.as_p }} + + + + + + +

+ + + + +

+
+

You may run this {{ type }} {{ preposition }} the following {{ other_type }}s.

+ +

Your {{ other_type }}s

+ {% for entity in object_list %} +
  • + {{ entity.name }} +
  • + {% endfor %} + +

    Other {{ other_type }}s

    - {% endblock %} From e93247c5f4278045d0d1971783a98fbfe90bf722 Mon Sep 17 00:00:00 2001 From: Sarah Date: Thu, 16 May 2019 14:05:10 +0100 Subject: [PATCH 06/53] fixed test that worked locally but not in github --- weblab/entities/tests/test_views.py | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/weblab/entities/tests/test_views.py b/weblab/entities/tests/test_views.py index 5d145e272..6e422ecd3 100644 --- a/weblab/entities/tests/test_views.py +++ b/weblab/entities/tests/test_views.py @@ -1962,23 +1962,16 @@ def test_nonexistent_entity_generates_404_for_user(self, client, logged_in_user, @pytest.mark.django_db class TestEntityRunExperiment: - def test_view_run_experiment(self, client, helpers, logged_in_user): - models = recipes.model.make(_quantity=2, author=logged_in_user) + def test_view_run_experiment_model(self, client, helpers, logged_in_user): + model = recipes.model.make(author=logged_in_user) protocols = recipes.protocol.make(_quantity=2, author=logged_in_user) - # model/1 - response = client.get('/entities/models/1/runexperiments/') + response = client.get('/entities/models/%d/runexperiments/' % model.pk) assert response.status_code == 200 assert list(response.context['object_list']) == protocols - # model/2 - response = client.get('/entities/models/2/runexperiments/') - assert response.status_code == 200 - assert list(response.context['object_list']) == protocols - # protocol/3 - response = client.get('/entities/protocols/3/runexperiments/') - assert response.status_code == 200 - assert list(response.context['object_list']) == models - # protocol/4 - response = client.get('/entities/protocols/4/runexperiments/') + + def test_view_run_experiment_protocol(self, client, helpers, logged_in_user): + models = recipes.model.make(_quantity=2, author=logged_in_user) + protocol = recipes.protocol.make(author=logged_in_user) + response = client.get('/entities/protocols/%d/runexperiments/' % protocol.pk) assert response.status_code == 200 assert list(response.context['object_list']) == models - From 88ecc0a7cabc60c68e7ac71ba45a5705cc586241 Mon Sep 17 00:00:00 2001 From: Sarah Date: Fri, 17 May 2019 10:31:22 +0100 Subject: [PATCH 07/53] sorted the view for my model/protocols I know need to work out getting the checkboxes/buttons to something and then replicate for global models/protocols --- weblab/entities/tests/test_views.py | 24 ++++++++++--- weblab/entities/views.py | 16 +++++++-- .../entities/entity_runexperiments.html | 35 ++++++++++++++++--- 3 files changed, 64 insertions(+), 11 deletions(-) diff --git a/weblab/entities/tests/test_views.py b/weblab/entities/tests/test_views.py index 6e422ecd3..87b1a1dda 100644 --- a/weblab/entities/tests/test_views.py +++ b/weblab/entities/tests/test_views.py @@ -1964,14 +1964,30 @@ def test_nonexistent_entity_generates_404_for_user(self, client, logged_in_user, class TestEntityRunExperiment: def test_view_run_experiment_model(self, client, helpers, logged_in_user): model = recipes.model.make(author=logged_in_user) - protocols = recipes.protocol.make(_quantity=2, author=logged_in_user) + protocol = recipes.protocol.make(author=logged_in_user) + commit1 = helpers.add_version(protocol, visibility='public') + commit2 = helpers.add_version(protocol, visibility='public') + protocol.add_tag('v1', commit2.hexsha) + response = client.get('/entities/models/%d/runexperiments/' % model.pk) assert response.status_code == 200 - assert list(response.context['object_list']) == protocols + assert response.context['object_list'] == [{'id': 'myprotocol1', + 'versions': [{'commit': commit2, 'tags': ['v1']}, + {'commit': commit1, 'tags': []}]}, + ] + assert response.context['preposition'] == 'under' def test_view_run_experiment_protocol(self, client, helpers, logged_in_user): - models = recipes.model.make(_quantity=2, author=logged_in_user) + model = recipes.model.make(author=logged_in_user) + commit1 = helpers.add_version(model, visibility='public') + commit2 = helpers.add_version(model, visibility='public') + model.add_tag('v1', commit2.hexsha) protocol = recipes.protocol.make(author=logged_in_user) response = client.get('/entities/protocols/%d/runexperiments/' % protocol.pk) assert response.status_code == 200 - assert list(response.context['object_list']) == models + assert response.context['object_list'] == [{'id': 'mymodel1', + 'versions': [{'commit': commit2, 'tags': ['v1']}, + {'commit': commit1, 'tags': []}]}, + ] + assert response.context['preposition'] == 'on' + diff --git a/weblab/entities/views.py b/weblab/entities/views.py index 76f448fa0..0f3e3df2c 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1027,12 +1027,24 @@ def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - # preposition to use in sentence You may run this entity on/under the following entities + # preposition to use in sentence: You may run this entity on/under the following entities context['preposition'] = 'under' if entity.entity_type == 'protocol': context['preposition'] = 'on' - context['object_list'] = Entity.objects.filter(entity_type=entity.other_type) + # ended up using a nested dict as nessed lists caused django's unpacking in forloops to + # mess things up slightly + other_entities = Entity.objects.filter(entity_type=entity.other_type) + context['object_list'] = [] + for item in other_entities: + versions = item.cachedentity.versions + version_info = [] + for version in versions.prefetch_related('tags'): + tag_list = list(version.tags.values_list('tag', flat=True)) + commit = item.repo.get_commit(version.sha) + version_info.append({'commit': commit, 'tags': tag_list}) + context['object_list'].append({'id': item.name, 'versions': version_info}) return context + diff --git a/weblab/templates/entities/entity_runexperiments.html b/weblab/templates/entities/entity_runexperiments.html index 4b80e89f4..f7b51bd08 100644 --- a/weblab/templates/entities/entity_runexperiments.html +++ b/weblab/templates/entities/entity_runexperiments.html @@ -29,11 +29,36 @@

    Run experiments using {{ entity.name }}

    You may run this {{ type }} {{ preposition }} the following {{ other_type }}s.

    Your {{ other_type }}s

    - {% for entity in object_list %} -
  • - {{ entity.name }} -
  • - {% endfor %} + + + {% for entity_object in object_list %} + + {{ entity_object.id }} + + {% for entity_version in entity_object.versions %} +
  • +

    + + + + {% include "./includes/version_name.html" with tags=entity_version.tags version=entity_version.commit only %} + + + by {{ entity_version.commit.author }}
    + + created + {% with entity_version.commit.filenames|length as numfiles %} + containing {{ numfiles }} file{{ numfiles|pluralize}} + {% endwith %} + +
    + + {{ entity_version.commit.message|linebreaksbr }} + +

    +
  • + {% endfor %} + {% endfor %}

    Other {{ other_type }}s

    From 5b04abf3f7d999d8e68ab6585ab36f2ecf4d3ec5 Mon Sep 17 00:00:00 2001 From: Sarah Date: Fri, 17 May 2019 10:47:51 +0100 Subject: [PATCH 08/53] add force override checkbox --- weblab/templates/entities/entity_runexperiments.html | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/weblab/templates/entities/entity_runexperiments.html b/weblab/templates/entities/entity_runexperiments.html index f7b51bd08..190c69b81 100644 --- a/weblab/templates/entities/entity_runexperiments.html +++ b/weblab/templates/entities/entity_runexperiments.html @@ -8,16 +8,16 @@ {% block content %}

    Run experiments using {{ entity.name }}

    - + +

    + + Force overwrite of existing experiments +

    {% csrf_token %} {{ form.as_p }} - - - -

    @@ -36,6 +36,7 @@

    Your {{ other_type }}s

    {{ entity_object.id }} {% for entity_version in entity_object.versions %} +
    • @@ -57,6 +58,7 @@

      Your {{ other_type }}s

    • +
    {% endfor %} {% endfor %} From 441a1bbdf4fddc77a18cd0333ffe3fcba0ad84be Mon Sep 17 00:00:00 2001 From: Sarah Date: Fri, 17 May 2019 13:25:44 +0100 Subject: [PATCH 09/53] My local set up is not letting me play with js files so adding them so my vagrant deployment will --- weblab/static/js/main.js | 1 + weblab/static/js/run_experiment.js | 24 +++++++++++++++++++ .../entities/entity_runexperiments.html | 12 ++++------ 3 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 weblab/static/js/run_experiment.js diff --git a/weblab/static/js/main.js b/weblab/static/js/main.js index 15de91e10..9dc2aefaa 100644 --- a/weblab/static/js/main.js +++ b/weblab/static/js/main.js @@ -10,6 +10,7 @@ var experiment = require('./experiment.js'); var notifications = require('./lib/notifications.js'); require('./compare.js'); require('./entity_version_list.js'); +require('./run_experiment.js'); require('django-formset'); diff --git a/weblab/static/js/run_experiment.js b/weblab/static/js/run_experiment.js new file mode 100644 index 000000000..901988355 --- /dev/null +++ b/weblab/static/js/run_experiment.js @@ -0,0 +1,24 @@ + +var RunExperiment = function() {}; + +RunExperiment.prototype = { + init: function() { + // Comparing entity versions click events + $("#checkallbutton").click (function () { + $(".experimentCheckBox").each (function () { + $(this).prop('checked', true) + }); + }); + $("#uncheckallbutton").click (function () { + $(".experimentCheckBox").prop('checked', false); + }); + } +}; + + +$(document).ready(function() { + if ($("#runexperiment").length > 0) { + var page = new RunExperiment(); + page.init(); + } +}); diff --git a/weblab/templates/entities/entity_runexperiments.html b/weblab/templates/entities/entity_runexperiments.html index 190c69b81..630266222 100644 --- a/weblab/templates/entities/entity_runexperiments.html +++ b/weblab/templates/entities/entity_runexperiments.html @@ -4,19 +4,17 @@ {% block title %}Experiment: run specific combinations - {% endblock title %} -{% block body_id %}experiment-run{% endblock %} +{% block body_id %}runexperiment{% endblock %} {% block content %}

    Run experiments using {{ entity.name }}

    - + Force overwrite of existing experiments

    - - {% csrf_token %} +
    - {{ form.as_p }}

    @@ -25,7 +23,6 @@

    Run experiments using {{ entity.name }}

    -

    You may run this {{ type }} {{ preposition }} the following {{ other_type }}s.

    Your {{ other_type }}s

    @@ -39,7 +36,7 @@

    Your {{ other_type }}s

    {% endfor %} {% endfor %} +

    Other {{ other_type }}s

    From bc4de2129b5e44a0796ad120dd844c60de565d86 Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 20 May 2019 09:04:13 +0100 Subject: [PATCH 10/53] add url test for runexperiments --- weblab/entities/tests/test_templatetags.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/weblab/entities/tests/test_templatetags.py b/weblab/entities/tests/test_templatetags.py index 464e23878..e76bba137 100644 --- a/weblab/entities/tests/test_templatetags.py +++ b/weblab/entities/tests/test_templatetags.py @@ -123,3 +123,14 @@ def test_url_friendly_label(model_with_version, helpers): commit3 = helpers.add_version(model_with_version) model_with_version.repo.tag('latest') assert entity_tags._url_friendly_label(model_with_version, commit3) == commit3.hexsha + + +@pytest.mark.django_db +def test_url_runexperiments(model_with_version, protocol_with_version): + model = model_with_version + assert (entity_tags.url_runexperiments(model) == + '/entities/models/%d/runexperiments/' % model.pk) + + protocol = protocol_with_version + assert (entity_tags.url_runexperiments(protocol) == + '/entities/protocols/%d/runexperiments/' % protocol.pk) From 898e5898bdaa4b311a9ef70598dc5bacc8f45bc3 Mon Sep 17 00:00:00 2001 From: Sarah Date: Mon, 20 May 2019 11:07:55 +0100 Subject: [PATCH 11/53] getting checkboxes to work as indicated --- weblab/entities/views.py | 7 ++++++- weblab/static/js/run_experiment.js | 16 +++++++++++----- .../entities/entity_runexperiments.html | 19 ++++++++++++++----- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/weblab/entities/views.py b/weblab/entities/views.py index 0f3e3df2c..a19f3d1fb 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1042,9 +1042,14 @@ def get_context_data(self, **kwargs): for version in versions.prefetch_related('tags'): tag_list = list(version.tags.values_list('tag', flat=True)) commit = item.repo.get_commit(version.sha) - version_info.append({'commit': commit, 'tags': tag_list}) + latest = item.repo.latest_commit + version_info.append({'commit': commit, 'tags': tag_list, 'latest': latest == commit}) context['object_list'].append({'id': item.name, 'versions': version_info}) return context + def post(self, request, *args, **kwargs): + # record_experiments_to_run(request.user, entity, commit) + return HttpResponseRedirect( + reverse('entities:version', args=[kwargs['entity_type'], kwargs['pk'], 'latest'])) diff --git a/weblab/static/js/run_experiment.js b/weblab/static/js/run_experiment.js index 901988355..285de69f0 100644 --- a/weblab/static/js/run_experiment.js +++ b/weblab/static/js/run_experiment.js @@ -3,16 +3,22 @@ var RunExperiment = function() {}; RunExperiment.prototype = { init: function() { - // Comparing entity versions click events $("#checkallbutton").click (function () { - $(".experimentCheckBox").each (function () { - $(this).prop('checked', true) + $(".latestexperimentCheckBox").prop('checked', true); + $(".experimentCheckBox").prop('checked', true); }); - }); $("#uncheckallbutton").click (function () { + $(".latestexperimentCheckBox").prop('checked', false); $(".experimentCheckBox").prop('checked', false); }); - } + $("#checklatestbutton").click (function () { + $(".latestexperimentCheckBox").prop('checked', true); + $(".experimentCheckBox").prop('checked', false); + }); + $("#runexperimentsbutton").click (function () { + // do something + }); + } }; diff --git a/weblab/templates/entities/entity_runexperiments.html b/weblab/templates/entities/entity_runexperiments.html index 630266222..21cb79638 100644 --- a/weblab/templates/entities/entity_runexperiments.html +++ b/weblab/templates/entities/entity_runexperiments.html @@ -10,18 +10,22 @@

    Run experiments using {{ entity.name }}

    - + Force overwrite of existing experiments

    -

    - + - +

    +

    + {% csrf_token %} + + +

    You may run this {{ type }} {{ preposition }} the following {{ other_type }}s.

    @@ -36,7 +40,12 @@

    Your {{ other_type }}s

    From cf45cd226d770a6a79a059492413a393280befde Mon Sep 17 00:00:00 2001 From: Sarah Date: Wed, 22 May 2019 10:19:56 +0100 Subject: [PATCH 23/53] improve query speed --- weblab/entities/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/weblab/entities/views.py b/weblab/entities/views.py index 78df8dc63..5256f7bb7 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1035,7 +1035,8 @@ def get_context_data(self, **kwargs): # ended up using a nested dict as nested lists caused django's unpacking in forloops to # mess things up slightly - other_entities = Entity.objects.filter(entity_type=entity.other_type) + other_entities = Entity.objects.filter(entity_type=entity.other_type)\ + .select_related('cachedentity').prefetch_related('cachedentity__versions', 'cachedentity__versions__tags') context['object_list'] = [] for item in other_entities: versions = item.cachedentity.versions From 0a2dac4fa60bbb1aafbcbd0a2b0087d0f9ecd35a Mon Sep 17 00:00:00 2001 From: Sarah Date: Wed, 22 May 2019 10:34:21 +0100 Subject: [PATCH 24/53] change wording of force override button --- weblab/templates/entities/entity_runexperiments.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weblab/templates/entities/entity_runexperiments.html b/weblab/templates/entities/entity_runexperiments.html index 00951ed7c..08de1386b 100644 --- a/weblab/templates/entities/entity_runexperiments.html +++ b/weblab/templates/entities/entity_runexperiments.html @@ -11,7 +11,7 @@

    Run experiments using {{ entity.name }}

    - Force overwrite of existing experiments + Create new versions of existing experiments (if unchecked, existing combinations will be skipped)

    From 12d466dc5579a63d0f3faea6d95cf221a4c8243a Mon Sep 17 00:00:00 2001 From: Sarah Date: Wed, 22 May 2019 10:49:26 +0100 Subject: [PATCH 25/53] only show Run experiment button if user has permission to create experiments --- weblab/templates/entities/entity_version.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/weblab/templates/entities/entity_version.html b/weblab/templates/entities/entity_version.html index 150450a2d..2754d5125 100644 --- a/weblab/templates/entities/entity_version.html +++ b/weblab/templates/entities/entity_version.html @@ -43,11 +43,11 @@

    Change visibility: {{ form.visibility }} help - - Run experiments: - - Run experiments: - + {% if perms.create_experiment %} + Run experiments: + + Run experiments: + {% endif %} {% else %} Visibility: {{ visibility }} From 626b5ed3bdce06e746afbbdf4c2385bf21cc6bcd Mon Sep 17 00:00:00 2001 From: Sarah Date: Wed, 22 May 2019 11:10:44 +0100 Subject: [PATCH 26/53] changed hard coded 'model' to get correct entity type --- weblab/templates/entities/entity_version.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/weblab/templates/entities/entity_version.html b/weblab/templates/entities/entity_version.html index 2754d5125..2de306fd6 100644 --- a/weblab/templates/entities/entity_version.html +++ b/weblab/templates/entities/entity_version.html @@ -46,7 +46,8 @@

    {% if perms.create_experiment %} Run experiments: - Run experiments: + Run experiments: {% endif %} {% else %} From dde92d21779309a1ce3c819a1592525b10dd8a77 Mon Sep 17 00:00:00 2001 From: Sarah Date: Thu, 23 May 2019 12:02:19 +0100 Subject: [PATCH 27/53] In teh interest of time pushing my development work to git so I get an interaction with the js --- weblab/entities/views.py | 15 +++++++++++++++ .../templates/entities/entity_runexperiments.html | 11 ++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/weblab/entities/views.py b/weblab/entities/views.py index 5256f7bb7..c9b6c2850 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1050,6 +1050,21 @@ def get_context_data(self, **kwargs): return context def post(self, request, *args, **kwargs): + rr = request.POST.get('rerun_expts') + print(rr) + experiments_to_run = request.POST.getlist('runexperimentlist[]') + print(experiments_to_run) + if request.POST.get('rerun_expts'): + # run all checked experiments (rerun if necessary) + for exper in experiments_to_run: + print(exper) +# record_experiments_to_run(request.user, entity, commit) + else: + # only run checked experiments that have not already been run + for exper in experiments_to_run: + print(exper) + # record_experiments_to_run(request.user, entity, commit) + # record_experiments_to_run(request.user, entity, commit) return HttpResponseRedirect( reverse('entities:version', args=[kwargs['entity_type'], kwargs['pk'], 'latest'])) diff --git a/weblab/templates/entities/entity_runexperiments.html b/weblab/templates/entities/entity_runexperiments.html index 08de1386b..a0a74bc71 100644 --- a/weblab/templates/entities/entity_runexperiments.html +++ b/weblab/templates/entities/entity_runexperiments.html @@ -10,7 +10,7 @@

    Run experiments using {{ entity.name }}

    - + Create new versions of existing experiments (if unchecked, existing combinations will be skipped)

    @@ -42,9 +42,14 @@

    Your {{ other_type }}s

    {% if entity_version.latest %} - + {% else %} - + {% endif %} From 29415f6b0b1dbcc58150d8a44305ce1d84877a6b Mon Sep 17 00:00:00 2001 From: Sarah Date: Thu, 23 May 2019 16:15:34 +0100 Subject: [PATCH 28/53] trying to see if this works --- weblab/entities/views.py | 27 ++++++++++--------- .../entities/entity_runexperiments.html | 4 +-- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/weblab/entities/views.py b/weblab/entities/views.py index c9b6c2850..2f33c5dc8 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1050,19 +1050,22 @@ def get_context_data(self, **kwargs): return context def post(self, request, *args, **kwargs): - rr = request.POST.get('rerun_expts') - print(rr) experiments_to_run = request.POST.getlist('runexperimentlist[]') - print(experiments_to_run) - if request.POST.get('rerun_expts'): - # run all checked experiments (rerun if necessary) - for exper in experiments_to_run: - print(exper) -# record_experiments_to_run(request.user, entity, commit) - else: - # only run checked experiments that have not already been run - for exper in experiments_to_run: - print(exper) + for version in experiments_to_run: + ident, sha = version.split(':') + entity = Entity.objects.get(pk=ident) + commit = entity.repo.get_commit(sha) + record_experiments_to_run(request.user, entity, commit) + # if request.POST.get('rerun_expts'): + # # run all checked experiments (rerun if necessary) + # for exper in experiments_to_run: + # entity = Entity.objects.get(exper.keys()[0]) + # commit = Entity.objects.get(exper.value()) + # record_experiments_to_run(request.user, entity, commit) + # else: + # # only run checked experiments that have not already been run + # for exper in experiments_to_run: + # print(exper) # record_experiments_to_run(request.user, entity, commit) # record_experiments_to_run(request.user, entity, commit) diff --git a/weblab/templates/entities/entity_runexperiments.html b/weblab/templates/entities/entity_runexperiments.html index a0a74bc71..c051eb0af 100644 --- a/weblab/templates/entities/entity_runexperiments.html +++ b/weblab/templates/entities/entity_runexperiments.html @@ -43,12 +43,12 @@

    Your {{ other_type }}s

    {% if entity_version.latest %} {% else %} {% endif %} From dd6e4e93fefdfa13c772eae3d40c1fbde720fa63 Mon Sep 17 00:00:00 2001 From: Sarah Date: Thu, 23 May 2019 16:42:50 +0100 Subject: [PATCH 29/53] am I actually picking up experiments --- weblab/entities/views.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/weblab/entities/views.py b/weblab/entities/views.py index 2f33c5dc8..14a18ac7a 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1051,6 +1051,8 @@ def get_context_data(self, **kwargs): def post(self, request, *args, **kwargs): experiments_to_run = request.POST.getlist('runexperimentlist[]') + if not experiments_to_run: + raise Http404 for version in experiments_to_run: ident, sha = version.split(':') entity = Entity.objects.get(pk=ident) From 4137ec8cdb713c6256baae5ef266725cb0775b97 Mon Sep 17 00:00:00 2001 From: Sarah Date: Thu, 23 May 2019 16:46:53 +0100 Subject: [PATCH 30/53] that confirmed my suspicions - take out the 404 code that I added to test --- weblab/entities/views.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/weblab/entities/views.py b/weblab/entities/views.py index 14a18ac7a..2f33c5dc8 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1051,8 +1051,6 @@ def get_context_data(self, **kwargs): def post(self, request, *args, **kwargs): experiments_to_run = request.POST.getlist('runexperimentlist[]') - if not experiments_to_run: - raise Http404 for version in experiments_to_run: ident, sha = version.split(':') entity = Entity.objects.get(pk=ident) From 65e7afe66e0146ff05830bce71e2028aa296ecb0 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 28 May 2019 13:26:56 +0100 Subject: [PATCH 31/53] finally got tings working so I add experiments to PlannedExperiments Now need to expand for other users ad whether w re-run and existing experiment --- weblab/entities/tests/test_views.py | 74 ++++++++++++++- weblab/entities/views.py | 37 ++++---- .../entities/entity_runexperiments.html | 90 +++++++++---------- 3 files changed, 134 insertions(+), 67 deletions(-) diff --git a/weblab/entities/tests/test_views.py b/weblab/entities/tests/test_views.py index d43d2e013..4ebcbc26e 100644 --- a/weblab/entities/tests/test_views.py +++ b/weblab/entities/tests/test_views.py @@ -2068,12 +2068,48 @@ def test_view_run_experiment_model(self, client, helpers, logged_in_user): response = client.get('/entities/models/%d/runexperiments/' % model.pk) assert response.status_code == 200 - assert response.context['object_list'] == [{'id': 'myprotocol1', + assert response.context['object_list'] == [{'id': protocol.pk, + 'name': 'myprotocol1', 'versions': [{'commit': commit2, 'tags': ['v1'], 'latest': True}, {'commit': commit1, 'tags': [], 'latest': False}]}, ] assert response.context['preposition'] == 'under' + def test_view_run_experiment_model_post(self, client, helpers, logged_in_user): + helpers.add_permission(logged_in_user, 'create_experiment', Experiment) + model = recipes.model.make(author=logged_in_user) + commit_model = helpers.add_version(model, visibility='public') + + protocol = recipes.protocol.make(author=logged_in_user) + commit1 = helpers.add_version(protocol, visibility='public') + commit2 = helpers.add_version(protocol, visibility='public') + protocol.add_tag('v1', commit2.hexsha) + + # Test context has correct information + response = client.get('/entities/models/%d/runexperiments/' % model.pk) + assert response.status_code == 200 + assert response.context['object_list'] == [{'id': protocol.pk, + 'name': 'myprotocol1', + 'versions': [{'commit': commit2, 'tags': ['v1'], 'latest': True}, + {'commit': commit1, 'tags': [], 'latest': False}]}, + ] + # Test post returns correct response + data = {'runexperimentlist[]': ['%d:%s' % (protocol.pk, commit2.hexsha)], + 'entity.repo.latest_commit.hexsha': commit_model.hexsha} + response = client.post('/entities/models/%d/runexperiments/' % model.pk, data=data) + assert response.status_code == 302 + assert response.url == '/entities/models/%d/versions/latest' % model.pk + + # Test that planned experiments have been added correctly + expected_proto_versions = set([ + (protocol, commit2.hexsha) + ]) + assert PlannedExperiment.objects.count() == 1 + for planned_experiment in PlannedExperiment.objects.all(): + assert planned_experiment.model == model + assert planned_experiment.model_version == commit_model.hexsha + assert (planned_experiment.protocol, planned_experiment.protocol_version) in expected_proto_versions + def test_view_run_experiment_protocol(self, client, helpers, logged_in_user): helpers.add_permission(logged_in_user, 'create_experiment', Experiment) model = recipes.model.make(author=logged_in_user) @@ -2083,9 +2119,43 @@ def test_view_run_experiment_protocol(self, client, helpers, logged_in_user): protocol = recipes.protocol.make(author=logged_in_user) response = client.get('/entities/protocols/%d/runexperiments/' % protocol.pk) assert response.status_code == 200 - assert response.context['object_list'] == [{'id': 'mymodel1', + assert response.context['object_list'] == [{'id': model.pk, + 'name': 'mymodel1', 'versions': [{'commit': commit2, 'tags': ['v1'], 'latest': True}, {'commit': commit1, 'tags': [], 'latest': False}]}, ] assert response.context['preposition'] == 'on' + def test_view_run_experiment_protocol_post(self, client, helpers, logged_in_user): + helpers.add_permission(logged_in_user, 'create_experiment', Experiment) + model = recipes.model.make(author=logged_in_user) + commit1 = helpers.add_version(model, visibility='public') + commit2 = helpers.add_version(model, visibility='public') + model.add_tag('v1', commit2.hexsha) + protocol = recipes.protocol.make(author=logged_in_user) + commit_protocol = helpers.add_version(protocol, visibility='public') + response = client.get('/entities/protocols/%d/runexperiments/' % protocol.pk) + assert response.status_code == 200 + assert response.context['object_list'] == [{'id': model.pk, + 'name': 'mymodel1', + 'versions': [{'commit': commit2, 'tags': ['v1'], 'latest': True}, + {'commit': commit1, 'tags': [], 'latest': False}]}, + ] + # Test post returns correct response + data = {'runexperimentlist[]': ['%d:%s' % (model.pk, commit1.hexsha), '%d:%s' % (model.pk, commit2.hexsha)], + 'entity.repo.latest_commit.hexsha': commit_protocol.hexsha} + response = client.post('/entities/protocols/%d/runexperiments/' % protocol.pk, data=data) + assert response.status_code == 302 + assert response.url == '/entities/protocols/%d/versions/latest' % protocol.pk + + # Test that planned experiments have been added correctly + expected_model_versions = set([ + (model, commit2.hexsha), + (model, commit1.hexsha) + ]) + assert PlannedExperiment.objects.count() == 2 + for planned_experiment in PlannedExperiment.objects.all(): + assert planned_experiment.protocol == protocol + assert planned_experiment.protocol_version == commit_protocol.hexsha + assert (planned_experiment.model, planned_experiment.model_version) in expected_model_versions + diff --git a/weblab/entities/views.py b/weblab/entities/views.py index 0c1b8654d..56a118b99 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1047,29 +1047,32 @@ def get_context_data(self, **kwargs): commit = item.repo.get_commit(version.sha) latest = item.repo.latest_commit version_info.append({'commit': commit, 'tags': tag_list, 'latest': latest == commit}) - context['object_list'].append({'id': item.name, 'versions': version_info}) + context['object_list'].append({'id': item.id, 'name': item.name, 'versions': version_info}) return context def post(self, request, *args, **kwargs): + # this in not intuitive + # in get context self.object was the entity being worked with + # here we have to retrieve it + entity = self.get_object() experiments_to_run = request.POST.getlist('runexperimentlist[]') for version in experiments_to_run: ident, sha = version.split(':') - entity = Entity.objects.get(pk=ident) - commit = entity.repo.get_commit(sha) - record_experiments_to_run(request.user, entity, commit) - # if request.POST.get('rerun_expts'): - # # run all checked experiments (rerun if necessary) - # for exper in experiments_to_run: - # entity = Entity.objects.get(exper.keys()[0]) - # commit = Entity.objects.get(exper.value()) - # record_experiments_to_run(request.user, entity, commit) - # else: - # # only run checked experiments that have not already been run - # for exper in experiments_to_run: - # print(exper) - # record_experiments_to_run(request.user, entity, commit) - - # record_experiments_to_run(request.user, entity, commit) + if entity.entity_type == 'protocol': + exper_kwargs = { + 'model_id': ident, + 'model_version': sha, + 'protocol_id': entity.id, + 'protocol_version': entity.repo.latest_commit.hexsha, + } + else: + exper_kwargs = { + 'model_id': entity.id, + 'model_version': entity.repo.latest_commit.hexsha, + 'protocol_id': ident, + 'protocol_version': sha, + } + PlannedExperiment.objects.get_or_create(**exper_kwargs) return HttpResponseRedirect( reverse('entities:version', args=[kwargs['entity_type'], kwargs['pk'], 'latest'])) diff --git a/weblab/templates/entities/entity_runexperiments.html b/weblab/templates/entities/entity_runexperiments.html index c051eb0af..40a13e9fb 100644 --- a/weblab/templates/entities/entity_runexperiments.html +++ b/weblab/templates/entities/entity_runexperiments.html @@ -8,73 +8,67 @@ {% block content %}

    Run experiments using {{ entity.name }}

    - -

    - - Create new versions of existing experiments (if unchecked, existing combinations will be skipped) -

    -
    + {% endfor %} -

    Other {{ other_type }}s

    +

    Other {{ other_type }}s

    + {% endblock %} From c6ad76fd53a5d1676434d8a16e507008f01ed584 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 28 May 2019 14:27:02 +0100 Subject: [PATCH 32/53] divide listed entities into 'My' and 'Other' --- weblab/entities/tests/test_views.py | 56 +++++++++++++++++++ weblab/entities/views.py | 6 +- .../entities/entity_runexperiments.html | 42 ++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) diff --git a/weblab/entities/tests/test_views.py b/weblab/entities/tests/test_views.py index 4ebcbc26e..4b34a34a0 100644 --- a/weblab/entities/tests/test_views.py +++ b/weblab/entities/tests/test_views.py @@ -2075,6 +2075,33 @@ def test_view_run_experiment_model(self, client, helpers, logged_in_user): ] assert response.context['preposition'] == 'under' + def test_view_run_experiment_model_multiple_users(self, client, helpers, logged_in_user, other_user): + helpers.add_permission(logged_in_user, 'create_experiment', Experiment) + model = recipes.model.make(author=logged_in_user) + + protocol = recipes.protocol.make(author=logged_in_user) + commit1 = helpers.add_version(protocol, visibility='public') + commit2 = helpers.add_version(protocol, visibility='public') + protocol.add_tag('v1', commit2.hexsha) + + other_protocol = recipes.protocol.make(author=other_user) + other_commit1 = helpers.add_version(other_protocol, visibility='public') + other_commit2 = helpers.add_version(other_protocol, visibility='public') + other_protocol.add_tag('v1', other_commit2.hexsha) + response = client.get('/entities/models/%d/runexperiments/' % model.pk) + assert response.status_code == 200 + assert response.context['object_list'] == [{'id': protocol.pk, + 'name': 'myprotocol1', + 'versions': [{'commit': commit2, 'tags': ['v1'], 'latest': True}, + {'commit': commit1, 'tags': [], 'latest': False}]}, + ] + assert response.context['other_object_list'] == [{'id': other_protocol.pk, + 'name': 'myprotocol2', + 'versions': [{'commit': other_commit2, 'tags': ['v1'], 'latest': True}, + {'commit': other_commit1, 'tags': [], 'latest': False}]}, + ] + assert response.context['preposition'] == 'under' + def test_view_run_experiment_model_post(self, client, helpers, logged_in_user): helpers.add_permission(logged_in_user, 'create_experiment', Experiment) model = recipes.model.make(author=logged_in_user) @@ -2126,6 +2153,35 @@ def test_view_run_experiment_protocol(self, client, helpers, logged_in_user): ] assert response.context['preposition'] == 'on' + def test_view_run_experiment_protocol_multiple_users(self, client, helpers, logged_in_user, other_user): + helpers.add_permission(logged_in_user, 'create_experiment', Experiment) + model = recipes.model.make(author=logged_in_user) + commit1 = helpers.add_version(model, visibility='public') + commit2 = helpers.add_version(model, visibility='public') + model.add_tag('v1', commit2.hexsha) + protocol = recipes.protocol.make(author=logged_in_user) + + other_model = recipes.model.make(author=other_user) + other_commit1 = helpers.add_version(other_model, visibility='public') + other_commit2 = helpers.add_version(other_model, visibility='public') + other_model.add_tag('v1', other_commit2.hexsha) + + protocol = recipes.protocol.make(author=logged_in_user) + + response = client.get('/entities/protocols/%d/runexperiments/' % protocol.pk) + assert response.status_code == 200 + assert response.context['object_list'] == [{'id': model.pk, + 'name': 'mymodel1', + 'versions': [{'commit': commit2, 'tags': ['v1'], 'latest': True}, + {'commit': commit1, 'tags': [], 'latest': False}]}, + ] + assert response.context['other_object_list'] == [{'id': other_model.pk, + 'name': 'mymodel2', + 'versions': [{'commit': other_commit2, 'tags': ['v1'], 'latest': True}, + {'commit': other_commit1, 'tags': [], 'latest': False}]}, + ] + assert response.context['preposition'] == 'on' + def test_view_run_experiment_protocol_post(self, client, helpers, logged_in_user): helpers.add_permission(logged_in_user, 'create_experiment', Experiment) model = recipes.model.make(author=logged_in_user) diff --git a/weblab/entities/views.py b/weblab/entities/views.py index 56a118b99..f5d92eecc 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1039,6 +1039,7 @@ def get_context_data(self, **kwargs): other_entities = Entity.objects.filter(entity_type=entity.other_type)\ .select_related('cachedentity').prefetch_related('cachedentity__versions', 'cachedentity__versions__tags') context['object_list'] = [] + context['other_object_list'] = [] for item in other_entities: versions = item.cachedentity.versions version_info = [] @@ -1047,7 +1048,10 @@ def get_context_data(self, **kwargs): commit = item.repo.get_commit(version.sha) latest = item.repo.latest_commit version_info.append({'commit': commit, 'tags': tag_list, 'latest': latest == commit}) - context['object_list'].append({'id': item.id, 'name': item.name, 'versions': version_info}) + if item.author == self.request.user: + context['object_list'].append({'id': item.id, 'name': item.name, 'versions': version_info}) + else: + context['other_object_list'].append({'id': item.id, 'name': item.name, 'versions': version_info}) return context def post(self, request, *args, **kwargs): diff --git a/weblab/templates/entities/entity_runexperiments.html b/weblab/templates/entities/entity_runexperiments.html index 40a13e9fb..fae040421 100644 --- a/weblab/templates/entities/entity_runexperiments.html +++ b/weblab/templates/entities/entity_runexperiments.html @@ -69,6 +69,48 @@

    Your {{ other_type }}s

    Other {{ other_type }}s

    + + {% for entity_object in other_object_list %} + + {{ entity_object.name }} + + {% endfor %} + {% endblock %} From 5a27adfe2c3d8ab17f2fa22474d4b24007fba81d Mon Sep 17 00:00:00 2001 From: Sarah Date: Wed, 29 May 2019 09:03:40 +0100 Subject: [PATCH 33/53] testing of my vs other lists and running experiments --- weblab/entities/tests/test_views.py | 100 +++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 2 deletions(-) diff --git a/weblab/entities/tests/test_views.py b/weblab/entities/tests/test_views.py index 4b34a34a0..dd9736c1c 100644 --- a/weblab/entities/tests/test_views.py +++ b/weblab/entities/tests/test_views.py @@ -2099,7 +2099,7 @@ def test_view_run_experiment_model_multiple_users(self, client, helpers, logged_ 'name': 'myprotocol2', 'versions': [{'commit': other_commit2, 'tags': ['v1'], 'latest': True}, {'commit': other_commit1, 'tags': [], 'latest': False}]}, - ] + ] assert response.context['preposition'] == 'under' def test_view_run_experiment_model_post(self, client, helpers, logged_in_user): @@ -2137,6 +2137,55 @@ def test_view_run_experiment_model_post(self, client, helpers, logged_in_user): assert planned_experiment.model_version == commit_model.hexsha assert (planned_experiment.protocol, planned_experiment.protocol_version) in expected_proto_versions + def test_view_run_experiment_post_model_multiple_users(self, client, helpers, logged_in_user, other_user): + helpers.add_permission(logged_in_user, 'create_experiment', Experiment) + model = recipes.model.make(author=logged_in_user) + commit_model = helpers.add_version(model, visibility='public') + + protocol = recipes.protocol.make(author=logged_in_user) + commit1 = helpers.add_version(protocol, visibility='public') + commit2 = helpers.add_version(protocol, visibility='public') + protocol.add_tag('v1', commit2.hexsha) + + other_protocol = recipes.protocol.make(author=other_user) + other_commit1 = helpers.add_version(other_protocol, visibility='public') + other_commit2 = helpers.add_version(other_protocol, visibility='public') + other_protocol.add_tag('v1', other_commit2.hexsha) + + # check context + response = client.get('/entities/models/%d/runexperiments/' % model.pk) + assert response.status_code == 200 + assert response.context['object_list'] == [{'id': protocol.pk, + 'name': 'myprotocol1', + 'versions': [{'commit': commit2, 'tags': ['v1'], 'latest': True}, + {'commit': commit1, 'tags': [], 'latest': False}]}, + ] + assert response.context['other_object_list'] == [{'id': other_protocol.pk, + 'name': 'myprotocol2', + 'versions': [{'commit': other_commit2, 'tags': ['v1'], 'latest': True}, + {'commit': other_commit1, 'tags': [], 'latest': False}]}, + ] + # Test post returns correct response + data = {'runexperimentlist[]': ['%d:%s' % (protocol.pk, commit2.hexsha), + '%d:%s' % (other_protocol.pk, other_commit1.hexsha), + '%d:%s' % (other_protocol.pk, other_commit2.hexsha)], + 'entity.repo.latest_commit.hexsha': commit_model.hexsha} + response = client.post('/entities/models/%d/runexperiments/' % model.pk, data=data) + assert response.status_code == 302 + assert response.url == '/entities/models/%d/versions/latest' % model.pk + + # Test that planned experiments have been added correctly + expected_proto_versions = set([ + (protocol, commit2.hexsha), + (other_protocol, other_commit1.hexsha), + (other_protocol, other_commit2.hexsha) + ]) + assert PlannedExperiment.objects.count() == 3 + for planned_experiment in PlannedExperiment.objects.all(): + assert planned_experiment.model == model + assert planned_experiment.model_version == commit_model.hexsha + assert (planned_experiment.protocol, planned_experiment.protocol_version) in expected_proto_versions + def test_view_run_experiment_protocol(self, client, helpers, logged_in_user): helpers.add_permission(logged_in_user, 'create_experiment', Experiment) model = recipes.model.make(author=logged_in_user) @@ -2159,7 +2208,6 @@ def test_view_run_experiment_protocol_multiple_users(self, client, helpers, logg commit1 = helpers.add_version(model, visibility='public') commit2 = helpers.add_version(model, visibility='public') model.add_tag('v1', commit2.hexsha) - protocol = recipes.protocol.make(author=logged_in_user) other_model = recipes.model.make(author=other_user) other_commit1 = helpers.add_version(other_model, visibility='public') @@ -2215,3 +2263,51 @@ def test_view_run_experiment_protocol_post(self, client, helpers, logged_in_user assert planned_experiment.protocol_version == commit_protocol.hexsha assert (planned_experiment.model, planned_experiment.model_version) in expected_model_versions + def test_view_run_experiment_post_protocol_multiple_users(self, client, helpers, logged_in_user, other_user): + helpers.add_permission(logged_in_user, 'create_experiment', Experiment) + model = recipes.model.make(author=logged_in_user) + commit1 = helpers.add_version(model, visibility='public') + commit2 = helpers.add_version(model, visibility='public') + model.add_tag('v1', commit2.hexsha) + protocol = recipes.protocol.make(author=logged_in_user) + commit_protocol = helpers.add_version(protocol, visibility='public') + + other_model = recipes.model.make(author=other_user) + other_commit1 = helpers.add_version(other_model, visibility='public') + other_commit2 = helpers.add_version(other_model, visibility='public') + other_model.add_tag('v1', other_commit2.hexsha) + + response = client.get('/entities/protocols/%d/runexperiments/' % protocol.pk) + assert response.status_code == 200 + assert response.context['object_list'] == [{'id': model.pk, + 'name': 'mymodel1', + 'versions': [{'commit': commit2, 'tags': ['v1'], 'latest': True}, + {'commit': commit1, 'tags': [], 'latest': False}]}, + ] + assert response.context['other_object_list'] == [{'id': other_model.pk, + 'name': 'mymodel2', + 'versions': [{'commit': other_commit2, 'tags': ['v1'], 'latest': True}, + {'commit': other_commit1, 'tags': [], 'latest': False}]}, + ] + # Test post returns correct response + data = {'runexperimentlist[]': ['%d:%s' % (model.pk, commit1.hexsha), + '%d:%s' % (model.pk, commit2.hexsha), + '%d:%s' % (other_model.pk, other_commit1.hexsha)], + 'entity.repo.latest_commit.hexsha': commit_protocol.hexsha} + response = client.post('/entities/protocols/%d/runexperiments/' % protocol.pk, data=data) + assert response.status_code == 302 + assert response.url == '/entities/protocols/%d/versions/latest' % protocol.pk + + # Test that planned experiments have been added correctly + expected_model_versions = set([ + (model, commit2.hexsha), + (model, commit1.hexsha), + (other_model, other_commit1.hexsha) + ]) + assert PlannedExperiment.objects.count() == 3 + for planned_experiment in PlannedExperiment.objects.all(): + assert planned_experiment.protocol == protocol + assert planned_experiment.protocol_version == commit_protocol.hexsha + assert (planned_experiment.model, planned_experiment.model_version) in expected_model_versions + + From 9b1e47d56c2199b439d660548b0d10d013d559d7 Mon Sep 17 00:00:00 2001 From: Sarah Date: Wed, 29 May 2019 12:17:55 +0100 Subject: [PATCH 34/53] Got the force or not to force rerun checkbox working --- weblab/entities/tests/test_views.py | 99 ++++++++++++++++++- weblab/entities/views.py | 33 ++++--- .../entities/entity_runexperiments.html | 8 +- 3 files changed, 117 insertions(+), 23 deletions(-) diff --git a/weblab/entities/tests/test_views.py b/weblab/entities/tests/test_views.py index dd9736c1c..a62651fbc 100644 --- a/weblab/entities/tests/test_views.py +++ b/weblab/entities/tests/test_views.py @@ -2122,7 +2122,52 @@ def test_view_run_experiment_model_post(self, client, helpers, logged_in_user): ] # Test post returns correct response data = {'runexperimentlist[]': ['%d:%s' % (protocol.pk, commit2.hexsha)], - 'entity.repo.latest_commit.hexsha': commit_model.hexsha} + 'entity.repo.latest_commit.hexsha': commit_model.hexsha, + 'rerun_expts': 'on'} + response = client.post('/entities/models/%d/runexperiments/' % model.pk, data=data) + assert response.status_code == 302 + assert response.url == '/entities/models/%d/versions/latest' % model.pk + + # Test that planned experiments have been added correctly + expected_proto_versions = set([ + (protocol, commit2.hexsha) + ]) + assert PlannedExperiment.objects.count() == 1 + for planned_experiment in PlannedExperiment.objects.all(): + assert planned_experiment.model == model + assert planned_experiment.model_version == commit_model.hexsha + assert (planned_experiment.protocol, planned_experiment.protocol_version) in expected_proto_versions + + def test_view_run_experiment_model_post_exclude_existing(self, client, helpers, logged_in_user): + helpers.add_permission(logged_in_user, 'create_experiment', Experiment) + model = recipes.model.make(author=logged_in_user) + commit_model = helpers.add_version(model, visibility='public') + + protocol = recipes.protocol.make(author=logged_in_user) + commit1 = helpers.add_version(protocol, visibility='public') + commit2 = helpers.add_version(protocol, visibility='public') + protocol.add_tag('v1', commit2.hexsha) + + recipes.experiment_version.make( + status='SUCCESS', + experiment__model=model, + experiment__model_version=commit_model.hexsha, + experiment__protocol=protocol, + experiment__protocol_version=commit1.hexsha) + + # Test context has correct information + response = client.get('/entities/models/%d/runexperiments/' % model.pk) + assert response.status_code == 200 + assert response.context['object_list'] == [{'id': protocol.pk, + 'name': 'myprotocol1', + 'versions': [{'commit': commit2, 'tags': ['v1'], 'latest': True}, + {'commit': commit1, 'tags': [], 'latest': False}]}, + ] + # Test post returns correct response + data = {'runexperimentlist[]': ['%d:%s' % (protocol.pk, commit1.hexsha), + '%d:%s' % (protocol.pk, commit2.hexsha)], + 'entity.repo.latest_commit.hexsha': commit_model.hexsha, + 'rerun_expts': None} response = client.post('/entities/models/%d/runexperiments/' % model.pk, data=data) assert response.status_code == 302 assert response.url == '/entities/models/%d/versions/latest' % model.pk @@ -2169,7 +2214,8 @@ def test_view_run_experiment_post_model_multiple_users(self, client, helpers, lo data = {'runexperimentlist[]': ['%d:%s' % (protocol.pk, commit2.hexsha), '%d:%s' % (other_protocol.pk, other_commit1.hexsha), '%d:%s' % (other_protocol.pk, other_commit2.hexsha)], - 'entity.repo.latest_commit.hexsha': commit_model.hexsha} + 'entity.repo.latest_commit.hexsha': commit_model.hexsha, + 'rerun_expts': 'on'} response = client.post('/entities/models/%d/runexperiments/' % model.pk, data=data) assert response.status_code == 302 assert response.url == '/entities/models/%d/versions/latest' % model.pk @@ -2186,6 +2232,7 @@ def test_view_run_experiment_post_model_multiple_users(self, client, helpers, lo assert planned_experiment.model_version == commit_model.hexsha assert (planned_experiment.protocol, planned_experiment.protocol_version) in expected_proto_versions + # repeat tests with protocol as the calling entity def test_view_run_experiment_protocol(self, client, helpers, logged_in_user): helpers.add_permission(logged_in_user, 'create_experiment', Experiment) model = recipes.model.make(author=logged_in_user) @@ -2247,7 +2294,8 @@ def test_view_run_experiment_protocol_post(self, client, helpers, logged_in_user ] # Test post returns correct response data = {'runexperimentlist[]': ['%d:%s' % (model.pk, commit1.hexsha), '%d:%s' % (model.pk, commit2.hexsha)], - 'entity.repo.latest_commit.hexsha': commit_protocol.hexsha} + 'entity.repo.latest_commit.hexsha': commit_protocol.hexsha, + 'rerun_expts': 'on'} response = client.post('/entities/protocols/%d/runexperiments/' % protocol.pk, data=data) assert response.status_code == 302 assert response.url == '/entities/protocols/%d/versions/latest' % protocol.pk @@ -2263,6 +2311,48 @@ def test_view_run_experiment_protocol_post(self, client, helpers, logged_in_user assert planned_experiment.protocol_version == commit_protocol.hexsha assert (planned_experiment.model, planned_experiment.model_version) in expected_model_versions + def test_view_run_experiment_protocol_post_exclude_existing(self, client, helpers, logged_in_user): + helpers.add_permission(logged_in_user, 'create_experiment', Experiment) + model = recipes.model.make(author=logged_in_user) + commit1 = helpers.add_version(model, visibility='public') + commit2 = helpers.add_version(model, visibility='public') + model.add_tag('v1', commit2.hexsha) + protocol = recipes.protocol.make(author=logged_in_user) + commit_protocol = helpers.add_version(protocol, visibility='public') + + recipes.experiment_version.make( + status='SUCCESS', + experiment__model=model, + experiment__model_version=commit1.hexsha, + experiment__protocol=protocol, + experiment__protocol_version=commit_protocol.hexsha) + + # Test context has correct information + response = client.get('/entities/protocols/%d/runexperiments/' % protocol.pk) + assert response.status_code == 200 + assert response.context['object_list'] == [{'id': model.pk, + 'name': 'mymodel1', + 'versions': [{'commit': commit2, 'tags': ['v1'], 'latest': True}, + {'commit': commit1, 'tags': [], 'latest': False}]}, + ] + # Test post returns correct response + data = {'runexperimentlist[]': ['%d:%s' % (model.pk, commit1.hexsha), '%d:%s' % (model.pk, commit2.hexsha)], + 'entity.repo.latest_commit.hexsha': commit_protocol.hexsha, + 'rerun_expts': None} + response = client.post('/entities/protocols/%d/runexperiments/' % protocol.pk, data=data) + assert response.status_code == 302 + assert response.url == '/entities/protocols/%d/versions/latest' % protocol.pk + + # Test that planned experiments have been added correctly + expected_model_versions = set([ + (model, commit2.hexsha), + ]) + assert PlannedExperiment.objects.count() == 1 + for planned_experiment in PlannedExperiment.objects.all(): + assert planned_experiment.protocol == protocol + assert planned_experiment.protocol_version == commit_protocol.hexsha + assert (planned_experiment.model, planned_experiment.model_version) in expected_model_versions + def test_view_run_experiment_post_protocol_multiple_users(self, client, helpers, logged_in_user, other_user): helpers.add_permission(logged_in_user, 'create_experiment', Experiment) model = recipes.model.make(author=logged_in_user) @@ -2293,7 +2383,8 @@ def test_view_run_experiment_post_protocol_multiple_users(self, client, helpers, data = {'runexperimentlist[]': ['%d:%s' % (model.pk, commit1.hexsha), '%d:%s' % (model.pk, commit2.hexsha), '%d:%s' % (other_model.pk, other_commit1.hexsha)], - 'entity.repo.latest_commit.hexsha': commit_protocol.hexsha} + 'entity.repo.latest_commit.hexsha': commit_protocol.hexsha, + 'rerun_expts': 'on'} response = client.post('/entities/protocols/%d/runexperiments/' % protocol.pk, data=data) assert response.status_code == 302 assert response.url == '/entities/protocols/%d/versions/latest' % protocol.pk diff --git a/weblab/entities/views.py b/weblab/entities/views.py index f5d92eecc..8000e5f0e 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1058,25 +1058,28 @@ def post(self, request, *args, **kwargs): # this in not intuitive # in get context self.object was the entity being worked with # here we have to retrieve it - entity = self.get_object() + this_entity = self.get_object() + + rerun = request.POST.get('rerun_expts') + exclude_existing = False + # look for 'None' string as this seems to be what test data passes for a NoneType + if not rerun or rerun == 'None': + exclude_existing = True experiments_to_run = request.POST.getlist('runexperimentlist[]') for version in experiments_to_run: ident, sha = version.split(':') - if entity.entity_type == 'protocol': - exper_kwargs = { - 'model_id': ident, - 'model_version': sha, - 'protocol_id': entity.id, - 'protocol_version': entity.repo.latest_commit.hexsha, - } - else: - exper_kwargs = { - 'model_id': entity.id, - 'model_version': entity.repo.latest_commit.hexsha, - 'protocol_id': ident, - 'protocol_version': sha, - } + exper_kwargs = { + this_entity.other_type + '_id': ident, + this_entity.other_type + '_version': sha, + this_entity.entity_type + '_id': this_entity.id, + this_entity.entity_type + '_version': this_entity.repo.latest_commit.hexsha, + } + if exclude_existing: + existing = Experiment.objects.filter(**exper_kwargs) + if existing: + continue PlannedExperiment.objects.get_or_create(**exper_kwargs) + # return to entity page return HttpResponseRedirect( reverse('entities:version', args=[kwargs['entity_type'], kwargs['pk'], 'latest'])) diff --git a/weblab/templates/entities/entity_runexperiments.html b/weblab/templates/entities/entity_runexperiments.html index fae040421..6f4baa9c1 100644 --- a/weblab/templates/entities/entity_runexperiments.html +++ b/weblab/templates/entities/entity_runexperiments.html @@ -8,10 +8,6 @@ {% block content %}

    Run experiments using {{ entity.name }}

    -

    - - Create new versions of existing experiments (if unchecked, existing combinations will be skipped) -

    @@ -19,6 +15,10 @@

    Run experiments using {{ entity.name }}

    {% csrf_token %} +

    + + Create new versions of existing experiments (if unchecked, existing combinations will be skipped) +

    You may run this {{ type }} {{ preposition }} the following {{ other_type }}s.

    From e1bf92d3cc80ffb0f0564b1637b232336a111f5d Mon Sep 17 00:00:00 2001 From: Sarah Date: Wed, 29 May 2019 16:39:07 +0100 Subject: [PATCH 35/53] changed spelling of function to be more python-esque Thanks Michael --- weblab/entities/templatetags/entities.py | 2 +- weblab/entities/tests/test_templatetags.py | 4 ++-- weblab/templates/entities/entity_version.html | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/weblab/entities/templatetags/entities.py b/weblab/entities/templatetags/entities.py index d154d65d3..d5cb1b6b1 100644 --- a/weblab/entities/templatetags/entities.py +++ b/weblab/entities/templatetags/entities.py @@ -192,5 +192,5 @@ def can_manage_entity(context, entity): @register.filter -def url_runexperiments(entity): +def url_run_experiments(entity): return reverse('entities:runexperiments', args=[entity.entity_type, entity.id]) diff --git a/weblab/entities/tests/test_templatetags.py b/weblab/entities/tests/test_templatetags.py index e76bba137..9aef0fe85 100644 --- a/weblab/entities/tests/test_templatetags.py +++ b/weblab/entities/tests/test_templatetags.py @@ -128,9 +128,9 @@ def test_url_friendly_label(model_with_version, helpers): @pytest.mark.django_db def test_url_runexperiments(model_with_version, protocol_with_version): model = model_with_version - assert (entity_tags.url_runexperiments(model) == + assert (entity_tags.url_run_experiments(model) == '/entities/models/%d/runexperiments/' % model.pk) protocol = protocol_with_version - assert (entity_tags.url_runexperiments(protocol) == + assert (entity_tags.url_run_experiments(protocol) == '/entities/protocols/%d/runexperiments/' % protocol.pk) diff --git a/weblab/templates/entities/entity_version.html b/weblab/templates/entities/entity_version.html index 2de306fd6..bc8ff336b 100644 --- a/weblab/templates/entities/entity_version.html +++ b/weblab/templates/entities/entity_version.html @@ -45,7 +45,7 @@

    {% if perms.create_experiment %} Run experiments: - + Run experiments: {% endif %} From 2986d6847289c148cbb77ed6b485431007e6c926 Mon Sep 17 00:00:00 2001 From: Sarah Date: Thu, 30 May 2019 15:20:25 +0100 Subject: [PATCH 36/53] changed name and added additional test for no checkboxes checked --- weblab/entities/tests/test_views.py | 50 ++++++++++++++++--- weblab/entities/views.py | 2 +- .../entities/entity_runexperiments.html | 8 +-- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/weblab/entities/tests/test_views.py b/weblab/entities/tests/test_views.py index a62651fbc..9624efe5e 100644 --- a/weblab/entities/tests/test_views.py +++ b/weblab/entities/tests/test_views.py @@ -2121,7 +2121,7 @@ def test_view_run_experiment_model_post(self, client, helpers, logged_in_user): {'commit': commit1, 'tags': [], 'latest': False}]}, ] # Test post returns correct response - data = {'runexperimentlist[]': ['%d:%s' % (protocol.pk, commit2.hexsha)], + data = {'model_protocol_list[]': ['%d:%s' % (protocol.pk, commit2.hexsha)], 'entity.repo.latest_commit.hexsha': commit_model.hexsha, 'rerun_expts': 'on'} response = client.post('/entities/models/%d/runexperiments/' % model.pk, data=data) @@ -2164,7 +2164,7 @@ def test_view_run_experiment_model_post_exclude_existing(self, client, helpers, {'commit': commit1, 'tags': [], 'latest': False}]}, ] # Test post returns correct response - data = {'runexperimentlist[]': ['%d:%s' % (protocol.pk, commit1.hexsha), + data = {'model_protocol_list[]': ['%d:%s' % (protocol.pk, commit1.hexsha), '%d:%s' % (protocol.pk, commit2.hexsha)], 'entity.repo.latest_commit.hexsha': commit_model.hexsha, 'rerun_expts': None} @@ -2211,7 +2211,7 @@ def test_view_run_experiment_post_model_multiple_users(self, client, helpers, lo {'commit': other_commit1, 'tags': [], 'latest': False}]}, ] # Test post returns correct response - data = {'runexperimentlist[]': ['%d:%s' % (protocol.pk, commit2.hexsha), + data = {'model_protocol_list[]': ['%d:%s' % (protocol.pk, commit2.hexsha), '%d:%s' % (other_protocol.pk, other_commit1.hexsha), '%d:%s' % (other_protocol.pk, other_commit2.hexsha)], 'entity.repo.latest_commit.hexsha': commit_model.hexsha, @@ -2293,7 +2293,7 @@ def test_view_run_experiment_protocol_post(self, client, helpers, logged_in_user {'commit': commit1, 'tags': [], 'latest': False}]}, ] # Test post returns correct response - data = {'runexperimentlist[]': ['%d:%s' % (model.pk, commit1.hexsha), '%d:%s' % (model.pk, commit2.hexsha)], + data = {'model_protocol_list[]': ['%d:%s' % (model.pk, commit1.hexsha), '%d:%s' % (model.pk, commit2.hexsha)], 'entity.repo.latest_commit.hexsha': commit_protocol.hexsha, 'rerun_expts': 'on'} response = client.post('/entities/protocols/%d/runexperiments/' % protocol.pk, data=data) @@ -2336,7 +2336,7 @@ def test_view_run_experiment_protocol_post_exclude_existing(self, client, helper {'commit': commit1, 'tags': [], 'latest': False}]}, ] # Test post returns correct response - data = {'runexperimentlist[]': ['%d:%s' % (model.pk, commit1.hexsha), '%d:%s' % (model.pk, commit2.hexsha)], + data = {'model_protocol_list[]': ['%d:%s' % (model.pk, commit1.hexsha), '%d:%s' % (model.pk, commit2.hexsha)], 'entity.repo.latest_commit.hexsha': commit_protocol.hexsha, 'rerun_expts': None} response = client.post('/entities/protocols/%d/runexperiments/' % protocol.pk, data=data) @@ -2380,7 +2380,7 @@ def test_view_run_experiment_post_protocol_multiple_users(self, client, helpers, {'commit': other_commit1, 'tags': [], 'latest': False}]}, ] # Test post returns correct response - data = {'runexperimentlist[]': ['%d:%s' % (model.pk, commit1.hexsha), + data = {'model_protocol_list[]': ['%d:%s' % (model.pk, commit1.hexsha), '%d:%s' % (model.pk, commit2.hexsha), '%d:%s' % (other_model.pk, other_commit1.hexsha)], 'entity.repo.latest_commit.hexsha': commit_protocol.hexsha, @@ -2401,4 +2401,42 @@ def test_view_run_experiment_post_protocol_multiple_users(self, client, helpers, assert planned_experiment.protocol_version == commit_protocol.hexsha assert (planned_experiment.model, planned_experiment.model_version) in expected_model_versions + def test_view_run_experiment_none_checked(self, client, helpers, logged_in_user): + helpers.add_permission(logged_in_user, 'create_experiment', Experiment) + model = recipes.model.make(author=logged_in_user) + commit_model = helpers.add_version(model, visibility='public') + + protocol = recipes.protocol.make(author=logged_in_user) + commit1 = helpers.add_version(protocol, visibility='public') + commit2 = helpers.add_version(protocol, visibility='public') + protocol.add_tag('v1', commit2.hexsha) + + # Test context has correct information + response = client.get('/entities/models/%d/runexperiments/' % model.pk) + assert response.status_code == 200 + assert response.context['object_list'] == [{'id': protocol.pk, + 'name': 'myprotocol1', + 'versions': [{'commit': commit2, 'tags': ['v1'], 'latest': True}, + {'commit': commit1, 'tags': [], 'latest': False}]}, + ] + # Test post returns correct response + data = {'model_protocol_list[]': [], + 'entity.repo.latest_commit.hexsha': commit_model.hexsha, + 'rerun_expts': 'on'} + response = client.post('/entities/models/%d/runexperiments/' % model.pk, data=data) + assert response.status_code == 302 + assert response.url == '/entities/models/%d/versions/latest' % model.pk + + # Test that no planned experiments have been added + assert PlannedExperiment.objects.count() == 0 + + data = {'model_protocol_list[]': [], + 'entity.repo.latest_commit.hexsha': commit_model.hexsha, + 'rerun_expts': None} + response = client.post('/entities/models/%d/runexperiments/' % model.pk, data=data) + assert response.status_code == 302 + assert response.url == '/entities/models/%d/versions/latest' % model.pk + + # Test that no planned experiments have been added + assert PlannedExperiment.objects.count() == 0 diff --git a/weblab/entities/views.py b/weblab/entities/views.py index 8000e5f0e..199dbee2f 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1065,7 +1065,7 @@ def post(self, request, *args, **kwargs): # look for 'None' string as this seems to be what test data passes for a NoneType if not rerun or rerun == 'None': exclude_existing = True - experiments_to_run = request.POST.getlist('runexperimentlist[]') + experiments_to_run = request.POST.getlist('model_protocol_list[]') for version in experiments_to_run: ident, sha = version.split(':') exper_kwargs = { diff --git a/weblab/templates/entities/entity_runexperiments.html b/weblab/templates/entities/entity_runexperiments.html index 6f4baa9c1..dbca6064e 100644 --- a/weblab/templates/entities/entity_runexperiments.html +++ b/weblab/templates/entities/entity_runexperiments.html @@ -38,12 +38,12 @@

    Your {{ other_type }}s

    {% else %} + name="model_protocol_list[]"/> {% endif %}
    @@ -82,12 +82,12 @@

    Other {{ other_type }}s

    {% else %} + name="model_protocol_list[]"/> {% endif %}
    From dcf1a71a7ed9900f0efe4890a3bb3c3bdd4cd13c Mon Sep 17 00:00:00 2001 From: Sarah Date: Thu, 30 May 2019 15:44:57 +0100 Subject: [PATCH 37/53] few more changes from Jonathan - mostly syntax --- weblab/entities/tests/test_templatetags.py | 4 +-- weblab/entities/tests/test_views.py | 38 +++++++++++----------- weblab/entities/urls.py | 2 +- weblab/entities/views.py | 12 +++++-- 4 files changed, 31 insertions(+), 25 deletions(-) diff --git a/weblab/entities/tests/test_templatetags.py b/weblab/entities/tests/test_templatetags.py index 9aef0fe85..568191368 100644 --- a/weblab/entities/tests/test_templatetags.py +++ b/weblab/entities/tests/test_templatetags.py @@ -129,8 +129,8 @@ def test_url_friendly_label(model_with_version, helpers): def test_url_runexperiments(model_with_version, protocol_with_version): model = model_with_version assert (entity_tags.url_run_experiments(model) == - '/entities/models/%d/runexperiments/' % model.pk) + '/entities/models/%d/runexperiments' % model.pk) protocol = protocol_with_version assert (entity_tags.url_run_experiments(protocol) == - '/entities/protocols/%d/runexperiments/' % protocol.pk) + '/entities/protocols/%d/runexperiments' % protocol.pk) diff --git a/weblab/entities/tests/test_views.py b/weblab/entities/tests/test_views.py index 9624efe5e..3bcf7df80 100644 --- a/weblab/entities/tests/test_views.py +++ b/weblab/entities/tests/test_views.py @@ -2066,7 +2066,7 @@ def test_view_run_experiment_model(self, client, helpers, logged_in_user): commit2 = helpers.add_version(protocol, visibility='public') protocol.add_tag('v1', commit2.hexsha) - response = client.get('/entities/models/%d/runexperiments/' % model.pk) + response = client.get('/entities/models/%d/runexperiments' % model.pk) assert response.status_code == 200 assert response.context['object_list'] == [{'id': protocol.pk, 'name': 'myprotocol1', @@ -2088,7 +2088,7 @@ def test_view_run_experiment_model_multiple_users(self, client, helpers, logged_ other_commit1 = helpers.add_version(other_protocol, visibility='public') other_commit2 = helpers.add_version(other_protocol, visibility='public') other_protocol.add_tag('v1', other_commit2.hexsha) - response = client.get('/entities/models/%d/runexperiments/' % model.pk) + response = client.get('/entities/models/%d/runexperiments' % model.pk) assert response.status_code == 200 assert response.context['object_list'] == [{'id': protocol.pk, 'name': 'myprotocol1', @@ -2113,7 +2113,7 @@ def test_view_run_experiment_model_post(self, client, helpers, logged_in_user): protocol.add_tag('v1', commit2.hexsha) # Test context has correct information - response = client.get('/entities/models/%d/runexperiments/' % model.pk) + response = client.get('/entities/models/%d/runexperiments' % model.pk) assert response.status_code == 200 assert response.context['object_list'] == [{'id': protocol.pk, 'name': 'myprotocol1', @@ -2124,7 +2124,7 @@ def test_view_run_experiment_model_post(self, client, helpers, logged_in_user): data = {'model_protocol_list[]': ['%d:%s' % (protocol.pk, commit2.hexsha)], 'entity.repo.latest_commit.hexsha': commit_model.hexsha, 'rerun_expts': 'on'} - response = client.post('/entities/models/%d/runexperiments/' % model.pk, data=data) + response = client.post('/entities/models/%d/runexperiments' % model.pk, data=data) assert response.status_code == 302 assert response.url == '/entities/models/%d/versions/latest' % model.pk @@ -2156,7 +2156,7 @@ def test_view_run_experiment_model_post_exclude_existing(self, client, helpers, experiment__protocol_version=commit1.hexsha) # Test context has correct information - response = client.get('/entities/models/%d/runexperiments/' % model.pk) + response = client.get('/entities/models/%d/runexperiments' % model.pk) assert response.status_code == 200 assert response.context['object_list'] == [{'id': protocol.pk, 'name': 'myprotocol1', @@ -2168,7 +2168,7 @@ def test_view_run_experiment_model_post_exclude_existing(self, client, helpers, '%d:%s' % (protocol.pk, commit2.hexsha)], 'entity.repo.latest_commit.hexsha': commit_model.hexsha, 'rerun_expts': None} - response = client.post('/entities/models/%d/runexperiments/' % model.pk, data=data) + response = client.post('/entities/models/%d/runexperiments' % model.pk, data=data) assert response.status_code == 302 assert response.url == '/entities/models/%d/versions/latest' % model.pk @@ -2198,7 +2198,7 @@ def test_view_run_experiment_post_model_multiple_users(self, client, helpers, lo other_protocol.add_tag('v1', other_commit2.hexsha) # check context - response = client.get('/entities/models/%d/runexperiments/' % model.pk) + response = client.get('/entities/models/%d/runexperiments' % model.pk) assert response.status_code == 200 assert response.context['object_list'] == [{'id': protocol.pk, 'name': 'myprotocol1', @@ -2216,7 +2216,7 @@ def test_view_run_experiment_post_model_multiple_users(self, client, helpers, lo '%d:%s' % (other_protocol.pk, other_commit2.hexsha)], 'entity.repo.latest_commit.hexsha': commit_model.hexsha, 'rerun_expts': 'on'} - response = client.post('/entities/models/%d/runexperiments/' % model.pk, data=data) + response = client.post('/entities/models/%d/runexperiments' % model.pk, data=data) assert response.status_code == 302 assert response.url == '/entities/models/%d/versions/latest' % model.pk @@ -2240,7 +2240,7 @@ def test_view_run_experiment_protocol(self, client, helpers, logged_in_user): commit2 = helpers.add_version(model, visibility='public') model.add_tag('v1', commit2.hexsha) protocol = recipes.protocol.make(author=logged_in_user) - response = client.get('/entities/protocols/%d/runexperiments/' % protocol.pk) + response = client.get('/entities/protocols/%d/runexperiments' % protocol.pk) assert response.status_code == 200 assert response.context['object_list'] == [{'id': model.pk, 'name': 'mymodel1', @@ -2263,7 +2263,7 @@ def test_view_run_experiment_protocol_multiple_users(self, client, helpers, logg protocol = recipes.protocol.make(author=logged_in_user) - response = client.get('/entities/protocols/%d/runexperiments/' % protocol.pk) + response = client.get('/entities/protocols/%d/runexperiments' % protocol.pk) assert response.status_code == 200 assert response.context['object_list'] == [{'id': model.pk, 'name': 'mymodel1', @@ -2285,7 +2285,7 @@ def test_view_run_experiment_protocol_post(self, client, helpers, logged_in_user model.add_tag('v1', commit2.hexsha) protocol = recipes.protocol.make(author=logged_in_user) commit_protocol = helpers.add_version(protocol, visibility='public') - response = client.get('/entities/protocols/%d/runexperiments/' % protocol.pk) + response = client.get('/entities/protocols/%d/runexperiments' % protocol.pk) assert response.status_code == 200 assert response.context['object_list'] == [{'id': model.pk, 'name': 'mymodel1', @@ -2296,7 +2296,7 @@ def test_view_run_experiment_protocol_post(self, client, helpers, logged_in_user data = {'model_protocol_list[]': ['%d:%s' % (model.pk, commit1.hexsha), '%d:%s' % (model.pk, commit2.hexsha)], 'entity.repo.latest_commit.hexsha': commit_protocol.hexsha, 'rerun_expts': 'on'} - response = client.post('/entities/protocols/%d/runexperiments/' % protocol.pk, data=data) + response = client.post('/entities/protocols/%d/runexperiments' % protocol.pk, data=data) assert response.status_code == 302 assert response.url == '/entities/protocols/%d/versions/latest' % protocol.pk @@ -2328,7 +2328,7 @@ def test_view_run_experiment_protocol_post_exclude_existing(self, client, helper experiment__protocol_version=commit_protocol.hexsha) # Test context has correct information - response = client.get('/entities/protocols/%d/runexperiments/' % protocol.pk) + response = client.get('/entities/protocols/%d/runexperiments' % protocol.pk) assert response.status_code == 200 assert response.context['object_list'] == [{'id': model.pk, 'name': 'mymodel1', @@ -2339,7 +2339,7 @@ def test_view_run_experiment_protocol_post_exclude_existing(self, client, helper data = {'model_protocol_list[]': ['%d:%s' % (model.pk, commit1.hexsha), '%d:%s' % (model.pk, commit2.hexsha)], 'entity.repo.latest_commit.hexsha': commit_protocol.hexsha, 'rerun_expts': None} - response = client.post('/entities/protocols/%d/runexperiments/' % protocol.pk, data=data) + response = client.post('/entities/protocols/%d/runexperiments' % protocol.pk, data=data) assert response.status_code == 302 assert response.url == '/entities/protocols/%d/versions/latest' % protocol.pk @@ -2367,7 +2367,7 @@ def test_view_run_experiment_post_protocol_multiple_users(self, client, helpers, other_commit2 = helpers.add_version(other_model, visibility='public') other_model.add_tag('v1', other_commit2.hexsha) - response = client.get('/entities/protocols/%d/runexperiments/' % protocol.pk) + response = client.get('/entities/protocols/%d/runexperiments' % protocol.pk) assert response.status_code == 200 assert response.context['object_list'] == [{'id': model.pk, 'name': 'mymodel1', @@ -2385,7 +2385,7 @@ def test_view_run_experiment_post_protocol_multiple_users(self, client, helpers, '%d:%s' % (other_model.pk, other_commit1.hexsha)], 'entity.repo.latest_commit.hexsha': commit_protocol.hexsha, 'rerun_expts': 'on'} - response = client.post('/entities/protocols/%d/runexperiments/' % protocol.pk, data=data) + response = client.post('/entities/protocols/%d/runexperiments' % protocol.pk, data=data) assert response.status_code == 302 assert response.url == '/entities/protocols/%d/versions/latest' % protocol.pk @@ -2412,7 +2412,7 @@ def test_view_run_experiment_none_checked(self, client, helpers, logged_in_user) protocol.add_tag('v1', commit2.hexsha) # Test context has correct information - response = client.get('/entities/models/%d/runexperiments/' % model.pk) + response = client.get('/entities/models/%d/runexperiments' % model.pk) assert response.status_code == 200 assert response.context['object_list'] == [{'id': protocol.pk, 'name': 'myprotocol1', @@ -2423,7 +2423,7 @@ def test_view_run_experiment_none_checked(self, client, helpers, logged_in_user) data = {'model_protocol_list[]': [], 'entity.repo.latest_commit.hexsha': commit_model.hexsha, 'rerun_expts': 'on'} - response = client.post('/entities/models/%d/runexperiments/' % model.pk, data=data) + response = client.post('/entities/models/%d/runexperiments' % model.pk, data=data) assert response.status_code == 302 assert response.url == '/entities/models/%d/versions/latest' % model.pk @@ -2433,7 +2433,7 @@ def test_view_run_experiment_none_checked(self, client, helpers, logged_in_user) data = {'model_protocol_list[]': [], 'entity.repo.latest_commit.hexsha': commit_model.hexsha, 'rerun_expts': None} - response = client.post('/entities/models/%d/runexperiments/' % model.pk, data=data) + response = client.post('/entities/models/%d/runexperiments' % model.pk, data=data) assert response.status_code == 302 assert response.url == '/entities/models/%d/versions/latest' % model.pk diff --git a/weblab/entities/urls.py b/weblab/entities/urls.py index 0107f9742..210eefa5c 100644 --- a/weblab/entities/urls.py +++ b/weblab/entities/urls.py @@ -137,7 +137,7 @@ ), url( - r'^%s/(?P\d+)/runexperiments/$' % _ENTITY_TYPE, + r'^%s/(?P\d+)/runexperiments$' % _ENTITY_TYPE, views.EntityRunExperimentView.as_view(), name='runexperiments', ), diff --git a/weblab/entities/views.py b/weblab/entities/views.py index 199dbee2f..2bbe1a6cc 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1018,7 +1018,7 @@ def get(self, request, *args, **kwargs): class EntityRunExperimentView(PermissionRequiredMixin, LoginRequiredMixin, EntityTypeMixin, DetailView): """ - Class for listing the possible experiment combinations + A view allowing users to set up a batch-run of experiments involving a single entity. """ permission_required = 'experiments.create_experiment' context_object_name = 'entity' @@ -1036,8 +1036,14 @@ def get_context_data(self, **kwargs): # ended up using a nested dict as nested lists caused django's unpacking in forloops to # mess things up slightly - other_entities = Entity.objects.filter(entity_type=entity.other_type)\ - .select_related('cachedentity').prefetch_related('cachedentity__versions', 'cachedentity__versions__tags') + other_entities = Entity.objects.filter( + entity_type=entity.other_type + ).select_related( + 'cachedentity' + ).prefetch_related( + 'cachedentity__versions', + 'cachedentity__versions__tags' + ) context['object_list'] = [] context['other_object_list'] = [] for item in other_entities: From 4b7ded9b73e6c0a0526a2340507c9f62e1205496 Mon Sep 17 00:00:00 2001 From: Sarah Date: Thu, 30 May 2019 16:01:27 +0100 Subject: [PATCH 38/53] more changes from Jonathan --- weblab/entities/tests/test_views.py | 10 +++++----- weblab/entities/views.py | 12 ++++-------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/weblab/entities/tests/test_views.py b/weblab/entities/tests/test_views.py index 3bcf7df80..92eed0611 100644 --- a/weblab/entities/tests/test_views.py +++ b/weblab/entities/tests/test_views.py @@ -2166,8 +2166,8 @@ def test_view_run_experiment_model_post_exclude_existing(self, client, helpers, # Test post returns correct response data = {'model_protocol_list[]': ['%d:%s' % (protocol.pk, commit1.hexsha), '%d:%s' % (protocol.pk, commit2.hexsha)], - 'entity.repo.latest_commit.hexsha': commit_model.hexsha, - 'rerun_expts': None} + 'entity.repo.latest_commit.hexsha': commit_model.hexsha + } response = client.post('/entities/models/%d/runexperiments' % model.pk, data=data) assert response.status_code == 302 assert response.url == '/entities/models/%d/versions/latest' % model.pk @@ -2338,7 +2338,7 @@ def test_view_run_experiment_protocol_post_exclude_existing(self, client, helper # Test post returns correct response data = {'model_protocol_list[]': ['%d:%s' % (model.pk, commit1.hexsha), '%d:%s' % (model.pk, commit2.hexsha)], 'entity.repo.latest_commit.hexsha': commit_protocol.hexsha, - 'rerun_expts': None} + } response = client.post('/entities/protocols/%d/runexperiments' % protocol.pk, data=data) assert response.status_code == 302 assert response.url == '/entities/protocols/%d/versions/latest' % protocol.pk @@ -2431,8 +2431,8 @@ def test_view_run_experiment_none_checked(self, client, helpers, logged_in_user) assert PlannedExperiment.objects.count() == 0 data = {'model_protocol_list[]': [], - 'entity.repo.latest_commit.hexsha': commit_model.hexsha, - 'rerun_expts': None} + 'entity.repo.latest_commit.hexsha': commit_model.hexsha + } response = client.post('/entities/models/%d/runexperiments' % model.pk, data=data) assert response.status_code == 302 assert response.url == '/entities/models/%d/versions/latest' % model.pk diff --git a/weblab/entities/views.py b/weblab/entities/views.py index 2bbe1a6cc..034323b4d 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -41,7 +41,7 @@ from core.visibility import ( Visibility, VisibilityMixin ) -from experiments.models import Experiment, PlannedExperiment +from experiments.models import Experiment, PlannedExperiment, ExperimentVersion from repocache.exceptions import RepoCacheMiss from repocache.models import CachedEntityVersion @@ -1065,12 +1065,9 @@ def post(self, request, *args, **kwargs): # in get context self.object was the entity being worked with # here we have to retrieve it this_entity = self.get_object() + this_version = this_entity.repo.latest_commit.hexsha - rerun = request.POST.get('rerun_expts') - exclude_existing = False - # look for 'None' string as this seems to be what test data passes for a NoneType - if not rerun or rerun == 'None': - exclude_existing = True + exclude_existing = 'rerun_expts' not in request.POST experiments_to_run = request.POST.getlist('model_protocol_list[]') for version in experiments_to_run: ident, sha = version.split(':') @@ -1081,8 +1078,7 @@ def post(self, request, *args, **kwargs): this_entity.entity_type + '_version': this_entity.repo.latest_commit.hexsha, } if exclude_existing: - existing = Experiment.objects.filter(**exper_kwargs) - if existing: + if Experiment.objects.filter(**exper_kwargs).exists(): continue PlannedExperiment.objects.get_or_create(**exper_kwargs) # return to entity page From 6f6c64bf7969dde17f75caf65ea903b50a0a2c9b Mon Sep 17 00:00:00 2001 From: Sarah Date: Fri, 31 May 2019 09:28:51 +0100 Subject: [PATCH 39/53] missed a line --- weblab/entities/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weblab/entities/views.py b/weblab/entities/views.py index 034323b4d..e71906584 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1075,7 +1075,7 @@ def post(self, request, *args, **kwargs): this_entity.other_type + '_id': ident, this_entity.other_type + '_version': sha, this_entity.entity_type + '_id': this_entity.id, - this_entity.entity_type + '_version': this_entity.repo.latest_commit.hexsha, + this_entity.entity_type + '_version': this_version, } if exclude_existing: if Experiment.objects.filter(**exper_kwargs).exists(): From 114f0b6b3c56866ce95b7e39fc675fb043768e84 Mon Sep 17 00:00:00 2001 From: Sarah Date: Fri, 31 May 2019 09:41:18 +0100 Subject: [PATCH 40/53] filter for experiments with or whithout versions --- weblab/entities/views.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/weblab/entities/views.py b/weblab/entities/views.py index e71906584..855d581cd 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1071,6 +1071,12 @@ def post(self, request, *args, **kwargs): experiments_to_run = request.POST.getlist('model_protocol_list[]') for version in experiments_to_run: ident, sha = version.split(':') + filter_kwargs = { + 'experiment__' + this_entity.other_type + '_id': ident, + 'experiment__' + this_entity.other_type + '_version': sha, + 'experiment__' + this_entity.entity_type + '_id': this_entity.id, + 'experiment__' + this_entity.entity_type + '_version': this_version, + } exper_kwargs = { this_entity.other_type + '_id': ident, this_entity.other_type + '_version': sha, @@ -1078,7 +1084,7 @@ def post(self, request, *args, **kwargs): this_entity.entity_type + '_version': this_version, } if exclude_existing: - if Experiment.objects.filter(**exper_kwargs).exists(): + if ExperimentVersion.objects.filter(**filter_kwargs).exists(): continue PlannedExperiment.objects.get_or_create(**exper_kwargs) # return to entity page From bdb41e16613136bcceb11cbf02687eea4cabea46 Mon Sep 17 00:00:00 2001 From: Sarah Date: Fri, 31 May 2019 09:55:12 +0100 Subject: [PATCH 41/53] add test for experiment no versions --- weblab/entities/tests/test_views.py | 41 +++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/weblab/entities/tests/test_views.py b/weblab/entities/tests/test_views.py index 92eed0611..89178817a 100644 --- a/weblab/entities/tests/test_views.py +++ b/weblab/entities/tests/test_views.py @@ -2440,3 +2440,44 @@ def test_view_run_experiment_none_checked(self, client, helpers, logged_in_user) # Test that no planned experiments have been added assert PlannedExperiment.objects.count() == 0 + def test_view_run_experiment_no_experiment_version(self, client, helpers, logged_in_user): + helpers.add_permission(logged_in_user, 'create_experiment', Experiment) + model = recipes.model.make(author=logged_in_user) + commit1 = helpers.add_version(model, visibility='public') + commit2 = helpers.add_version(model, visibility='public') + model.add_tag('v1', commit2.hexsha) + protocol = recipes.protocol.make(author=logged_in_user) + commit_protocol = helpers.add_version(protocol, visibility='public') + + recipes.experiment_version.make( + experiment__model=model, + experiment__model_version=commit1.hexsha, + experiment__protocol=protocol, + experiment__protocol_version=commit_protocol.hexsha) + + # Test context has correct information + response = client.get('/entities/protocols/%d/runexperiments' % protocol.pk) + assert response.status_code == 200 + assert response.context['object_list'] == [{'id': model.pk, + 'name': 'mymodel1', + 'versions': [{'commit': commit2, 'tags': ['v1'], 'latest': True}, + {'commit': commit1, 'tags': [], 'latest': False}]}, + ] + # Test post returns correct response + data = {'model_protocol_list[]': ['%d:%s' % (model.pk, commit1.hexsha), '%d:%s' % (model.pk, commit2.hexsha)], + 'entity.repo.latest_commit.hexsha': commit_protocol.hexsha, + } + response = client.post('/entities/protocols/%d/runexperiments' % protocol.pk, data=data) + assert response.status_code == 302 + assert response.url == '/entities/protocols/%d/versions/latest' % protocol.pk + + # Test that planned experiments have been added correctly + expected_model_versions = set([ + (model, commit2.hexsha), + ]) + assert PlannedExperiment.objects.count() == 1 + for planned_experiment in PlannedExperiment.objects.all(): + assert planned_experiment.protocol == protocol + assert planned_experiment.protocol_version == commit_protocol.hexsha + assert (planned_experiment.model, planned_experiment.model_version) in expected_model_versions + From e555f0aa4eb3e733fa4372c747c3292f8d3683e9 Mon Sep 17 00:00:00 2001 From: Sarah Date: Fri, 31 May 2019 09:55:47 +0100 Subject: [PATCH 42/53] took out if permission to create experiment --- weblab/templates/entities/entity_version.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/weblab/templates/entities/entity_version.html b/weblab/templates/entities/entity_version.html index bc8ff336b..c33bc8370 100644 --- a/weblab/templates/entities/entity_version.html +++ b/weblab/templates/entities/entity_version.html @@ -43,12 +43,11 @@

    Change visibility: {{ form.visibility }} help - {% if perms.create_experiment %} + Run experiments: Run experiments: - {% endif %} {% else %} Visibility: {{ visibility }} From 9874020fd1b809cbf8c6e6db239a0e69752b2612 Mon Sep 17 00:00:00 2001 From: Sarah Date: Fri, 31 May 2019 09:58:39 +0100 Subject: [PATCH 43/53] add newline at eof --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0bd223e76..9706a8215 100644 --- a/.gitignore +++ b/.gitignore @@ -115,4 +115,4 @@ weblab/data/ weblab/media/ #PyCharm files -weblab/.idea/ \ No newline at end of file +weblab/.idea/ From a3a4e6da4dc4eb22a7ba7c24ac52c3c16110d2e0 Mon Sep 17 00:00:00 2001 From: Jonathan Cooper Date: Sat, 1 Jun 2019 11:04:32 +0100 Subject: [PATCH 44/53] Creating expts & editing entities are independent permissions This is what I meant by my review comment; sorry I was unclear! --- weblab/templates/entities/entity_version.html | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/weblab/templates/entities/entity_version.html b/weblab/templates/entities/entity_version.html index c33bc8370..f59e1ef8f 100644 --- a/weblab/templates/entities/entity_version.html +++ b/weblab/templates/entities/entity_version.html @@ -43,16 +43,18 @@

    Change visibility: {{ form.visibility }} help - - Run experiments: - - Run experiments: {% else %} Visibility: {{ visibility }} help {% endif %} + {% if perms.create_experiment %} + Run experiments: + + Run experiments: + + {% endif %}

    - +

    + + Create new versions of existing experiments (if unchecked, existing combinations will be skipped) +

    - - + -

    -

    - {% csrf_token %} - + + {% csrf_token %} + -
    -

    -

    You may run this {{ type }} {{ preposition }} the following {{ other_type }}s.

    -

    Your {{ other_type }}s

    +

    You may run this {{ type }} {{ preposition }} the following {{ other_type }}s.

    + +

    Your {{ other_type }}s

    - {% for entity_object in object_list %} + {% for entity_object in object_list %} - {{ entity_object.id }} + {{ entity_object.name }}
    - {% endfor %} -

    From e616eaf166a8494885b90d69975e4516e8ace374 Mon Sep 17 00:00:00 2001 From: Jonathan Cooper Date: Sat, 1 Jun 2019 11:06:12 +0100 Subject: [PATCH 45/53] Funkier way of setting filter args --- weblab/entities/views.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/weblab/entities/views.py b/weblab/entities/views.py index 855d581cd..2c6544673 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1071,24 +1071,20 @@ def post(self, request, *args, **kwargs): experiments_to_run = request.POST.getlist('model_protocol_list[]') for version in experiments_to_run: ident, sha = version.split(':') - filter_kwargs = { - 'experiment__' + this_entity.other_type + '_id': ident, - 'experiment__' + this_entity.other_type + '_version': sha, - 'experiment__' + this_entity.entity_type + '_id': this_entity.id, - 'experiment__' + this_entity.entity_type + '_version': this_version, - } exper_kwargs = { this_entity.other_type + '_id': ident, this_entity.other_type + '_version': sha, this_entity.entity_type + '_id': this_entity.id, - this_entity.entity_type + '_version': this_version, + this_entity.entity_type + '_version': this_version, } if exclude_existing: + filter_kwargs = { + 'experiment__' + name: value + for (name, value) in exper_kwargs.items() + } if ExperimentVersion.objects.filter(**filter_kwargs).exists(): continue PlannedExperiment.objects.get_or_create(**exper_kwargs) # return to entity page return HttpResponseRedirect( reverse('entities:version', args=[kwargs['entity_type'], kwargs['pk'], 'latest'])) - - From 79334c2412d14194987e697399e24b07eb75c23c Mon Sep 17 00:00:00 2001 From: Jonathan Cooper Date: Sat, 1 Jun 2019 11:26:12 +0100 Subject: [PATCH 46/53] Correct experiment with no versions test --- weblab/entities/tests/test_views.py | 48 ++++------------------------- 1 file changed, 6 insertions(+), 42 deletions(-) diff --git a/weblab/entities/tests/test_views.py b/weblab/entities/tests/test_views.py index 89178817a..59d16a91f 100644 --- a/weblab/entities/tests/test_views.py +++ b/weblab/entities/tests/test_views.py @@ -2326,6 +2326,12 @@ def test_view_run_experiment_protocol_post_exclude_existing(self, client, helper experiment__model_version=commit1.hexsha, experiment__protocol=protocol, experiment__protocol_version=commit_protocol.hexsha) + # This experiment has no versions so should not be excluded + recipes.experiment.make( + model=model, + model_version=commit2.hexsha, + protocol=protocol, + protocol_version=commit_protocol.hexsha) # Test context has correct information response = client.get('/entities/protocols/%d/runexperiments' % protocol.pk) @@ -2439,45 +2445,3 @@ def test_view_run_experiment_none_checked(self, client, helpers, logged_in_user) # Test that no planned experiments have been added assert PlannedExperiment.objects.count() == 0 - - def test_view_run_experiment_no_experiment_version(self, client, helpers, logged_in_user): - helpers.add_permission(logged_in_user, 'create_experiment', Experiment) - model = recipes.model.make(author=logged_in_user) - commit1 = helpers.add_version(model, visibility='public') - commit2 = helpers.add_version(model, visibility='public') - model.add_tag('v1', commit2.hexsha) - protocol = recipes.protocol.make(author=logged_in_user) - commit_protocol = helpers.add_version(protocol, visibility='public') - - recipes.experiment_version.make( - experiment__model=model, - experiment__model_version=commit1.hexsha, - experiment__protocol=protocol, - experiment__protocol_version=commit_protocol.hexsha) - - # Test context has correct information - response = client.get('/entities/protocols/%d/runexperiments' % protocol.pk) - assert response.status_code == 200 - assert response.context['object_list'] == [{'id': model.pk, - 'name': 'mymodel1', - 'versions': [{'commit': commit2, 'tags': ['v1'], 'latest': True}, - {'commit': commit1, 'tags': [], 'latest': False}]}, - ] - # Test post returns correct response - data = {'model_protocol_list[]': ['%d:%s' % (model.pk, commit1.hexsha), '%d:%s' % (model.pk, commit2.hexsha)], - 'entity.repo.latest_commit.hexsha': commit_protocol.hexsha, - } - response = client.post('/entities/protocols/%d/runexperiments' % protocol.pk, data=data) - assert response.status_code == 302 - assert response.url == '/entities/protocols/%d/versions/latest' % protocol.pk - - # Test that planned experiments have been added correctly - expected_model_versions = set([ - (model, commit2.hexsha), - ]) - assert PlannedExperiment.objects.count() == 1 - for planned_experiment in PlannedExperiment.objects.all(): - assert planned_experiment.protocol == protocol - assert planned_experiment.protocol_version == commit_protocol.hexsha - assert (planned_experiment.model, planned_experiment.model_version) in expected_model_versions - From 5f501c77dfb9111bd233e10e36ce63585bcdde2d Mon Sep 17 00:00:00 2001 From: Jonathan Cooper Date: Sat, 1 Jun 2019 11:38:43 +0100 Subject: [PATCH 47/53] Associate run experiments view with an entity _version_ Sorry, I should have noticed this a while ago! --- weblab/entities/templatetags/entities.py | 6 +- weblab/entities/tests/test_views.py | 90 ++++++++++++------- weblab/entities/urls.py | 12 +-- weblab/entities/views.py | 6 +- weblab/templates/entities/entity_version.html | 2 +- 5 files changed, 72 insertions(+), 44 deletions(-) diff --git a/weblab/entities/templatetags/entities.py b/weblab/entities/templatetags/entities.py index d5cb1b6b1..76658fd09 100644 --- a/weblab/entities/templatetags/entities.py +++ b/weblab/entities/templatetags/entities.py @@ -192,5 +192,7 @@ def can_manage_entity(context, entity): @register.filter -def url_run_experiments(entity): - return reverse('entities:runexperiments', args=[entity.entity_type, entity.id]) +def url_run_experiments(entity, commit): + last_tag = _url_friendly_label(entity, commit) + args = [entity.entity_type, entity.id, last_tag] + return reverse('entities:runexperiments', args=args) diff --git a/weblab/entities/tests/test_views.py b/weblab/entities/tests/test_views.py index 59d16a91f..99bcae870 100644 --- a/weblab/entities/tests/test_views.py +++ b/weblab/entities/tests/test_views.py @@ -2061,12 +2061,14 @@ class TestEntityRunExperiment: def test_view_run_experiment_model(self, client, helpers, logged_in_user): helpers.add_permission(logged_in_user, 'create_experiment', Experiment) model = recipes.model.make(author=logged_in_user) + helpers.add_version(model, visibility='private') protocol = recipes.protocol.make(author=logged_in_user) commit1 = helpers.add_version(protocol, visibility='public') commit2 = helpers.add_version(protocol, visibility='public') protocol.add_tag('v1', commit2.hexsha) - response = client.get('/entities/models/%d/runexperiments' % model.pk) + response = client.get( + '/entities/models/%d/versions/%s/runexperiments' % (model.pk, 'latest')) assert response.status_code == 200 assert response.context['object_list'] == [{'id': protocol.pk, 'name': 'myprotocol1', @@ -2078,6 +2080,7 @@ def test_view_run_experiment_model(self, client, helpers, logged_in_user): def test_view_run_experiment_model_multiple_users(self, client, helpers, logged_in_user, other_user): helpers.add_permission(logged_in_user, 'create_experiment', Experiment) model = recipes.model.make(author=logged_in_user) + helpers.add_version(model, visibility='moderated') protocol = recipes.protocol.make(author=logged_in_user) commit1 = helpers.add_version(protocol, visibility='public') @@ -2088,7 +2091,9 @@ def test_view_run_experiment_model_multiple_users(self, client, helpers, logged_ other_commit1 = helpers.add_version(other_protocol, visibility='public') other_commit2 = helpers.add_version(other_protocol, visibility='public') other_protocol.add_tag('v1', other_commit2.hexsha) - response = client.get('/entities/models/%d/runexperiments' % model.pk) + + response = client.get( + '/entities/models/%d/versions/%s/runexperiments' % (model.pk, 'latest')) assert response.status_code == 200 assert response.context['object_list'] == [{'id': protocol.pk, 'name': 'myprotocol1', @@ -2113,7 +2118,8 @@ def test_view_run_experiment_model_post(self, client, helpers, logged_in_user): protocol.add_tag('v1', commit2.hexsha) # Test context has correct information - response = client.get('/entities/models/%d/runexperiments' % model.pk) + response = client.get( + '/entities/models/%d/versions/%s/runexperiments' % (model.pk, commit_model.hexsha)) assert response.status_code == 200 assert response.context['object_list'] == [{'id': protocol.pk, 'name': 'myprotocol1', @@ -2122,9 +2128,10 @@ def test_view_run_experiment_model_post(self, client, helpers, logged_in_user): ] # Test post returns correct response data = {'model_protocol_list[]': ['%d:%s' % (protocol.pk, commit2.hexsha)], - 'entity.repo.latest_commit.hexsha': commit_model.hexsha, 'rerun_expts': 'on'} - response = client.post('/entities/models/%d/runexperiments' % model.pk, data=data) + response = client.post( + '/entities/models/%d/versions/%s/runexperiments' % (model.pk, commit_model.hexsha), + data=data) assert response.status_code == 302 assert response.url == '/entities/models/%d/versions/latest' % model.pk @@ -2156,7 +2163,8 @@ def test_view_run_experiment_model_post_exclude_existing(self, client, helpers, experiment__protocol_version=commit1.hexsha) # Test context has correct information - response = client.get('/entities/models/%d/runexperiments' % model.pk) + response = client.get( + '/entities/models/%d/versions/%s/runexperiments' % (model.pk, commit_model.hexsha)) assert response.status_code == 200 assert response.context['object_list'] == [{'id': protocol.pk, 'name': 'myprotocol1', @@ -2165,10 +2173,11 @@ def test_view_run_experiment_model_post_exclude_existing(self, client, helpers, ] # Test post returns correct response data = {'model_protocol_list[]': ['%d:%s' % (protocol.pk, commit1.hexsha), - '%d:%s' % (protocol.pk, commit2.hexsha)], - 'entity.repo.latest_commit.hexsha': commit_model.hexsha + '%d:%s' % (protocol.pk, commit2.hexsha)], } - response = client.post('/entities/models/%d/runexperiments' % model.pk, data=data) + response = client.post( + '/entities/models/%d/versions/%s/runexperiments' % (model.pk, commit_model.hexsha), + data=data) assert response.status_code == 302 assert response.url == '/entities/models/%d/versions/latest' % model.pk @@ -2198,7 +2207,8 @@ def test_view_run_experiment_post_model_multiple_users(self, client, helpers, lo other_protocol.add_tag('v1', other_commit2.hexsha) # check context - response = client.get('/entities/models/%d/runexperiments' % model.pk) + response = client.get( + '/entities/models/%d/versions/%s/runexperiments' % (model.pk, commit_model.hexsha)) assert response.status_code == 200 assert response.context['object_list'] == [{'id': protocol.pk, 'name': 'myprotocol1', @@ -2212,11 +2222,12 @@ def test_view_run_experiment_post_model_multiple_users(self, client, helpers, lo ] # Test post returns correct response data = {'model_protocol_list[]': ['%d:%s' % (protocol.pk, commit2.hexsha), - '%d:%s' % (other_protocol.pk, other_commit1.hexsha), - '%d:%s' % (other_protocol.pk, other_commit2.hexsha)], - 'entity.repo.latest_commit.hexsha': commit_model.hexsha, + '%d:%s' % (other_protocol.pk, other_commit1.hexsha), + '%d:%s' % (other_protocol.pk, other_commit2.hexsha)], 'rerun_expts': 'on'} - response = client.post('/entities/models/%d/runexperiments' % model.pk, data=data) + response = client.post( + '/entities/models/%d/versions/%s/runexperiments' % (model.pk, commit_model.hexsha), + data=data) assert response.status_code == 302 assert response.url == '/entities/models/%d/versions/latest' % model.pk @@ -2240,7 +2251,10 @@ def test_view_run_experiment_protocol(self, client, helpers, logged_in_user): commit2 = helpers.add_version(model, visibility='public') model.add_tag('v1', commit2.hexsha) protocol = recipes.protocol.make(author=logged_in_user) - response = client.get('/entities/protocols/%d/runexperiments' % protocol.pk) + helpers.add_version(protocol, visibility='private') + + response = client.get( + '/entities/protocols/%d/versions/%s/runexperiments' % (protocol.pk, 'latest')) assert response.status_code == 200 assert response.context['object_list'] == [{'id': model.pk, 'name': 'mymodel1', @@ -2262,8 +2276,10 @@ def test_view_run_experiment_protocol_multiple_users(self, client, helpers, logg other_model.add_tag('v1', other_commit2.hexsha) protocol = recipes.protocol.make(author=logged_in_user) + helpers.add_version(protocol, visibility='private') - response = client.get('/entities/protocols/%d/runexperiments' % protocol.pk) + response = client.get( + '/entities/protocols/%d/versions/%s/runexperiments' % (protocol.pk, 'latest')) assert response.status_code == 200 assert response.context['object_list'] == [{'id': model.pk, 'name': 'mymodel1', @@ -2285,7 +2301,9 @@ def test_view_run_experiment_protocol_post(self, client, helpers, logged_in_user model.add_tag('v1', commit2.hexsha) protocol = recipes.protocol.make(author=logged_in_user) commit_protocol = helpers.add_version(protocol, visibility='public') - response = client.get('/entities/protocols/%d/runexperiments' % protocol.pk) + + response = client.get( + '/entities/protocols/%d/versions/%s/runexperiments' % (protocol.pk, commit_protocol.hexsha)) assert response.status_code == 200 assert response.context['object_list'] == [{'id': model.pk, 'name': 'mymodel1', @@ -2294,9 +2312,10 @@ def test_view_run_experiment_protocol_post(self, client, helpers, logged_in_user ] # Test post returns correct response data = {'model_protocol_list[]': ['%d:%s' % (model.pk, commit1.hexsha), '%d:%s' % (model.pk, commit2.hexsha)], - 'entity.repo.latest_commit.hexsha': commit_protocol.hexsha, 'rerun_expts': 'on'} - response = client.post('/entities/protocols/%d/runexperiments' % protocol.pk, data=data) + response = client.post( + '/entities/protocols/%d/versions/%s/runexperiments' % (protocol.pk, commit_protocol.hexsha), + data=data) assert response.status_code == 302 assert response.url == '/entities/protocols/%d/versions/latest' % protocol.pk @@ -2334,7 +2353,8 @@ def test_view_run_experiment_protocol_post_exclude_existing(self, client, helper protocol_version=commit_protocol.hexsha) # Test context has correct information - response = client.get('/entities/protocols/%d/runexperiments' % protocol.pk) + response = client.get( + '/entities/protocols/%d/versions/%s/runexperiments' % (protocol.pk, commit_protocol.hexsha)) assert response.status_code == 200 assert response.context['object_list'] == [{'id': model.pk, 'name': 'mymodel1', @@ -2343,9 +2363,10 @@ def test_view_run_experiment_protocol_post_exclude_existing(self, client, helper ] # Test post returns correct response data = {'model_protocol_list[]': ['%d:%s' % (model.pk, commit1.hexsha), '%d:%s' % (model.pk, commit2.hexsha)], - 'entity.repo.latest_commit.hexsha': commit_protocol.hexsha, } - response = client.post('/entities/protocols/%d/runexperiments' % protocol.pk, data=data) + response = client.post( + '/entities/protocols/%d/versions/%s/runexperiments' % (protocol.pk, commit_protocol.hexsha), + data=data) assert response.status_code == 302 assert response.url == '/entities/protocols/%d/versions/latest' % protocol.pk @@ -2373,7 +2394,8 @@ def test_view_run_experiment_post_protocol_multiple_users(self, client, helpers, other_commit2 = helpers.add_version(other_model, visibility='public') other_model.add_tag('v1', other_commit2.hexsha) - response = client.get('/entities/protocols/%d/runexperiments' % protocol.pk) + response = client.get( + '/entities/protocols/%d/versions/%s/runexperiments' % (protocol.pk, commit_protocol.hexsha)) assert response.status_code == 200 assert response.context['object_list'] == [{'id': model.pk, 'name': 'mymodel1', @@ -2389,9 +2411,10 @@ def test_view_run_experiment_post_protocol_multiple_users(self, client, helpers, data = {'model_protocol_list[]': ['%d:%s' % (model.pk, commit1.hexsha), '%d:%s' % (model.pk, commit2.hexsha), '%d:%s' % (other_model.pk, other_commit1.hexsha)], - 'entity.repo.latest_commit.hexsha': commit_protocol.hexsha, 'rerun_expts': 'on'} - response = client.post('/entities/protocols/%d/runexperiments' % protocol.pk, data=data) + response = client.post( + '/entities/protocols/%d/versions/%s/runexperiments' % (protocol.pk, commit_protocol.hexsha), + data=data) assert response.status_code == 302 assert response.url == '/entities/protocols/%d/versions/latest' % protocol.pk @@ -2418,7 +2441,8 @@ def test_view_run_experiment_none_checked(self, client, helpers, logged_in_user) protocol.add_tag('v1', commit2.hexsha) # Test context has correct information - response = client.get('/entities/models/%d/runexperiments' % model.pk) + response = client.get( + '/entities/models/%d/versions/%s/runexperiments' % (model.pk, commit_model.hexsha)) assert response.status_code == 200 assert response.context['object_list'] == [{'id': protocol.pk, 'name': 'myprotocol1', @@ -2427,19 +2451,21 @@ def test_view_run_experiment_none_checked(self, client, helpers, logged_in_user) ] # Test post returns correct response data = {'model_protocol_list[]': [], - 'entity.repo.latest_commit.hexsha': commit_model.hexsha, 'rerun_expts': 'on'} - response = client.post('/entities/models/%d/runexperiments' % model.pk, data=data) + response = client.post( + '/entities/models/%d/versions/%s/runexperiments' % (model.pk, commit_model.hexsha), + data=data) assert response.status_code == 302 assert response.url == '/entities/models/%d/versions/latest' % model.pk # Test that no planned experiments have been added assert PlannedExperiment.objects.count() == 0 - data = {'model_protocol_list[]': [], - 'entity.repo.latest_commit.hexsha': commit_model.hexsha - } - response = client.post('/entities/models/%d/runexperiments' % model.pk, data=data) + # Try again without re-running + data = {'model_protocol_list[]': []} + response = client.post( + '/entities/models/%d/versions/%s/runexperiments' % (model.pk, commit_model.hexsha), + data=data) assert response.status_code == 302 assert response.url == '/entities/models/%d/versions/latest' % model.pk diff --git a/weblab/entities/urls.py b/weblab/entities/urls.py index 210eefa5c..791916283 100644 --- a/weblab/entities/urls.py +++ b/weblab/entities/urls.py @@ -118,6 +118,12 @@ name='entity_archive', ), + url( + r'^%s/(?P\d+)/versions/%s/runexperiments$' % (_ENTITY_TYPE, _COMMIT), + views.EntityRunExperimentView.as_view(), + name='runexperiments', + ), + url( r'^(?P\d+)/upload-file$', views.FileUploadView.as_view(), @@ -135,10 +141,4 @@ views.EntityDiffView.as_view(), name='diff', ), - - url( - r'^%s/(?P\d+)/runexperiments$' % _ENTITY_TYPE, - views.EntityRunExperimentView.as_view(), - name='runexperiments', - ), ] diff --git a/weblab/entities/views.py b/weblab/entities/views.py index 2c6544673..6352639ba 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1016,7 +1016,8 @@ def get(self, request, *args, **kwargs): }) -class EntityRunExperimentView(PermissionRequiredMixin, LoginRequiredMixin, EntityTypeMixin, DetailView): +class EntityRunExperimentView(PermissionRequiredMixin, LoginRequiredMixin, + EntityTypeMixin, EntityVersionMixin, DetailView): """ A view allowing users to set up a batch-run of experiments involving a single entity. """ @@ -1026,7 +1027,6 @@ class EntityRunExperimentView(PermissionRequiredMixin, LoginRequiredMixin, Entit def get_context_data(self, **kwargs): entity = self.object - context = super().get_context_data(**kwargs) # preposition to use in sentence: You may run this entity on/under the following entities @@ -1065,7 +1065,7 @@ def post(self, request, *args, **kwargs): # in get context self.object was the entity being worked with # here we have to retrieve it this_entity = self.get_object() - this_version = this_entity.repo.latest_commit.hexsha + this_version = self.get_commit().hexsha exclude_existing = 'rerun_expts' not in request.POST experiments_to_run = request.POST.getlist('model_protocol_list[]') diff --git a/weblab/templates/entities/entity_version.html b/weblab/templates/entities/entity_version.html index f59e1ef8f..854eb88e5 100644 --- a/weblab/templates/entities/entity_version.html +++ b/weblab/templates/entities/entity_version.html @@ -50,7 +50,7 @@

    {% endif %} {% if perms.create_experiment %} Run experiments: - + Run experiments: From 24d783b5a56afbc9e606b5f78f3178516c1428c0 Mon Sep 17 00:00:00 2001 From: Jonathan Cooper Date: Sat, 1 Jun 2019 11:59:25 +0100 Subject: [PATCH 48/53] Fix templatetag test --- weblab/entities/tests/test_templatetags.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/weblab/entities/tests/test_templatetags.py b/weblab/entities/tests/test_templatetags.py index 568191368..dd6e3a8a1 100644 --- a/weblab/entities/tests/test_templatetags.py +++ b/weblab/entities/tests/test_templatetags.py @@ -128,9 +128,11 @@ def test_url_friendly_label(model_with_version, helpers): @pytest.mark.django_db def test_url_runexperiments(model_with_version, protocol_with_version): model = model_with_version - assert (entity_tags.url_run_experiments(model) == - '/entities/models/%d/runexperiments' % model.pk) + model_commit = model.repo.latest_commit + assert (entity_tags.url_run_experiments(model, model_commit) == + '/entities/models/%d/versions/%s/runexperiments' % (model.pk, model_commit.hexsha)) protocol = protocol_with_version - assert (entity_tags.url_run_experiments(protocol) == - '/entities/protocols/%d/runexperiments' % protocol.pk) + protocol_commit = protocol.repo.latest_commit + assert (entity_tags.url_run_experiments(protocol, protocol_commit) == + '/entities/protocols/%d/versions/%s/runexperiments' % (protocol.pk, protocol_commit.hexsha)) From 20d73fb3c1321438c0a9d4540cd5f5ceca550602 Mon Sep 17 00:00:00 2001 From: Sarah Date: Thu, 6 Jun 2019 10:38:51 +0100 Subject: [PATCH 49/53] pick relevant commits that went into 182-fitting branch --- weblab/templates/entities/entity_version.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/weblab/templates/entities/entity_version.html b/weblab/templates/entities/entity_version.html index 854eb88e5..4a832d834 100644 --- a/weblab/templates/entities/entity_version.html +++ b/weblab/templates/entities/entity_version.html @@ -39,7 +39,7 @@

    {% if permission %} Add tag. -
    + Change visibility: {{ form.visibility }} help @@ -48,9 +48,9 @@

    Visibility: {{ visibility }} help {% endif %} - {% if perms.create_experiment %} + {% if perms.experiments.create_experiment %} Run experiments: - + Run experiments: From 955c62037c263c8880e6980f2bf98255aa85c7ff Mon Sep 17 00:00:00 2001 From: Sarah Date: Thu, 6 Jun 2019 12:25:06 +0100 Subject: [PATCH 50/53] Force text to be inline rather than separate lines --- .../templates/entities/entity_runexperiments.html | 14 ++++++-------- .../templates/entities/includes/version_name.html | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/weblab/templates/entities/entity_runexperiments.html b/weblab/templates/entities/entity_runexperiments.html index dbca6064e..4832c59ec 100644 --- a/weblab/templates/entities/entity_runexperiments.html +++ b/weblab/templates/entities/entity_runexperiments.html @@ -52,12 +52,11 @@

    Your {{ other_type }}s

    by {{ entity_version.commit.author }}
    - created + created {% with entity_version.commit.filenames|length as numfiles %} - containing {{ numfiles }} file{{ numfiles|pluralize }} + containing {{ numfiles }} file{{ numfiles|pluralize }} {% endwith %} - -
    +
    {{ entity_version.commit.message|linebreaksbr }} @@ -96,12 +95,11 @@

    Other {{ other_type }}s

    by {{ entity_version.commit.author }}
    - created + created {% with entity_version.commit.filenames|length as numfiles %} - containing {{ numfiles }} file{{ numfiles|pluralize }} + containing {{ numfiles }} file{{ numfiles|pluralize }} {% endwith %} - -
    +
    {{ entity_version.commit.message|linebreaksbr }} diff --git a/weblab/templates/entities/includes/version_name.html b/weblab/templates/entities/includes/version_name.html index bef138138..6533c5c71 100644 --- a/weblab/templates/entities/includes/version_name.html +++ b/weblab/templates/entities/includes/version_name.html @@ -3,6 +3,6 @@ {% for tag in tags %} {{ tag }}{% if not forloop.last %},{% endif %} {% endfor %} -{% if tags %}({% endif %}{% spaceless %} +{% if tags %}({% endif %}{% spaceless %} {{ version.hexsha|truncatechars:11 }} {% endspaceless %}{% if tags %}){% endif %} From d93574c0662b5f4986b9ba7a7cb2b8fc9ceff36c Mon Sep 17 00:00:00 2001 From: Jonathan Cooper Date: Tue, 11 Jun 2019 10:58:13 +0100 Subject: [PATCH 51/53] Shrink display further --- .../templates/entities/entity_runexperiments.html | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/weblab/templates/entities/entity_runexperiments.html b/weblab/templates/entities/entity_runexperiments.html index 4832c59ec..d81e7bb26 100644 --- a/weblab/templates/entities/entity_runexperiments.html +++ b/weblab/templates/entities/entity_runexperiments.html @@ -50,16 +50,11 @@

    Your {{ other_type }}s

    {% include "./includes/version_name.html" with tags=entity_version.tags version=entity_version.commit only %}
    - by {{ entity_version.commit.author }}
    + by {{ entity_version.commit.author }} + created
    - created - {% with entity_version.commit.filenames|length as numfiles %} - containing {{ numfiles }} file{{ numfiles|pluralize }} - {% endwith %} -
    - - {{ entity_version.commit.message|linebreaksbr }} - + {{ entity_version.commit.message|linebreaksbr }} +

    {% endfor %} From 8fd191b67d0f680a0170ce9aea6d6d8ad1115527 Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 11 Jun 2019 11:44:55 +0100 Subject: [PATCH 52/53] add tests for run experiment view of not latest version of an entity --- weblab/entities/tests/test_views.py | 68 +++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/weblab/entities/tests/test_views.py b/weblab/entities/tests/test_views.py index e6e979fbc..4af567e2d 100644 --- a/weblab/entities/tests/test_views.py +++ b/weblab/entities/tests/test_views.py @@ -2244,6 +2244,40 @@ def test_view_run_experiment_post_model_multiple_users(self, client, helpers, lo assert planned_experiment.model_version == commit_model.hexsha assert (planned_experiment.protocol, planned_experiment.protocol_version) in expected_proto_versions + def test_view_run_experiment_model_not_latest(self, client, helpers, logged_in_user): + helpers.add_permission(logged_in_user, 'create_experiment', Experiment) + model = recipes.model.make(author=logged_in_user) + helpers.add_version(model, visibility='private') + model_commit1 = helpers.add_version(model, visibility='public') + model.add_tag('model_v1', model_commit1.hexsha) + model_commit2 = helpers.add_version(model, visibility='public') + protocol = recipes.protocol.make(author=logged_in_user) + commit1 = helpers.add_version(protocol, visibility='public') + commit2 = helpers.add_version(protocol, visibility='public') + protocol.add_tag('v1', commit2.hexsha) + + # display page using tag + response = client.get( + '/entities/models/%d/versions/%s/runexperiments' % (model.pk, 'model_v1')) + assert response.status_code == 200 + assert response.context['object_list'] == [{'id': protocol.pk, + 'name': 'myprotocol1', + 'versions': [{'commit': commit2, 'tags': ['v1'], 'latest': True}, + {'commit': commit1, 'tags': [], 'latest': False}]}, + ] + assert response.context['preposition'] == 'under' + + #display page using sha + response = client.get( + '/entities/models/%d/versions/%s/runexperiments' % (model.pk, model_commit2.hexsha)) + assert response.status_code == 200 + assert response.context['object_list'] == [{'id': protocol.pk, + 'name': 'myprotocol1', + 'versions': [{'commit': commit2, 'tags': ['v1'], 'latest': True}, + {'commit': commit1, 'tags': [], 'latest': False}]}, + ] + assert response.context['preposition'] == 'under' + # repeat tests with protocol as the calling entity def test_view_run_experiment_protocol(self, client, helpers, logged_in_user): helpers.add_permission(logged_in_user, 'create_experiment', Experiment) @@ -2472,3 +2506,37 @@ def test_view_run_experiment_none_checked(self, client, helpers, logged_in_user) # Test that no planned experiments have been added assert PlannedExperiment.objects.count() == 0 + + def test_view_run_experiment_protocol_not_latest(self, client, helpers, logged_in_user): + helpers.add_permission(logged_in_user, 'create_experiment', Experiment) + model = recipes.model.make(author=logged_in_user) + commit1 = helpers.add_version(model, visibility='public') + commit2 = helpers.add_version(model, visibility='public') + model.add_tag('v1', commit2.hexsha) + protocol = recipes.protocol.make(author=logged_in_user) + proto_commit1 = helpers.add_version(protocol, visibility='public') + proto_commit2 = helpers.add_version(protocol, visibility='public') + protocol.add_tag('p1', proto_commit1.hexsha) + + # display using tag + response = client.get( + '/entities/protocols/%d/versions/%s/runexperiments' % (protocol.pk, 'p1')) + assert response.status_code == 200 + assert response.context['object_list'] == [{'id': model.pk, + 'name': 'mymodel1', + 'versions': [{'commit': commit2, 'tags': ['v1'], 'latest': True}, + {'commit': commit1, 'tags': [], 'latest': False}]}, + ] + assert response.context['preposition'] == 'on' + + # display using sha + response = client.get( + '/entities/protocols/%d/versions/%s/runexperiments' % (protocol.pk, proto_commit2.hexsha)) + assert response.status_code == 200 + assert response.context['object_list'] == [{'id': model.pk, + 'name': 'mymodel1', + 'versions': [{'commit': commit2, 'tags': ['v1'], 'latest': True}, + {'commit': commit1, 'tags': [], 'latest': False}]}, + ] + assert response.context['preposition'] == 'on' + From a4dbf1c7074eeb14b1db059cdbc7754aabc2a99d Mon Sep 17 00:00:00 2001 From: Sarah Date: Tue, 11 Jun 2019 15:08:25 +0100 Subject: [PATCH 53/53] Test that post runxperiments also works with not latest version which was worth it as I discovered I always redirected back to latest version even when using another - this is now fixed and tested --- weblab/entities/tests/test_views.py | 65 +++++++++++++++++++---------- weblab/entities/views.py | 7 +++- 2 files changed, 48 insertions(+), 24 deletions(-) diff --git a/weblab/entities/tests/test_views.py b/weblab/entities/tests/test_views.py index 4af567e2d..793faed7b 100644 --- a/weblab/entities/tests/test_views.py +++ b/weblab/entities/tests/test_views.py @@ -2251,6 +2251,7 @@ def test_view_run_experiment_model_not_latest(self, client, helpers, logged_in_u model_commit1 = helpers.add_version(model, visibility='public') model.add_tag('model_v1', model_commit1.hexsha) model_commit2 = helpers.add_version(model, visibility='public') + model.add_tag('model_v2', model_commit2.hexsha) protocol = recipes.protocol.make(author=logged_in_user) commit1 = helpers.add_version(protocol, visibility='public') commit2 = helpers.add_version(protocol, visibility='public') @@ -2267,16 +2268,26 @@ def test_view_run_experiment_model_not_latest(self, client, helpers, logged_in_u ] assert response.context['preposition'] == 'under' - #display page using sha - response = client.get( - '/entities/models/%d/versions/%s/runexperiments' % (model.pk, model_commit2.hexsha)) - assert response.status_code == 200 - assert response.context['object_list'] == [{'id': protocol.pk, - 'name': 'myprotocol1', - 'versions': [{'commit': commit2, 'tags': ['v1'], 'latest': True}, - {'commit': commit1, 'tags': [], 'latest': False}]}, - ] - assert response.context['preposition'] == 'under' + # Test post returns correct response + data = {'model_protocol_list[]': ['%d:%s' % (protocol.pk, commit2.hexsha), + '%d:%s' % (protocol.pk, commit1.hexsha)], + 'rerun_expts': 'on'} + response = client.post( + '/entities/models/%d/versions/%s/runexperiments' % (model.pk, 'model_v1'), + data=data) + assert response.status_code == 302 + assert response.url == '/entities/models/%d/versions/model_v1' % model.pk + + # Test that planned experiments have been added correctly + expected_proto_versions = set([ + (protocol, commit2.hexsha), + (protocol, commit1.hexsha), + ]) + assert PlannedExperiment.objects.count() == 2 + for planned_experiment in PlannedExperiment.objects.all(): + assert planned_experiment.model == model + assert planned_experiment.model_version == model_commit1.hexsha + assert (planned_experiment.protocol, planned_experiment.protocol_version) in expected_proto_versions # repeat tests with protocol as the calling entity def test_view_run_experiment_protocol(self, client, helpers, logged_in_user): @@ -2517,21 +2528,11 @@ def test_view_run_experiment_protocol_not_latest(self, client, helpers, logged_i proto_commit1 = helpers.add_version(protocol, visibility='public') proto_commit2 = helpers.add_version(protocol, visibility='public') protocol.add_tag('p1', proto_commit1.hexsha) - - # display using tag - response = client.get( - '/entities/protocols/%d/versions/%s/runexperiments' % (protocol.pk, 'p1')) - assert response.status_code == 200 - assert response.context['object_list'] == [{'id': model.pk, - 'name': 'mymodel1', - 'versions': [{'commit': commit2, 'tags': ['v1'], 'latest': True}, - {'commit': commit1, 'tags': [], 'latest': False}]}, - ] - assert response.context['preposition'] == 'on' + protocol.add_tag('p2', proto_commit2.hexsha) # display using sha response = client.get( - '/entities/protocols/%d/versions/%s/runexperiments' % (protocol.pk, proto_commit2.hexsha)) + '/entities/protocols/%d/versions/%s/runexperiments' % (protocol.pk, proto_commit1.hexsha)) assert response.status_code == 200 assert response.context['object_list'] == [{'id': model.pk, 'name': 'mymodel1', @@ -2540,3 +2541,23 @@ def test_view_run_experiment_protocol_not_latest(self, client, helpers, logged_i ] assert response.context['preposition'] == 'on' + # Test post returns correct response + data = {'model_protocol_list[]': ['%d:%s' % (model.pk, commit1.hexsha), '%d:%s' % (model.pk, commit2.hexsha)], + 'rerun_expts': 'on'} + response = client.post( + '/entities/protocols/%d/versions/%s/runexperiments' % (protocol.pk, proto_commit1.hexsha), + data=data) + assert response.status_code == 302 + assert response.url == '/entities/protocols/%d/versions/%s' % (protocol.pk, proto_commit1.hexsha) + + # Test that planned experiments have been added correctly + expected_model_versions = set([ + (model, commit2.hexsha), + (model, commit1.hexsha) + ]) + assert PlannedExperiment.objects.count() == 2 + for planned_experiment in PlannedExperiment.objects.all(): + assert planned_experiment.protocol == protocol + assert planned_experiment.protocol_version == proto_commit1.hexsha + assert (planned_experiment.model, planned_experiment.model_version) in expected_model_versions + diff --git a/weblab/entities/views.py b/weblab/entities/views.py index 821dd2b9a..c665ab96d 100644 --- a/weblab/entities/views.py +++ b/weblab/entities/views.py @@ -1068,7 +1068,7 @@ def post(self, request, *args, **kwargs): # here we have to retrieve it this_entity = self.get_object() this_version = self.get_commit().hexsha - + is_latest = (this_version == this_entity.repocache.latest_version.sha) exclude_existing = 'rerun_expts' not in request.POST experiments_to_run = request.POST.getlist('model_protocol_list[]') for version in experiments_to_run: @@ -1088,5 +1088,8 @@ def post(self, request, *args, **kwargs): continue PlannedExperiment.objects.get_or_create(**exper_kwargs) # return to entity page + version_to_use = 'latest' + if not is_latest: + version_to_use = kwargs['sha'] return HttpResponseRedirect( - reverse('entities:version', args=[kwargs['entity_type'], kwargs['pk'], 'latest'])) + reverse('entities:version', args=[kwargs['entity_type'], kwargs['pk'], version_to_use]))