From 434aa056a250c81d74d32c92e09b8fe6b7fce0e2 Mon Sep 17 00:00:00 2001 From: guerler Date: Mon, 2 Mar 2015 18:12:34 -0500 Subject: [PATCH 01/12] Parameters: Cover additional case for multiple hdas --- lib/galaxy/tools/parameters/basic.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/galaxy/tools/parameters/basic.py b/lib/galaxy/tools/parameters/basic.py index 95c72280a5f..55094a57808 100644 --- a/lib/galaxy/tools/parameters/basic.py +++ b/lib/galaxy/tools/parameters/basic.py @@ -2000,6 +2000,8 @@ class DataToolParameter( BaseDataToolParameter ): rval = trans.sa_session.query( trans.app.model.HistoryDatasetCollectionAssociation ).get( decoded_id ) else: raise ValueError("Unknown input source %s passed to job submission API." % single_value['src']) + elif isinstance( single_value, trans.app.model.HistoryDatasetAssociation ): + rval.append( single_value ) else: rval.append( trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( single_value ) ) elif isinstance( value, trans.app.model.HistoryDatasetAssociation ): From 0d62ee6960f8a8a84bc306ea9f1dd2d77d7726e9 Mon Sep 17 00:00:00 2001 From: guerler Date: Mon, 2 Mar 2015 18:25:46 -0500 Subject: [PATCH 02/12] Parameters: Fix collection selection for multiple dataset input field --- client/galaxy/scripts/mvc/tools/tools-select-content.js | 2 +- lib/galaxy/tools/__init__.py | 5 +++++ lib/galaxy/tools/parameters/basic.py | 2 ++ static/scripts/mvc/tools/tools-select-content.js | 2 +- static/scripts/packed/mvc/tools/tools-select-content.js | 2 +- 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/client/galaxy/scripts/mvc/tools/tools-select-content.js b/client/galaxy/scripts/mvc/tools/tools-select-content.js index 1a682b00578..b3e6ca20d69 100644 --- a/client/galaxy/scripts/mvc/tools/tools-select-content.js +++ b/client/galaxy/scripts/mvc/tools/tools-select-content.js @@ -217,7 +217,7 @@ var View = Backbone.View.extend({ } // identify suitable select field - if (new_value && new_value.values.length > 0 && new_value.values[0].src == 'hcda') { + if (new_value && new_value.values.length > 0 && new_value.values[0].src == 'hdca') { this.current = 'collection'; this.select_collection.value(list[0]); } else { diff --git a/lib/galaxy/tools/__init__.py b/lib/galaxy/tools/__init__.py index 4492688dac1..c2eecdf8d0b 100755 --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -2316,6 +2316,11 @@ class Tool( object, Dictifiable ): 'id' : trans.security.encode_id(v.id), 'src' : 'hda' } + elif isinstance(v, trans.app.model.HistoryDatasetCollectionAssociation): + return { + 'id' : trans.security.encode_id(v.id), + 'src' : 'hdca' + } elif isinstance(v, bool): if v is True: return 'true' diff --git a/lib/galaxy/tools/parameters/basic.py b/lib/galaxy/tools/parameters/basic.py index 55094a57808..b3ecac09217 100644 --- a/lib/galaxy/tools/parameters/basic.py +++ b/lib/galaxy/tools/parameters/basic.py @@ -2018,6 +2018,8 @@ class DataToolParameter( BaseDataToolParameter ): encoded_id = str( value )[ len( "__collection_reduce__|" ): ] decoded_id = trans.app.security.decode_id( encoded_id ) rval = trans.sa_session.query( trans.app.model.HistoryDatasetCollectionAssociation ).get( decoded_id ) + elif isinstance( value, trans.app.model.HistoryDatasetCollectionAssociation ): + rval = value else: rval = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( value ) if isinstance( rval, list ): diff --git a/static/scripts/mvc/tools/tools-select-content.js b/static/scripts/mvc/tools/tools-select-content.js index 1a682b00578..b3e6ca20d69 100644 --- a/static/scripts/mvc/tools/tools-select-content.js +++ b/static/scripts/mvc/tools/tools-select-content.js @@ -217,7 +217,7 @@ var View = Backbone.View.extend({ } // identify suitable select field - if (new_value && new_value.values.length > 0 && new_value.values[0].src == 'hcda') { + if (new_value && new_value.values.length > 0 && new_value.values[0].src == 'hdca') { this.current = 'collection'; this.select_collection.value(list[0]); } else { diff --git a/static/scripts/packed/mvc/tools/tools-select-content.js b/static/scripts/packed/mvc/tools/tools-select-content.js index b4d33cc72a4..d8e34cf1cd4 100644 --- a/static/scripts/packed/mvc/tools/tools-select-content.js +++ b/static/scripts/packed/mvc/tools/tools-select-content.js @@ -1 +1 @@ -define(["utils/utils","mvc/ui/ui-misc","mvc/ui/ui-tabs","mvc/tools/tools-template"],function(c,e,b,a){var d=Backbone.View.extend({initialize:function(g,p){this.app=g;this.options=p;var o=this;this.setElement('
');this.list={};var m=[];if(p.type=="data_collection"){this.mode="collection"}else{if(p.multiple){this.mode="multiple"}else{this.mode="single"}}this.current=this.mode;this.list={};var k=c.textify(p.extensions);var j="No dataset available.";if(k){j="No "+k+" dataset available."}var l="No dataset list available.";if(k){l="No "+k+" dataset collection available."}if(this.mode=="single"){m.push({icon:"fa-file-o",value:"single",tooltip:"Single dataset"});this.select_single=new e.Select.View({optional:p.optional,error_text:j,onchange:function(){o.trigger("change")}});this.list.single={field:this.select_single,type:"hda"}}if(this.mode=="single"||this.mode=="multiple"){m.push({icon:"fa-files-o",value:"multiple",tooltip:"Multiple datasets"});this.select_multiple=new e.Select.View({multiple:true,searchable:false,error_text:j,onchange:function(){o.trigger("change")}});this.list.multiple={field:this.select_multiple,type:"hda"}}if(this.mode=="single"||this.mode=="multiple"||this.mode=="collection"){m.push({icon:"fa-folder-o",value:"collection",tooltip:"Dataset collection"});this.select_collection=new e.Select.View({error_text:l,optional:p.optional,onchange:function(){o.trigger("change")}});this.list.collection={field:this.select_collection,type:"hdca"}}this.button_type=new e.RadioButton.View({value:this.current,data:m,onchange:function(i){o.current=i;o.refresh();o.trigger("change")}});this.$batch=$(a.batchMode());var f=_.size(this.list);var n=0;if(f>1){this.$el.append(this.button_type.$el);n=Math.max(0,_.size(this.list)*35)+"px"}for(var h in this.list){this.$el.append(this.list[h].field.$el.css({"margin-left":n}))}this.$el.append(this.$batch.css({"margin-left":n}));this.update(p.data);if(this.options.value!==undefined){this.value(this.options.value)}this.refresh();this.on("change",function(){if(p.onchange){p.onchange(o.value())}})},wait:function(){for(var f in this.list){this.list[f].field.wait()}},unwait:function(){for(var f in this.list){this.list[f].field.unwait()}},update:function(g){function f(l,h){if(l){var m=[];for(var j in h){var k=h[j];m.push({label:k.hid+": "+k.name,value:k.id})}l.update(m)}}f(this.select_single,g.hda);f(this.select_multiple,g.hda);f(this.select_collection,g.hdca);this.app.content.add(g)},value:function(j){if(j!==undefined){if(j&&j.values){try{var m=[];for(var h in j.values){m.push(j.values[h].id)}if(j&&j.values.length>0&&j.values[0].src=="hcda"){this.current="collection";this.select_collection.value(m[0])}else{if(this.mode=="multiple"){this.current="multiple";this.select_multiple.value(m)}else{this.current="single";this.select_single.value(m[0])}}}catch(l){console.debug("tools-select-content::value() - Skipped.")}}else{for(var h in this.list){this.list[h].field.value(null)}}}this.refresh();var k=this._select().value();if(k===null){return null}if(!(k instanceof Array)){k=[k]}if(k.length===0){return null}var f={batch:this._batch(),values:[]};for(var h in k){var g=this.app.content.get({id:k[h],src:this.list[this.current].type});if(g){f.values.push(g)}else{return null}}f.values.sort(function(n,i){return n.hid-i.hid});return f},refresh:function(){this.button_type.value(this.current);for(var g in this.list){var f=this.list[g].field.$el;if(this.current==g){f.show()}else{f.hide()}}if(this._batch()){this.$batch.show()}else{this.$batch.hide()}},_select:function(){return this.list[this.current].field},_batch:function(){if(this.current=="collection"){var f=this.app.content.get({id:this._select().value(),src:"hdca"});if(f&&f.map_over_type){return true}}if(this.current!="single"){if(this.mode=="single"){return true}}return false}});return{View:d}}); \ No newline at end of file +define(["utils/utils","mvc/ui/ui-misc","mvc/ui/ui-tabs","mvc/tools/tools-template"],function(c,e,b,a){var d=Backbone.View.extend({initialize:function(g,p){this.app=g;this.options=p;var o=this;this.setElement('
');this.list={};var m=[];if(p.type=="data_collection"){this.mode="collection"}else{if(p.multiple){this.mode="multiple"}else{this.mode="single"}}this.current=this.mode;this.list={};var k=c.textify(p.extensions);var j="No dataset available.";if(k){j="No "+k+" dataset available."}var l="No dataset list available.";if(k){l="No "+k+" dataset collection available."}if(this.mode=="single"){m.push({icon:"fa-file-o",value:"single",tooltip:"Single dataset"});this.select_single=new e.Select.View({optional:p.optional,error_text:j,onchange:function(){o.trigger("change")}});this.list.single={field:this.select_single,type:"hda"}}if(this.mode=="single"||this.mode=="multiple"){m.push({icon:"fa-files-o",value:"multiple",tooltip:"Multiple datasets"});this.select_multiple=new e.Select.View({multiple:true,searchable:false,error_text:j,onchange:function(){o.trigger("change")}});this.list.multiple={field:this.select_multiple,type:"hda"}}if(this.mode=="single"||this.mode=="multiple"||this.mode=="collection"){m.push({icon:"fa-folder-o",value:"collection",tooltip:"Dataset collection"});this.select_collection=new e.Select.View({error_text:l,optional:p.optional,onchange:function(){o.trigger("change")}});this.list.collection={field:this.select_collection,type:"hdca"}}this.button_type=new e.RadioButton.View({value:this.current,data:m,onchange:function(i){o.current=i;o.refresh();o.trigger("change")}});this.$batch=$(a.batchMode());var f=_.size(this.list);var n=0;if(f>1){this.$el.append(this.button_type.$el);n=Math.max(0,_.size(this.list)*35)+"px"}for(var h in this.list){this.$el.append(this.list[h].field.$el.css({"margin-left":n}))}this.$el.append(this.$batch.css({"margin-left":n}));this.update(p.data);if(this.options.value!==undefined){this.value(this.options.value)}this.refresh();this.on("change",function(){if(p.onchange){p.onchange(o.value())}})},wait:function(){for(var f in this.list){this.list[f].field.wait()}},unwait:function(){for(var f in this.list){this.list[f].field.unwait()}},update:function(g){function f(l,h){if(l){var m=[];for(var j in h){var k=h[j];m.push({label:k.hid+": "+k.name,value:k.id})}l.update(m)}}f(this.select_single,g.hda);f(this.select_multiple,g.hda);f(this.select_collection,g.hdca);this.app.content.add(g)},value:function(j){if(j!==undefined){if(j&&j.values){try{var m=[];for(var h in j.values){m.push(j.values[h].id)}if(j&&j.values.length>0&&j.values[0].src=="hdca"){this.current="collection";this.select_collection.value(m[0])}else{if(this.mode=="multiple"){this.current="multiple";this.select_multiple.value(m)}else{this.current="single";this.select_single.value(m[0])}}}catch(l){console.debug("tools-select-content::value() - Skipped.")}}else{for(var h in this.list){this.list[h].field.value(null)}}}this.refresh();var k=this._select().value();if(k===null){return null}if(!(k instanceof Array)){k=[k]}if(k.length===0){return null}var f={batch:this._batch(),values:[]};for(var h in k){var g=this.app.content.get({id:k[h],src:this.list[this.current].type});if(g){f.values.push(g)}else{return null}}f.values.sort(function(n,i){return n.hid-i.hid});return f},refresh:function(){this.button_type.value(this.current);for(var g in this.list){var f=this.list[g].field.$el;if(this.current==g){f.show()}else{f.hide()}}if(this._batch()){this.$batch.show()}else{this.$batch.hide()}},_select:function(){return this.list[this.current].field},_batch:function(){if(this.current=="collection"){var f=this.app.content.get({id:this._select().value(),src:"hdca"});if(f&&f.map_over_type){return true}}if(this.current!="single"){if(this.mode=="single"){return true}}return false}});return{View:d}}); \ No newline at end of file From b1f365420872fc71f262dc57fd39c08b1e3f92a7 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Mon, 2 Mar 2015 21:32:30 -0500 Subject: [PATCH 03/12] Tool data API testing fixes. - Add files I didn't commit previously in test/functional/tool-data/. - Comment out test for tool data table deletion since Dan fixed the problem of regular users running data managers through the API (https://github.com/galaxyproject/galaxy/commit/48f77dc742acf01ddbafafcc4634e69378f1f020) that I previously exploited to write the test. --- test/api/test_tool_data.py | 56 +++++++++---------- test/functional/tool-data/data1/entry.txt | 1 + .../tool-data/data1/entry.txt.index | 1 + test/functional/tool-data/data2/entry.txt | 1 + .../tool-data/data2/entry.txt.index | 1 + 5 files changed, 32 insertions(+), 28 deletions(-) create mode 100644 test/functional/tool-data/data1/entry.txt create mode 100644 test/functional/tool-data/data1/entry.txt.index create mode 100644 test/functional/tool-data/data2/entry.txt create mode 100644 test/functional/tool-data/data2/entry.txt.index diff --git a/test/api/test_tool_data.py b/test/api/test_tool_data.py index 866c89e0fb1..d12d3222241 100644 --- a/test/api/test_tool_data.py +++ b/test/api/test_tool_data.py @@ -1,11 +1,6 @@ """ Tests for the tool data API. """ -import json - from base import api -from .helpers import DatasetPopulator - -from requests import delete import operator @@ -40,7 +35,7 @@ class ToolDataApiTestCase( api.ApiTestCase ): field = show_field_response.json() self._assert_has_keys( field, "files", "name", "fields", "fingerprint", "base_dir" ) files = field[ "files" ] - assert len( files ) == 2 + assert len( files ) == 2, "Length of files [%s] was not 2." % files def test_download_field_file(self): show_field_response = self._get( "tool_data/testalpha/fields/data1/files/entry.txt", admin=True ) @@ -48,27 +43,32 @@ class ToolDataApiTestCase( api.ApiTestCase ): content = show_field_response.content assert content == "This is data 1.", content - def test_delete_entry(self): - show_response = self._get( "tool_data/testbeta", admin=True ) - original_count = len(show_response.json()["fields"]) + # Following test case rendered invalid by the fix in + # https://github.com/galaxyproject/galaxy/commit/48f77dc742acf01ddbafafcc4634e69378f1f020#diff-bfb557a99c1f7d646d4968d8d680b885R154. + # TODO: Restore the test case when test framework allows actions from + # admin users. - dataset_populator = DatasetPopulator( self.galaxy_interactor ) - history_id = dataset_populator.new_history() - payload = dataset_populator.run_tool_payload( - tool_id="data_manager", - inputs={"ignored_value": "moo"}, - history_id=history_id, - ) - create_response = self._post( "tools", data=payload ) - self._assert_status_code_is( create_response, 200 ) - dataset_populator.wait_for_history( history_id, assert_ok=True ) - show_response = self._get( "tool_data/testbeta", admin=True ) - updated_fields = show_response.json()["fields"] - assert len(updated_fields) == original_count + 1 - field0 = updated_fields[0] - url = self._api_url( "tool_data/testbeta?key=%s" % self.galaxy_interactor.master_api_key ) - delete( url, data=json.dumps({"values": "\t".join(field0)}) ) + # def test_delete_entry(self): + # show_response = self._get( "tool_data/testbeta", admin=True ) + # original_count = len(show_response.json()["fields"]) - show_response = self._get( "tool_data/testbeta", admin=True ) - updated_fields = show_response.json()["fields"] - assert len(updated_fields) == original_count + # dataset_populator = DatasetPopulator( self.galaxy_interactor ) + # history_id = dataset_populator.new_history() + # payload = dataset_populator.run_tool_payload( + # tool_id="data_manager", + # inputs={"ignored_value": "moo"}, + # history_id=history_id, + # ) + # create_response = self._post( "tools", data=payload ) + # self._assert_status_code_is( create_response, 200 ) + # dataset_populator.wait_for_history( history_id, assert_ok=True ) + # show_response = self._get( "tool_data/testbeta", admin=True ) + # updated_fields = show_response.json()["fields"] + # assert len(updated_fields) == original_count + 1 + # field0 = updated_fields[0] + # url = self._api_url( "tool_data/testbeta?key=%s" % self.galaxy_interactor.master_api_key ) + # delete( url, data=json.dumps({"values": "\t".join(field0)}) ) + + # show_response = self._get( "tool_data/testbeta", admin=True ) + # updated_fields = show_response.json()["fields"] + # assert len(updated_fields) == original_count diff --git a/test/functional/tool-data/data1/entry.txt b/test/functional/tool-data/data1/entry.txt new file mode 100644 index 00000000000..f70b104b450 --- /dev/null +++ b/test/functional/tool-data/data1/entry.txt @@ -0,0 +1 @@ +This is data 1. \ No newline at end of file diff --git a/test/functional/tool-data/data1/entry.txt.index b/test/functional/tool-data/data1/entry.txt.index new file mode 100644 index 00000000000..f3a6edd40a8 --- /dev/null +++ b/test/functional/tool-data/data1/entry.txt.index @@ -0,0 +1 @@ +fancy compressed map built with cool algorithms... \ No newline at end of file diff --git a/test/functional/tool-data/data2/entry.txt b/test/functional/tool-data/data2/entry.txt new file mode 100644 index 00000000000..12c526a2a4b --- /dev/null +++ b/test/functional/tool-data/data2/entry.txt @@ -0,0 +1 @@ +This is data 2. \ No newline at end of file diff --git a/test/functional/tool-data/data2/entry.txt.index b/test/functional/tool-data/data2/entry.txt.index new file mode 100644 index 00000000000..8965f832336 --- /dev/null +++ b/test/functional/tool-data/data2/entry.txt.index @@ -0,0 +1 @@ +fancy compressed map built with cool algorithms...2 \ No newline at end of file From a20938fc48c0d94c5371aa1185c804ca6bc9c99a Mon Sep 17 00:00:00 2001 From: John Chilton Date: Mon, 2 Mar 2015 22:31:32 -0500 Subject: [PATCH 04/12] Attempt to fix intermittently failing jobs API test. Retry check several times in case there is some sort of timing problem where a history turns okay - before a job. Improve assertion error message. --- test/api/test_jobs.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/test/api/test_jobs.py b/test/api/test_jobs.py index d5d6c3d3d51..192da79f465 100644 --- a/test/api/test_jobs.py +++ b/test/api/test_jobs.py @@ -29,14 +29,23 @@ class JobsApiTestCase( api.ApiTestCase, TestsDatasets ): def test_index_state_filter( self ): # Initial number of ok jobs original_count = len( self.__uploads_with_state( "ok" ) ) - # Run through dataset upload to ensure num uplaods at least greater # by 1. self.__history_with_ok_dataset() # Verify number of ok jobs is actually greater. - new_count = len( self.__uploads_with_state( "ok" ) ) - assert original_count < new_count + count_increased = False + for i in range(10): + new_count = len( self.__uploads_with_state( "ok" ) ) + if original_count < new_count: + count_increased = True + break + time.sleep(.1) + + if not count_increased: + template = "Jobs in ok state did not increase (was %d, now %d)" + message = template % (original_count, new_count) + raise AssertionError(message) def test_index_date_filter( self ): self.__history_with_new_dataset() From f8bfe89c4238cb875988d3aec605f1e598ec61ce Mon Sep 17 00:00:00 2001 From: John Chilton Date: Mon, 2 Mar 2015 22:33:07 -0500 Subject: [PATCH 05/12] Clarify failing test test_tools.py. --- test/api/test_tools.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/api/test_tools.py b/test/api/test_tools.py index b1cb8c95f8a..e1b5485ce5b 100644 --- a/test/api/test_tools.py +++ b/test/api/test_tools.py @@ -219,8 +219,9 @@ class ToolsTestCase( api.ApiTestCase ): 'col': "' ; echo 'moo", } response = self._run( "column_param", history_id, inputs ) - # TODO: make this test pass... - self._assert_status_code_is( response, 400 ) + if response.status_code == 200: + message = "Known, high priority issue. Column parameters are sanitized but invalid values should prevent execution and doesn't." + raise AssertionError(message) @skip_without_tool( "collection_paired_test" ) def test_collection_parameter( self ): From 391abd5fd6a30ef78ca8bbf4fda0dd27deed58a7 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Mon, 2 Mar 2015 22:34:40 -0500 Subject: [PATCH 06/12] Remove assert False from test/api/test_workflows_from_yaml.py. These aren't ideal tests - but it is some indication that things are working that the API will import the workflow and produce a representation. Should follow up at some point and verify the representation is in fact the correct one. --- test/api/test_workflows_from_yaml.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/api/test_workflows_from_yaml.py b/test/api/test_workflows_from_yaml.py index 865459f3c85..4c1860cc723 100644 --- a/test/api/test_workflows_from_yaml.py +++ b/test/api/test_workflows_from_yaml.py @@ -100,8 +100,6 @@ test_data: $link: the_pause """) print self._get("workflows/%s/download" % workflow_id).json() - assert False - # TODO: fill out test... def test_implicit_connections( self ): workflow_id = self._upload_yaml_workflow(""" @@ -132,4 +130,3 @@ test_data: """) workflow = self._get("workflows/%s/download" % workflow_id).json() print workflow - assert False From fc0a6d8764da8d84627c9674b869fb2ecff4069e Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 3 Mar 2015 09:30:55 -0500 Subject: [PATCH 07/12] Fix intermittently failing test test_workflow_run_dynamic_output_collections. Love it when the bugs correspond to actual TODOs I left in the code. --- test/api/test_workflows.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/test/api/test_workflows.py b/test/api/test_workflows.py index aa5e6ef9765..3a9219894d3 100644 --- a/test/api/test_workflows.py +++ b/test/api/test_workflows.py @@ -570,11 +570,13 @@ class WorkflowsApiTestCase( BaseWorkflowsApiTestCase ): '0': self._ds_entry(hda1), '1': self._ds_entry(hda2), } - self.__invoke_workflow( history_id, workflow_id, inputs ) - # TODO: wait on workflow invocations - time.sleep(10) - self.dataset_populator.wait_for_history( history_id, assert_ok=True ) - self.assertEquals("10.0\n30.0\n20.0\n40.0\n", self.dataset_populator.get_history_dataset_content( history_id, hid=0 ) ) + invocation_id = self.__invoke_workflow( history_id, workflow_id, inputs ) + self.wait_for_invocation_and_jobs( history_id, workflow_id, invocation_id ) + details = self.dataset_populator.get_history_dataset_details( history_id, hid=0 ) + last_item_hid = details["hid"] + assert last_item_hid == 7, "Expected 7 history items, got %s" % last_item_hid + content = self.dataset_populator.get_history_dataset_content( history_id, hid=0 ) + self.assertEquals("10.0\n30.0\n20.0\n40.0\n", content ) def test_workflow_request( self ): workflow = self.workflow_populator.load_workflow( name="test_for_queue" ) @@ -740,12 +742,15 @@ test_data: assert len( self._history_jobs( history_id ) ) == 2 self.__review_paused_steps( workflow_id, invocation_id, order_index=2, action=True ) - self.wait_for_invocation( workflow_id, invocation_id ) - time.sleep(1) - self.dataset_populator.wait_for_history( history_id, assert_ok=True ) - time.sleep(1) + self.wait_for_invocation_and_jobs( history_id, workflow_id, invocation_id ) assert len( self._history_jobs( history_id ) ) == 4 + def wait_for_invocation_and_jobs( self, history_id, workflow_id, invocation_id, assert_ok=True ): + self.wait_for_invocation( workflow_id, invocation_id ) + time.sleep(.5) + self.dataset_populator.wait_for_history( history_id, assert_ok=True ) + time.sleep(.5) + def test_cannot_run_inaccessible_workflow( self ): workflow = self.workflow_populator.load_workflow( name="test_for_run_cannot_access" ) workflow_request, history_id = self._setup_workflow_run( workflow ) From f823278efdfab68a3de119da292eb98ff24523f8 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 3 Mar 2015 09:37:30 -0500 Subject: [PATCH 08/12] Fix bug in workflows test for implicit connections between steps. It would fail when being run with the rest of the suite and not on its own - because it was using the same id for the workflow id and invocation id - which is obviously wrong unless it is a completely fresh database :). --- test/api/test_workflows.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/api/test_workflows.py b/test/api/test_workflows.py index 3a9219894d3..acaa39e5a81 100644 --- a/test/api/test_workflows.py +++ b/test/api/test_workflows.py @@ -168,6 +168,7 @@ class BaseWorkflowsApiTestCase( api.ApiTestCase ): return RunJobsSummary( history_id=history_id, workflow_id=workflow_id, + invocation_id=invocation_id, inputs=inputs, jobs=jobs, ) @@ -733,7 +734,7 @@ test_data: time.sleep( 2 ) history_id = run_summary.history_id workflow_id = run_summary.workflow_id - invocation_id = run_summary.workflow_id + invocation_id = run_summary.invocation_id self.dataset_populator.wait_for_history( history_id, assert_ok=True ) invocation = self._invocation_details( workflow_id, invocation_id ) assert invocation[ 'state' ] != 'scheduled' @@ -1174,4 +1175,4 @@ test_data: 'input_steps', ) -RunJobsSummary = namedtuple('RunJobsSummary', ['history_id', 'workflow_id', 'inputs', 'jobs']) +RunJobsSummary = namedtuple('RunJobsSummary', ['history_id', 'workflow_id', 'invocation_id', 'inputs', 'jobs']) From 05ff2aa6cec0404b5817d14891fffc3432613d2a Mon Sep 17 00:00:00 2001 From: Daniel Blankenberg Date: Tue, 3 Mar 2015 10:24:58 -0500 Subject: [PATCH 09/12] Add a 10 second timeout to loading data URLs for Tool Data Tables. --- lib/galaxy/tools/data/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/tools/data/__init__.py b/lib/galaxy/tools/data/__init__.py index 59c729c9bf9..c90b188027c 100644 --- a/lib/galaxy/tools/data/__init__.py +++ b/lib/galaxy/tools/data/__init__.py @@ -263,7 +263,7 @@ class TabularToolDataTable( ToolDataTable, Dictifiable ): self.data = [] self.configure_and_load( config_element, tool_data_path, from_shed_config) - def configure_and_load( self, config_element, tool_data_path, from_shed_config=False): + def configure_and_load( self, config_element, tool_data_path, from_shed_config=False, url_timeout=10 ): """ Configure and load table from an XML element. """ @@ -289,7 +289,7 @@ class TabularToolDataTable( ToolDataTable, Dictifiable ): if filename: tmp_file = NamedTemporaryFile( prefix='TTDT_URL_%s-' % self.name ) try: - tmp_file.write( urlopen( filename ).read() ) + tmp_file.write( urlopen( filename, timeout=url_timeout ).read() ) except Exception, e: log.error( 'Error loading Data Table URL "%s": %s', filename, e ) continue From 853f5156c0649badd5cc18bba3a06f084a154468 Mon Sep 17 00:00:00 2001 From: Daniel Blankenberg Date: Tue, 3 Mar 2015 10:49:12 -0500 Subject: [PATCH 10/12] When loading Dynamic Display application links, allow the application to load even if one set of links does not. --- lib/galaxy/datatypes/display_applications/application.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/datatypes/display_applications/application.py b/lib/galaxy/datatypes/display_applications/application.py index 75ffcf6368f..82b8e638b73 100644 --- a/lib/galaxy/datatypes/display_applications/application.py +++ b/lib/galaxy/datatypes/display_applications/application.py @@ -245,8 +245,11 @@ class DisplayApplication( object ): if link: self.links[ link.id ] = link for dynamic_links in elem.findall( 'dynamic_links' ): - for link in DynamicDisplayApplicationBuilder( dynamic_links, self, self.app.datatypes_registry.build_sites ): - self.links[ link.id ] = link + try: + for link in DynamicDisplayApplicationBuilder( dynamic_links, self, self.app.datatypes_registry.build_sites ): + self.links[ link.id ] = link + except Exception, e: + log.error( "Error loading a set of Dynamic Display Application links: %s", e ) def get_link( self, link_name, data, dataset_hash, user_hash, trans, app_kwds ): #returns a link object with data knowledge to generate links self._check_and_reload() From 2e3bebbfe2994438040718b04d2269f1d3141294 Mon Sep 17 00:00:00 2001 From: Daniel Blankenberg Date: Tue, 3 Mar 2015 11:55:47 -0500 Subject: [PATCH 11/12] Fix for reports app not running mysql. --- lib/galaxy/webapps/reports/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/galaxy/webapps/reports/app.py b/lib/galaxy/webapps/reports/app.py index 8b362adb05c..10d306ac05d 100644 --- a/lib/galaxy/webapps/reports/app.py +++ b/lib/galaxy/webapps/reports/app.py @@ -25,7 +25,7 @@ class UniverseApplication( object ): db_url, self.config.database_engine_options, create_tables=True ) - self.targets_mysql = 'mysql' in self.config.database_connection + self.targets_mysql = self.config.database_connection and 'mysql' in self.config.database_connection # Security helper self.security = security.SecurityHelper( id_secret=self.config.id_secret ) # used for cachebusting -- refactor this into a *SINGLE* UniverseApplication base. From d390ef29558c0e92187602593c3fee4238db4d4d Mon Sep 17 00:00:00 2001 From: Carl Eberhard Date: Tue, 3 Mar 2015 13:13:26 -0500 Subject: [PATCH 12/12] Fix to safari that still uses prefixed flexbox attributes --- static/style/blue/base.css | 4 ++-- static/style/src/less/history.less | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/static/style/blue/base.css b/static/style/blue/base.css index 00ec730c9c9..e63c0a5346a 100644 --- a/static/style/blue/base.css +++ b/static/style/blue/base.css @@ -2119,7 +2119,7 @@ div.permissionContainer{padding-left:20px} .annotated-history-panel table.list-items>tbody>tr>td>.list-item{border:0px} .annotated-history-panel .empty-message{margin-top:8px} .current-history-panel .list-item.history-content.current-content{border-left:5px solid #4E5777} -.multi-panel-history{display:flex;flex-direction:column;}.multi-panel-history .flex-row-container,.multi-panel-history .flex-column-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;min-width:0px;min-height:0px;-webkit-align-items:stretch;-ms-align-items:stretch;align-items:stretch;-webkit-align-content:stretch;-ms-align-content:stretch;align-content:stretch;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start} +.multi-panel-history{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.multi-panel-history .flex-row-container,.multi-panel-history .flex-column-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;min-width:0px;min-height:0px;-webkit-align-items:stretch;-ms-align-items:stretch;align-items:stretch;-webkit-align-content:stretch;-ms-align-content:stretch;align-content:stretch;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start} .multi-panel-history .flex-row-container{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column} .multi-panel-history .flex-column-container{-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row} .multi-panel-history .flex-row,.multi-panel-history .flex-column{-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;-webkit-align-self:auto;-ms-flex-item-align:auto;align-self:auto} @@ -2142,7 +2142,7 @@ div.permissionContainer{padding-left:20px} .multi-panel-history .history-column:nth-child(2){margin-left:320px} .multi-panel-history .history-column:last-child{margin-right:0px} .multi-panel-history .history-column .dropdown-menu{z-index:inherit} -.multi-panel-history .history-column .panel-controls{width:100%;height:24px;border-radius:3px;background-color:white;text-align:center;flex:0 0 auto;-webkit-align-self:auto;-ms-flex-item-align:auto;align-self:auto}.multi-panel-history .history-column .panel-controls .btn{height:20px;line-height:normal;font-size:90%;padding-top:0px;padding-bottom:0px} +.multi-panel-history .history-column .panel-controls{width:100%;height:24px;border-radius:3px;background-color:white;text-align:center;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;-webkit-align-self:auto;-ms-flex-item-align:auto;align-self:auto}.multi-panel-history .history-column .panel-controls .btn{height:20px;line-height:normal;font-size:90%;padding-top:0px;padding-bottom:0px} .multi-panel-history .history-column .panel-controls .pull-left .btn{margin-right:4px} .multi-panel-history .history-column .panel-controls .pull-right .btn{margin-left:4px} .multi-panel-history .history-column .panel-controls .panel-menu{z-index:1}.multi-panel-history .history-column .panel-controls .panel-menu .dropdown-menu a{text-align:left} diff --git a/static/style/src/less/history.less b/static/style/src/less/history.less index 7ef65171c21..d2fdb9e5f31 100644 --- a/static/style/src/less/history.less +++ b/static/style/src/less/history.less @@ -584,7 +584,13 @@ // for some reason, .flex-row-container below won't be applied to multi-panel-history since it's the enclosing node // re-apply here + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; display: flex; + + -webkit-flex-direction: column; + -ms-flex-direction: column; flex-direction: column; .flex-row-container, @@ -770,6 +776,8 @@ background-color: white; text-align: center; + -webkit-flex: 0 0 auto; + -ms-flex: 0 0 auto; flex: 0 0 auto; -webkit-align-self: auto;