galaxy-commits
Threads by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- 15302 discussions
commit/galaxy-central: jgoecks: Grid framework fixes, including extension of sanitize_text to work with lists of text.
by Bitbucket 14 Feb '13
by Bitbucket 14 Feb '13
14 Feb '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/db08c095de0c/
changeset: db08c095de0c
user: jgoecks
date: 2013-02-14 19:48:52
summary: Grid framework fixes, including extension of sanitize_text to work with lists of text.
affected #: 3 files
diff -r 3ffe47cea647ae61a02d74bbff68e0e07bff70e4 -r db08c095de0c249f3a6cde62f254c104de1fb6ea lib/galaxy/util/__init__.py
--- a/lib/galaxy/util/__init__.py
+++ b/lib/galaxy/util/__init__.py
@@ -196,7 +196,18 @@
return text
def sanitize_text(text):
- """Restricts the characters that are allowed in a text"""
+ """
+ Restricts the characters that are allowed in text; accepts both strings
+ and lists of strings.
+ """
+ if isinstance( text, basestring ):
+ return _sanitize_text_helper(text)
+ elif isinstance( text, list ):
+ return [ _sanitize_text_helper(t) for t in text ]
+
+def _sanitize_text_helper(text):
+ """Restricts the characters that are allowed in a string"""
+
out = []
for c in text:
if c in valid_chars:
diff -r 3ffe47cea647ae61a02d74bbff68e0e07bff70e4 -r db08c095de0c249f3a6cde62f254c104de1fb6ea static/scripts/galaxy.grids.js
--- a/static/scripts/galaxy.grids.js
+++ b/static/scripts/galaxy.grids.js
@@ -48,7 +48,7 @@
// Update URL arg with new condition.
if (append) {
// Update or append value.
- var cur_val = this.attributes.key,
+ var cur_val = this.attributes.filters[key],
new_val;
if (cur_val === null || cur_val === undefined) {
new_val = value;
diff -r 3ffe47cea647ae61a02d74bbff68e0e07bff70e4 -r db08c095de0c249f3a6cde62f254c104de1fb6ea static/scripts/packed/galaxy.grids.js
--- a/static/scripts/packed/galaxy.grids.js
+++ b/static/scripts/packed/galaxy.grids.js
@@ -1,1 +1,1 @@
-jQuery.ajaxSettings.traditional=true;$(document).ready(function(){init_grid_elements();init_grid_controls();$("input[type=text]").each(function(){$(this).click(function(){$(this).select()}).keyup(function(){$(this).css("font-style","normal")})})});var Grid=Backbone.Model.extend({defaults:{url_base:"",async:false,async_ops:[],categorical_filters:[],filters:{},sort_key:null,show_item_checkboxes:false,cur_page:1,num_pages:1,operation:undefined,item_ids:undefined},can_async_op:function(a){return _.indexOf(this.attributes.async_ops,a)!==-1},add_filter:function(e,f,b){if(b){var c=this.attributes.key,a;if(c===null||c===undefined){a=f}else{if(typeof(c)=="string"){if(c=="All"){a=f}else{var d=[];d[0]=c;d[1]=f;a=d}}else{a=c;a.push(f)}}this.attributes.filters[e]=a}else{this.attributes.filters[e]=f}},remove_filter:function(b,e){var a=this.attributes.filters[b];if(a===null||a===undefined){return false}var d=true;if(typeof(a)==="string"){if(a=="All"){d=false}else{delete this.attributes.filters[b]}}else{var c=_.indexOf(a,e);if(c!==-1){a.splice(c,1)}else{d=false}}return d},get_url_data:function(){var a={async:this.attributes.async,sort:this.attributes.sort_key,page:this.attributes.cur_page,show_item_checkboxes:this.attributes.show_item_checkboxes};if(this.attributes.operation){a.operation=this.attributes.operation}if(this.attributes.item_ids){a.id=this.attributes.item_ids}var b=this;_.each(_.keys(b.attributes.filters),function(c){a["f-"+c]=b.attributes.filters[c]});return a}});function init_operation_buttons(){$("input[name=operation]:submit").each(function(){$(this).click(function(){var b=$(this).val();var a=[];$("input[name=id]:checked").each(function(){a.push($(this).val())});do_operation(b,a)})})}function init_grid_controls(){init_operation_buttons();$(".submit-image").each(function(){$(this).mousedown(function(){$(this).addClass("gray-background")});$(this).mouseup(function(){$(this).removeClass("gray-background")})});$(".sort-link").each(function(){$(this).click(function(){set_sort_condition($(this).attr("sort_key"));return false})});$(".page-link > a").each(function(){$(this).click(function(){set_page($(this).attr("page_num"));return false})});$(".categorical-filter > a").each(function(){$(this).click(function(){set_categorical_filter($(this).attr("filter_key"),$(this).attr("filter_val"));return false})});$(".text-filter-form").each(function(){$(this).submit(function(){var d=$(this).attr("column_key");var c=$("#input-"+d+"-filter");var e=c.val();c.val("");add_filter_condition(d,e,true);return false})});var a=$("#input-tags-filter");if(a.length){a.autocomplete(history_tag_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}var b=$("#input-name-filter");if(b.length){b.autocomplete(history_name_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}$(".advanced-search-toggle").each(function(){$(this).click(function(){$("#standard-search").slideToggle("fast");$("#advanced-search").slideToggle("fast");return false})})}function init_grid_elements(){$(".grid").each(function(){var b=$(this).find("input.grid-row-select-checkbox");var a=$(this).find("span.grid-selected-count");var c=function(){a.text($(b).filter(":checked").length)};$(b).each(function(){$(this).change(c)});c()});$(".label").each(function(){var a=$(this).attr("href");if(a!==undefined&&a.indexOf("operation=")!=-1){$(this).click(function(){do_operation_from_href($(this).attr("href"));return false})}});$(".community_rating_star").rating({});make_popup_menus()}function go_page_one(){var a=grid.get("cur_page");if(a!==null&&a!==undefined&&a!=="all"){grid.set("cur_page",1)}}function add_filter_condition(c,e,a){if(e===""){return false}grid.add_filter(c,e,a);var d=$("<span>"+e+"<a href='javascript:void(0);'><span class='delete-search-icon' /></a></span>");d.addClass("text-filter-val");d.click(function(){grid.remove_filter(c,e);$(this).remove();go_page_one();update_grid()});var b=$("#"+c+"-filtering-criteria");b.append(d);go_page_one();update_grid()}function add_tag_to_grid_filter(c,b){var a=c+(b!==undefined&&b!==""?":"+b:"");$("#advanced-search").show("fast");add_filter_condition("tags",a,true)}function set_sort_condition(f){var e=grid.get("sort_key");var d=f;if(e.indexOf(f)!==-1){if(e.substring(0,1)!=="-"){d="-"+f}else{}}$(".sort-arrow").remove();var c=(d.substring(0,1)=="-")?"↑":"↓";var a=$("<span>"+c+"</span>").addClass("sort-arrow");var b=$("#"+f+"-header");b.append(a);grid.set("sort_key",d);go_page_one();update_grid()}function set_categorical_filter(b,d){var a=grid.get("categorical_filters")[b],c=grid.get("filters")[b];$("."+b+"-filter").each(function(){var h=$.trim($(this).text());var f=a[h];var g=f[b];if(g==d){$(this).empty();$(this).addClass("current-filter");$(this).append(h)}else{if(g==c){$(this).empty();var e=$("<a href='#'>"+h+"</a>");e.click(function(){set_categorical_filter(b,g)});$(this).removeClass("current-filter");$(this).append(e)}}});grid.add_filter(b,d);go_page_one();update_grid()}function set_page(a){$(".page-link").each(function(){var g=$(this).attr("id"),e=parseInt(g.split("-")[2],10),c=grid.get("cur_page"),f;if(e===a){f=$(this).children().text();$(this).empty();$(this).addClass("inactive-link");$(this).text(f)}else{if(e===c){f=$(this).text();$(this).empty();$(this).removeClass("inactive-link");var d=$("<a href='#'>"+f+"</a>");d.click(function(){set_page(e)});$(this).append(d)}}});var b=true;if(a==="all"){grid.set("cur_page",a);b=false}else{grid.set("cur_page",parseInt(a,10))}update_grid(b)}function do_operation(b,a){b=b.toLowerCase();grid.set({operation:b,item_ids:a});if(grid.can_async_op(b)){update_grid(true)}else{go_to_URL()}}function do_operation_from_href(c){var f=c.split("?");if(f.length>1){var a=f[1];var e=a.split("&");var b=null;var g=-1;for(var d=0;d<e.length;d++){if(e[d].indexOf("operation")!=-1){b=e[d].split("=")[1]}else{if(e[d].indexOf("id")!=-1){g=e[d].split("=")[1]}}}do_operation(b,g);return false}}function go_to_URL(){grid.set("async",false);window.location=grid.get("url_base")+"?"+$.param(grid.get_url_data())}function update_grid(a){if(!grid.get("async")){go_to_URL();return}var b=(grid.get("operation")?"POST":"GET");$(".loading-elt-overlay").show();$.ajax({type:b,url:grid.get("url_base"),data:grid.get_url_data(),error:function(){alert("Grid refresh failed")},success:function(d){var c=d.split("*****");$("#grid-table-body").html(c[0]);$("#grid-table-footer").html(c[1]);$("#grid-table-body").trigger("update");init_grid_elements();init_operation_buttons();make_popup_menus();$(".loading-elt-overlay").hide();var e=$.trim(c[2]);if(e!==""){$("#grid-message").html(e).show();setTimeout(function(){$("#grid-message").hide()},5000)}},complete:function(){grid.set({operation:undefined,item_ids:undefined})}})}function check_all_items(){var a=document.getElementById("check_all"),b=document.getElementsByTagName("input"),d=0,c;if(a.checked===true){for(c=0;c<b.length;c++){if(b[c].name.indexOf("id")!==-1){b[c].checked=true;d++}}}else{for(c=0;c<b.length;c++){if(b[c].name.indexOf("id")!==-1){b[c].checked=false}}}init_grid_elements()};
\ No newline at end of file
+jQuery.ajaxSettings.traditional=true;$(document).ready(function(){init_grid_elements();init_grid_controls();$("input[type=text]").each(function(){$(this).click(function(){$(this).select()}).keyup(function(){$(this).css("font-style","normal")})})});var Grid=Backbone.Model.extend({defaults:{url_base:"",async:false,async_ops:[],categorical_filters:[],filters:{},sort_key:null,show_item_checkboxes:false,cur_page:1,num_pages:1,operation:undefined,item_ids:undefined},can_async_op:function(a){return _.indexOf(this.attributes.async_ops,a)!==-1},add_filter:function(e,f,b){if(b){var c=this.attributes.filters[e],a;if(c===null||c===undefined){a=f}else{if(typeof(c)=="string"){if(c=="All"){a=f}else{var d=[];d[0]=c;d[1]=f;a=d}}else{a=c;a.push(f)}}this.attributes.filters[e]=a}else{this.attributes.filters[e]=f}},remove_filter:function(b,e){var a=this.attributes.filters[b];if(a===null||a===undefined){return false}var d=true;if(typeof(a)==="string"){if(a=="All"){d=false}else{delete this.attributes.filters[b]}}else{var c=_.indexOf(a,e);if(c!==-1){a.splice(c,1)}else{d=false}}return d},get_url_data:function(){var a={async:this.attributes.async,sort:this.attributes.sort_key,page:this.attributes.cur_page,show_item_checkboxes:this.attributes.show_item_checkboxes};if(this.attributes.operation){a.operation=this.attributes.operation}if(this.attributes.item_ids){a.id=this.attributes.item_ids}var b=this;_.each(_.keys(b.attributes.filters),function(c){a["f-"+c]=b.attributes.filters[c]});return a}});function init_operation_buttons(){$("input[name=operation]:submit").each(function(){$(this).click(function(){var b=$(this).val();var a=[];$("input[name=id]:checked").each(function(){a.push($(this).val())});do_operation(b,a)})})}function init_grid_controls(){init_operation_buttons();$(".submit-image").each(function(){$(this).mousedown(function(){$(this).addClass("gray-background")});$(this).mouseup(function(){$(this).removeClass("gray-background")})});$(".sort-link").each(function(){$(this).click(function(){set_sort_condition($(this).attr("sort_key"));return false})});$(".page-link > a").each(function(){$(this).click(function(){set_page($(this).attr("page_num"));return false})});$(".categorical-filter > a").each(function(){$(this).click(function(){set_categorical_filter($(this).attr("filter_key"),$(this).attr("filter_val"));return false})});$(".text-filter-form").each(function(){$(this).submit(function(){var d=$(this).attr("column_key");var c=$("#input-"+d+"-filter");var e=c.val();c.val("");add_filter_condition(d,e,true);return false})});var a=$("#input-tags-filter");if(a.length){a.autocomplete(history_tag_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}var b=$("#input-name-filter");if(b.length){b.autocomplete(history_name_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}$(".advanced-search-toggle").each(function(){$(this).click(function(){$("#standard-search").slideToggle("fast");$("#advanced-search").slideToggle("fast");return false})})}function init_grid_elements(){$(".grid").each(function(){var b=$(this).find("input.grid-row-select-checkbox");var a=$(this).find("span.grid-selected-count");var c=function(){a.text($(b).filter(":checked").length)};$(b).each(function(){$(this).change(c)});c()});$(".label").each(function(){var a=$(this).attr("href");if(a!==undefined&&a.indexOf("operation=")!=-1){$(this).click(function(){do_operation_from_href($(this).attr("href"));return false})}});$(".community_rating_star").rating({});make_popup_menus()}function go_page_one(){var a=grid.get("cur_page");if(a!==null&&a!==undefined&&a!=="all"){grid.set("cur_page",1)}}function add_filter_condition(c,e,a){if(e===""){return false}grid.add_filter(c,e,a);var d=$("<span>"+e+"<a href='javascript:void(0);'><span class='delete-search-icon' /></a></span>");d.addClass("text-filter-val");d.click(function(){grid.remove_filter(c,e);$(this).remove();go_page_one();update_grid()});var b=$("#"+c+"-filtering-criteria");b.append(d);go_page_one();update_grid()}function add_tag_to_grid_filter(c,b){var a=c+(b!==undefined&&b!==""?":"+b:"");$("#advanced-search").show("fast");add_filter_condition("tags",a,true)}function set_sort_condition(f){var e=grid.get("sort_key");var d=f;if(e.indexOf(f)!==-1){if(e.substring(0,1)!=="-"){d="-"+f}else{}}$(".sort-arrow").remove();var c=(d.substring(0,1)=="-")?"↑":"↓";var a=$("<span>"+c+"</span>").addClass("sort-arrow");var b=$("#"+f+"-header");b.append(a);grid.set("sort_key",d);go_page_one();update_grid()}function set_categorical_filter(b,d){var a=grid.get("categorical_filters")[b],c=grid.get("filters")[b];$("."+b+"-filter").each(function(){var h=$.trim($(this).text());var f=a[h];var g=f[b];if(g==d){$(this).empty();$(this).addClass("current-filter");$(this).append(h)}else{if(g==c){$(this).empty();var e=$("<a href='#'>"+h+"</a>");e.click(function(){set_categorical_filter(b,g)});$(this).removeClass("current-filter");$(this).append(e)}}});grid.add_filter(b,d);go_page_one();update_grid()}function set_page(a){$(".page-link").each(function(){var g=$(this).attr("id"),e=parseInt(g.split("-")[2],10),c=grid.get("cur_page"),f;if(e===a){f=$(this).children().text();$(this).empty();$(this).addClass("inactive-link");$(this).text(f)}else{if(e===c){f=$(this).text();$(this).empty();$(this).removeClass("inactive-link");var d=$("<a href='#'>"+f+"</a>");d.click(function(){set_page(e)});$(this).append(d)}}});var b=true;if(a==="all"){grid.set("cur_page",a);b=false}else{grid.set("cur_page",parseInt(a,10))}update_grid(b)}function do_operation(b,a){b=b.toLowerCase();grid.set({operation:b,item_ids:a});if(grid.can_async_op(b)){update_grid(true)}else{go_to_URL()}}function do_operation_from_href(c){var f=c.split("?");if(f.length>1){var a=f[1];var e=a.split("&");var b=null;var g=-1;for(var d=0;d<e.length;d++){if(e[d].indexOf("operation")!=-1){b=e[d].split("=")[1]}else{if(e[d].indexOf("id")!=-1){g=e[d].split("=")[1]}}}do_operation(b,g);return false}}function go_to_URL(){grid.set("async",false);window.location=grid.get("url_base")+"?"+$.param(grid.get_url_data())}function update_grid(a){if(!grid.get("async")){go_to_URL();return}var b=(grid.get("operation")?"POST":"GET");$(".loading-elt-overlay").show();$.ajax({type:b,url:grid.get("url_base"),data:grid.get_url_data(),error:function(){alert("Grid refresh failed")},success:function(d){var c=d.split("*****");$("#grid-table-body").html(c[0]);$("#grid-table-footer").html(c[1]);$("#grid-table-body").trigger("update");init_grid_elements();init_operation_buttons();make_popup_menus();$(".loading-elt-overlay").hide();var e=$.trim(c[2]);if(e!==""){$("#grid-message").html(e).show();setTimeout(function(){$("#grid-message").hide()},5000)}},complete:function(){grid.set({operation:undefined,item_ids:undefined})}})}function check_all_items(){var a=document.getElementById("check_all"),b=document.getElementsByTagName("input"),d=0,c;if(a.checked===true){for(c=0;c<b.length;c++){if(b[c].name.indexOf("id")!==-1){b[c].checked=true;d++}}}else{for(c=0;c<b.length;c++){if(b[c].name.indexOf("id")!==-1){b[c].checked=false}}}init_grid_elements()};
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: inithello: Refactor the tool shed functional tests' upload_file method for clarity.
by Bitbucket 14 Feb '13
by Bitbucket 14 Feb '13
14 Feb '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/3ffe47cea647/
changeset: 3ffe47cea647
user: inithello
date: 2013-02-14 05:36:18
summary: Refactor the tool shed functional tests' upload_file method for clarity.
affected #: 34 files
diff -r dde899d789b698f29269e521d2abc8a1f1373921 -r 3ffe47cea647ae61a02d74bbff68e0e07bff70e4 test/tool_shed/base/twilltestcase.py
--- a/test/tool_shed/base/twilltestcase.py
+++ b/test/tool_shed/base/twilltestcase.py
@@ -168,11 +168,11 @@
raise AssertionError( errmsg )
def create_category( self, **kwd ):
category = test_db_util.get_category_by_name( kwd[ 'name' ] )
- if category is not None:
- return category
- self.visit_url( '/admin/manage_categories?operation=create' )
- self.submit_form( form_no=1, button="create_category_button", **kwd )
- return test_db_util.get_category_by_name( kwd[ 'name' ] )
+ if category is None:
+ self.visit_url( '/admin/manage_categories?operation=create' )
+ self.submit_form( form_no=1, button="create_category_button", **kwd )
+ category = test_db_util.get_category_by_name( kwd[ 'name' ] )
+ return category
def create_checkbox_query_string( self, field_name, value ):
'''
From galaxy.web.form_builder.CheckboxField:
@@ -213,8 +213,13 @@
dependency_description=dependency_description )
self.upload_file( repository,
'repository_dependencies.xml',
- filepath=filepath,
- commit_message='Uploaded dependency on %s.' % ', '.join( repo.name for repo in depends_on ) )
+ filepath=filepath,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded dependency on %s.' % ', '.join( repo.name for repo in depends_on ),
+ strings_displayed=[],
+ strings_not_displayed=[] )
def create_repository_review( self, repository, review_contents_dict, changeset_revision=None, copy_from=None):
strings_displayed = []
if not copy_from:
@@ -860,17 +865,35 @@
def upload_file( self,
repository,
filename,
- filepath=None,
- valid_tools_only=True,
+ filepath,
+ valid_tools_only,
+ uncompress_file,
+ remove_repo_files_not_in_tar,
+ commit_message,
strings_displayed=[],
- strings_not_displayed=[],
- **kwd ):
+ strings_not_displayed=[] ):
+ removed_message = 'files were removed from the repository'
+ if remove_repo_files_not_in_tar:
+ if not self.repository_is_new( repository ):
+ if removed_message not in strings_displayed:
+ strings_displayed.append( removed_message )
+ else:
+ if removed_message not in strings_not_displayed:
+ strings_not_displayed.append( removed_message )
self.visit_url( '/upload/upload?repository_id=%s' % self.security.encode_id( repository.id ) )
if valid_tools_only:
strings_displayed.extend( [ 'has been successfully', 'uploaded to the repository.' ] )
- for key in kwd:
- tc.fv( "1", key, kwd[ key ] )
tc.formfile( "1", "file_data", self.get_filename( filename, filepath ) )
+ if uncompress_file:
+ tc.fv( 1, 'uncompress_file', 'Yes' )
+ else:
+ tc.fv( 1, 'uncompress_file', 'No' )
+ if not self.repository_is_new( repository ):
+ if remove_repo_files_not_in_tar:
+ tc.fv( 1, 'remove_repo_files_not_in_tar', 'Yes' )
+ else:
+ tc.fv( 1, 'remove_repo_files_not_in_tar', 'No' )
+ tc.fv( 1, 'commit_message', commit_message )
tc.submit( "upload_button" )
self.check_for_strings( strings_displayed, strings_not_displayed )
# Uncomment this if it becomes necessary to wait for an asynchronous process to complete after submitting an upload.
diff -r dde899d789b698f29269e521d2abc8a1f1373921 -r 3ffe47cea647ae61a02d74bbff68e0e07bff70e4 test/tool_shed/functional/test_0000_basic_repository_features.py
--- a/test/tool_shed/functional/test_0000_basic_repository_features.py
+++ b/test/tool_shed/functional/test_0000_basic_repository_features.py
@@ -56,7 +56,15 @@
def test_0030_upload_filtering_1_1_0( self ):
"""Upload filtering_1.1.0.tar to the repository"""
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
- self.upload_file( repository, 'filtering/filtering_1.1.0.tar', commit_message="Uploaded filtering 1.1.0" )
+ self.upload_file( repository,
+ filename='filtering/filtering_1.1.0.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=True,
+ commit_message="Uploaded filtering 1.1.0",
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0035_verify_repository( self ):
'''Display basic repository pages'''
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
@@ -102,15 +110,27 @@
'''Upload filtering.txt file associated with tool version 1.1.0.'''
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
self.upload_file( repository,
- 'filtering/filtering_0000.txt',
- commit_message="Uploaded filtering.txt",
- uncompress_file='No',
- remove_repo_files_not_in_tar='No' )
+ filename='filtering/filtering_0000.txt',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message="Uploaded filtering.txt",
+ strings_displayed=[],
+ strings_not_displayed=[] )
self.display_manage_repository_page( repository, strings_displayed=[ 'Readme file for filtering 1.1.0' ] )
def test_0055_upload_filtering_test_data( self ):
'''Upload filtering test data.'''
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
- self.upload_file( repository, 'filtering/filtering_test_data.tar', commit_message="Uploaded filtering test data", remove_repo_files_not_in_tar='No' )
+ self.upload_file( repository,
+ filename='filtering/filtering_test_data.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message="Uploaded filtering test data",
+ strings_displayed=[],
+ strings_not_displayed=[] )
self.display_repository_file_contents( repository=repository,
filename='1.bed',
filepath='test-data',
@@ -121,9 +141,14 @@
'''Upload filtering version 2.2.0'''
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
self.upload_file( repository,
- 'filtering/filtering_2.2.0.tar',
- commit_message="Uploaded filtering 2.2.0",
- remove_repo_files_not_in_tar='No' )
+ filename='filtering/filtering_2.2.0.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message="Uploaded filtering 2.2.0",
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0065_verify_filtering_repository( self ):
'''Verify the new tool versions and repository metadata.'''
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
@@ -138,7 +163,15 @@
def test_0070_upload_readme_txt_file( self ):
'''Upload readme.txt file associated with tool version 2.2.0.'''
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
- self.upload_file( repository, 'readme.txt', commit_message="Uploaded readme.txt" )
+ self.upload_file( repository,
+ filename='readme.txt',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message="Uploaded readme.txt",
+ strings_displayed=[],
+ strings_not_displayed=[] )
self.display_manage_repository_page( repository, strings_displayed=[ 'This is a readme file.' ] )
# Verify that there is a different readme file for each metadata revision.
metadata_revisions = self.get_repository_metadata_revisions( repository )
diff -r dde899d789b698f29269e521d2abc8a1f1373921 -r 3ffe47cea647ae61a02d74bbff68e0e07bff70e4 test/tool_shed/functional/test_0010_repository_with_tool_dependencies.py
--- a/test/tool_shed/functional/test_0010_repository_with_tool_dependencies.py
+++ b/test/tool_shed/functional/test_0010_repository_with_tool_dependencies.py
@@ -34,10 +34,14 @@
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
self.upload_file( repository,
- 'freebayes/freebayes.xml',
+ filename='freebayes/freebayes.xml',
+ filepath=None,
valid_tools_only=False,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded the tool xml.',
strings_displayed=[ 'Metadata may have been defined', 'This file requires an entry', 'tool_data_table_conf' ],
- commit_message='Uploaded the tool xml.' )
+ strings_not_displayed=[] )
self.display_manage_repository_page( repository, strings_displayed=[ 'Invalid tools' ], strings_not_displayed=[ 'Valid tools' ] )
tip = self.get_repository_tip( repository )
self.check_repository_invalid_tools_for_changeset_revision( repository,
@@ -47,10 +51,14 @@
'''Upload the missing tool_data_table_conf.xml.sample file to the repository.'''
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
self.upload_file( repository,
- 'freebayes/tool_data_table_conf.xml.sample',
+ filename='freebayes/tool_data_table_conf.xml.sample',
+ filepath=None,
valid_tools_only=False,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded the tool data table sample file.',
strings_displayed=[],
- commit_message='Uploaded the tool data table sample file.' )
+ strings_not_displayed=[] )
self.display_manage_repository_page( repository, strings_displayed=[ 'Invalid tools' ], strings_not_displayed=[ 'Valid tools' ] )
tip = self.get_repository_tip( repository )
self.check_repository_invalid_tools_for_changeset_revision( repository,
@@ -60,30 +68,50 @@
'''Upload the missing sam_fa_indices.loc.sample file to the repository.'''
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
self.upload_file( repository,
- 'freebayes/sam_fa_indices.loc.sample',
+ filename='freebayes/sam_fa_indices.loc.sample',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded tool data table .loc file.',
strings_displayed=[],
- commit_message='Uploaded tool data table .loc file.' )
+ strings_not_displayed=[] )
def test_0025_upload_malformed_tool_dependency_xml( self ):
'''Upload tool_dependencies.xml with bad characters in the readme tag.'''
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
self.upload_file( repository,
- os.path.join( 'freebayes', 'malformed_tool_dependencies', 'tool_dependencies.xml' ),
+ filename=os.path.join( 'freebayes', 'malformed_tool_dependencies', 'tool_dependencies.xml' ),
+ filepath=None,
valid_tools_only=False,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded malformed tool dependency XML.',
strings_displayed=[ 'Exception attempting to parse tool_dependencies.xml', 'not well-formed' ],
- commit_message='Uploaded malformed tool dependency XML.' )
+ strings_not_displayed=[] )
def test_0030_upload_invalid_tool_dependency_xml( self ):
'''Upload tool_dependencies.xml defining version 0.9.5 of the freebayes package.'''
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
self.upload_file( repository,
- os.path.join( 'freebayes', 'invalid_tool_dependencies', 'tool_dependencies.xml' ),
+ filename=os.path.join( 'freebayes', 'invalid_tool_dependencies', 'tool_dependencies.xml' ),
+ filepath=None,
+ valid_tools_only=False,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded invalid tool dependency XML.',
strings_displayed=[ 'Name, version and type from a tool requirement tag does not match' ],
- commit_message='Uploaded invalid tool dependency XML.' )
+ strings_not_displayed=[] )
def test_0035_upload_valid_tool_dependency_xml( self ):
'''Upload tool_dependencies.xml defining version 0.9.4_9696d0ce8a962f7bb61c4791be5ce44312b81cf8 of the freebayes package.'''
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
self.upload_file( repository,
- os.path.join( 'freebayes', 'tool_dependencies.xml' ),
- commit_message='Uploaded valid tool dependency XML.' )
+ filename=os.path.join( 'freebayes', 'tool_dependencies.xml' ),
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded valid tool dependency XML.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0040_verify_tool_dependencies( self ):
'''Verify that the uploaded tool_dependencies.xml specifies the correct package versions.'''
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
diff -r dde899d789b698f29269e521d2abc8a1f1373921 -r 3ffe47cea647ae61a02d74bbff68e0e07bff70e4 test/tool_shed/functional/test_0020_basic_repository_dependencies.py
--- a/test/tool_shed/functional/test_0020_basic_repository_dependencies.py
+++ b/test/tool_shed/functional/test_0020_basic_repository_dependencies.py
@@ -37,7 +37,15 @@
owner=common.test_user_1_name,
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
- self.upload_file( repository, 'emboss/datatypes/datatypes_conf.xml', commit_message='Uploaded datatypes_conf.xml.' )
+ self.upload_file( repository,
+ filename='emboss/datatypes/datatypes_conf.xml',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded datatypes_conf.xml.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0015_verify_datatypes_in_datatypes_repository( self ):
'''Verify that the emboss_datatypes repository contains datatype entries.'''
repository = test_db_util.get_repository_by_name_and_owner( datatypes_repository_name, common.test_user_1_name )
@@ -51,7 +59,15 @@
owner=common.test_user_1_name,
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
- self.upload_file( repository, 'emboss/emboss.tar', commit_message='Uploaded emboss_5.tar' )
+ self.upload_file( repository,
+ filename='emboss/emboss.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded emboss.tar',
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0025_generate_and_upload_repository_dependencies_xml( self ):
'''Generate and upload the repository_dependencies.xml file'''
repository = test_db_util.get_repository_by_name_and_owner( emboss_repository_name, common.test_user_1_name )
@@ -60,9 +76,14 @@
self.generate_repository_dependency_xml( [ datatypes_repository ],
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ) )
self.upload_file( repository,
- 'repository_dependencies.xml',
- filepath=repository_dependencies_path,
- commit_message='Uploaded repository_dependencies.xml' )
+ filename='repository_dependencies.xml',
+ filepath=repository_dependencies_path,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded repository_dependencies.xml.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0030_verify_emboss_5_dependencies( self ):
'''Verify that the emboss_5 repository now depends on the emboss_datatypes repository with correct name, owner, and changeset revision.'''
repository = test_db_util.get_repository_by_name_and_owner( emboss_repository_name, common.test_user_1_name )
diff -r dde899d789b698f29269e521d2abc8a1f1373921 -r 3ffe47cea647ae61a02d74bbff68e0e07bff70e4 test/tool_shed/functional/test_0030_repository_dependency_revisions.py
--- a/test/tool_shed/functional/test_0030_repository_dependency_revisions.py
+++ b/test/tool_shed/functional/test_0030_repository_dependency_revisions.py
@@ -28,36 +28,83 @@
def test_0005_create_category( self ):
"""Create a category for this test suite"""
self.create_category( name='Test 0030 Repository Dependency Revisions', description='Testing repository dependencies by revision.' )
- def test_0010_create_repositories( self ):
- '''Create the emboss_5_0030, emboss_6_0030, emboss_datatypes_0030, and emboss_0030 repositories and populate the emboss_datatypes repository.'''
+ def test_0010_create_emboss_5_repository( self ):
+ '''Create and populate the emboss_5_0030 repository.'''
self.logout()
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
category = test_db_util.get_category_by_name( 'Test 0030 Repository Dependency Revisions' )
- emboss_5_repository = self.get_or_create_repository( name=emboss_5_repository_name,
- description=emboss_repository_description,
- long_description=emboss_repository_long_description,
- owner=common.test_user_1_name,
- category_id=self.security.encode_id( category.id ) )
- emboss_6_repository = self.get_or_create_repository( name=emboss_6_repository_name,
- description=emboss_repository_description,
- long_description=emboss_repository_long_description,
- owner=common.test_user_1_name,
- category_id=self.security.encode_id( category.id ) )
- datatypes_repository = self.get_or_create_repository( name=datatypes_repository_name,
- description=emboss_repository_description,
- long_description=emboss_repository_long_description,
- owner=common.test_user_1_name,
- category_id=self.security.encode_id( category.id ) )
- emboss_repository = self.get_or_create_repository( name=emboss_repository_name,
+ repository = self.get_or_create_repository( name=emboss_5_repository_name,
+ description=emboss_repository_description,
+ long_description=emboss_repository_long_description,
+ owner=common.test_user_1_name,
+ category_id=self.security.encode_id( category.id ) )
+ self.upload_file( repository,
+ filename='emboss/emboss.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded tool tarball.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ def test_0015_create_emboss_6_repository( self ):
+ '''Create and populate the emboss_6_0030 repository.'''
+ self.logout()
+ self.login( email=common.test_user_1_email, username=common.test_user_1_name )
+ category = test_db_util.get_category_by_name( 'Test 0030 Repository Dependency Revisions' )
+ repository = self.get_or_create_repository( name=emboss_6_repository_name,
+ description=emboss_repository_description,
+ long_description=emboss_repository_long_description,
+ owner=common.test_user_1_name,
+ category_id=self.security.encode_id( category.id ) )
+ self.upload_file( repository,
+ filename='emboss/emboss.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded tool tarball.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ def test_0020_create_emboss_datatypes_repository( self ):
+ '''Create and populate the emboss_datatypes_0030 repository.'''
+ self.logout()
+ self.login( email=common.test_user_1_email, username=common.test_user_1_name )
+ category = test_db_util.get_category_by_name( 'Test 0030 Repository Dependency Revisions' )
+ repository = self.get_or_create_repository( name=datatypes_repository_name,
+ description=emboss_repository_description,
+ long_description=emboss_repository_long_description,
+ owner=common.test_user_1_name,
+ category_id=self.security.encode_id( category.id ) )
+ self.upload_file( repository,
+ filename='emboss/datatypes/datatypes_conf.xml',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded datatypes_conf.xml.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ def test_0025_create_emboss_repository( self ):
+ '''Create and populate the emboss_0030 repository.'''
+ self.logout()
+ self.login( email=common.test_user_1_email, username=common.test_user_1_name )
+ category = test_db_util.get_category_by_name( 'Test 0030 Repository Dependency Revisions' )
+ repository = self.get_or_create_repository( name=emboss_repository_name,
description=emboss_repository_description,
long_description=emboss_repository_long_description,
owner=common.test_user_1_name,
category_id=self.security.encode_id( category.id ) )
- self.upload_file( emboss_5_repository, 'emboss/emboss.tar', commit_message='Uploaded tool tarball.' )
- self.upload_file( emboss_6_repository, 'emboss/emboss.tar', commit_message='Uploaded tool tarball.' )
- self.upload_file( datatypes_repository, 'emboss/datatypes/datatypes_conf.xml', commit_message='Uploaded datatypes_conf.xml.' )
- self.upload_file( emboss_repository, 'emboss/emboss.tar', commit_message='Uploaded tool tarball.' )
- def test_0015_generate_repository_dependencies_for_emboss_5( self ):
+ self.upload_file( repository,
+ filename='emboss/emboss.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded the tool tarball.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ def test_0030_generate_repository_dependencies_for_emboss_5( self ):
'''Generate a repository_dependencies.xml file specifying emboss_datatypes and upload it to the emboss_5 repository.'''
datatypes_repository = test_db_util.get_repository_by_name_and_owner( datatypes_repository_name, common.test_user_1_name )
repository_dependencies_path = self.generate_temp_path( 'test_0030', additional_paths=[ 'emboss' ] )
@@ -65,18 +112,28 @@
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ) )
emboss_5_repository = test_db_util.get_repository_by_name_and_owner( emboss_5_repository_name, common.test_user_1_name )
self.upload_file( emboss_5_repository,
- 'repository_dependencies.xml',
- filepath=repository_dependencies_path,
- commit_message='Uploaded repository_depepndencies.xml.' )
- def test_0020_generate_repository_dependencies_for_emboss_6( self ):
+ filename='repository_dependencies.xml',
+ filepath=repository_dependencies_path,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded repository_dependencies.xml.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ def test_0035_generate_repository_dependencies_for_emboss_6( self ):
'''Generate a repository_dependencies.xml file specifying emboss_datatypes and upload it to the emboss_6 repository.'''
emboss_6_repository = test_db_util.get_repository_by_name_and_owner( emboss_6_repository_name, common.test_user_1_name )
repository_dependencies_path = self.generate_temp_path( 'test_0030', additional_paths=[ 'emboss' ] )
self.upload_file( emboss_6_repository,
- 'repository_dependencies.xml',
- filepath=repository_dependencies_path,
- commit_message='Uploaded repository_depepndencies.xml.' )
- def test_0025_generate_repository_dependency_on_emboss_5( self ):
+ filename='repository_dependencies.xml',
+ filepath=repository_dependencies_path,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded repository_dependencies.xml.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ def test_0040_generate_repository_dependency_on_emboss_5( self ):
'''Create and upload repository_dependencies.xml for the emboss_5_0030 repository.'''
emboss_repository = test_db_util.get_repository_by_name_and_owner( emboss_repository_name, common.test_user_1_name )
emboss_5_repository = test_db_util.get_repository_by_name_and_owner( emboss_5_repository_name, common.test_user_1_name )
@@ -85,10 +142,15 @@
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ),
dependency_description='Emboss requires the Emboss 5 repository.' )
self.upload_file( emboss_repository,
- 'repository_dependencies.xml',
- filepath=repository_dependencies_path,
- commit_message='Uploaded dependency configuration specifying emboss_5' )
- def test_0030_generate_repository_dependency_on_emboss_6( self ):
+ filename='repository_dependencies.xml',
+ filepath=repository_dependencies_path,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded repository_dependencies.xml.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ def test_0045_generate_repository_dependency_on_emboss_6( self ):
'''Create and upload repository_dependencies.xml for the emboss_6_0030 repository.'''
emboss_repository = test_db_util.get_repository_by_name_and_owner( emboss_repository_name, common.test_user_1_name )
emboss_6_repository = test_db_util.get_repository_by_name_and_owner( emboss_6_repository_name, common.test_user_1_name )
@@ -97,10 +159,15 @@
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ),
dependency_description='Emboss requires the Emboss 6 repository.' )
self.upload_file( emboss_repository,
- 'repository_dependencies.xml',
- filepath=repository_dependencies_path,
- commit_message='Uploaded dependency configuration specifying emboss_6' )
- def test_0035_verify_repository_dependency_revisions( self ):
+ filename='repository_dependencies.xml',
+ filepath=repository_dependencies_path,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded repository_dependencies.xml.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ def test_0050_verify_repository_dependency_revisions( self ):
'''Verify that different metadata revisions of the emboss repository have different repository dependencies.'''
repository = test_db_util.get_repository_by_name_and_owner( emboss_repository_name, common.test_user_1_name )
repository_metadata = [ ( metadata.metadata, metadata.changeset_revision ) for metadata in self.get_repository_metadata( repository ) ]
@@ -120,7 +187,7 @@
self.display_manage_repository_page( repository,
changeset_revision=changeset_revision,
strings_displayed=strings_displayed )
- def test_0040_verify_repository_metadata( self ):
+ def test_0055_verify_repository_metadata( self ):
'''Verify that resetting the metadata does not change it.'''
emboss_repository = test_db_util.get_repository_by_name_and_owner( emboss_repository_name, common.test_user_1_name )
emboss_5_repository = test_db_util.get_repository_by_name_and_owner( emboss_5_repository_name, common.test_user_1_name )
diff -r dde899d789b698f29269e521d2abc8a1f1373921 -r 3ffe47cea647ae61a02d74bbff68e0e07bff70e4 test/tool_shed/functional/test_0040_repository_circular_dependencies.py
--- a/test/tool_shed/functional/test_0040_repository_circular_dependencies.py
+++ b/test/tool_shed/functional/test_0040_repository_circular_dependencies.py
@@ -37,9 +37,14 @@
categories=[ 'test_0040_repository_circular_dependencies' ],
strings_displayed=[] )
self.upload_file( repository,
- 'freebayes/freebayes.tar',
+ filename='freebayes/freebayes.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded the tool tarball.',
strings_displayed=[],
- commit_message='Uploaded freebayes.tar.' )
+ strings_not_displayed=[] )
def test_0015_create_filtering_repository( self ):
'''Create and populate filtering_0040.'''
self.logout()
@@ -51,9 +56,14 @@
categories=[ 'test_0040_repository_circular_dependencies' ],
strings_displayed=[] )
self.upload_file( repository,
- 'filtering/filtering_1.1.0.tar',
+ filename='filtering/filtering_1.1.0.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded the tool tarball for filtering 1.1.0.',
strings_displayed=[],
- commit_message='Uploaded filtering.tar.' )
+ strings_not_displayed=[] )
def test_0020_create_dependency_on_freebayes( self ):
'''Upload a repository_dependencies.xml file that specifies the current revision of freebayes to the filtering_0040 repository.'''
# The dependency structure should look like:
@@ -67,9 +77,14 @@
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ),
dependency_description='Filtering 1.1.0 depends on the freebayes repository.' )
self.upload_file( filtering_repository,
- 'repository_dependencies.xml',
+ filename='repository_dependencies.xml',
filepath=repository_dependencies_path,
- commit_message='Uploaded dependency on freebayes' )
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded dependency on freebayes.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0025_create_dependency_on_filtering( self ):
'''Upload a repository_dependencies.xml file that specifies the current revision of filtering to the freebayes_0040 repository.'''
# The dependency structure should look like:
@@ -83,9 +98,14 @@
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ),
dependency_description='Freebayes depends on the filtering repository.' )
self.upload_file( freebayes_repository,
- 'repository_dependencies.xml',
+ filename='repository_dependencies.xml',
filepath=repository_dependencies_path,
- commit_message='Uploaded dependency on filtering' )
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded dependency on filtering.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0030_verify_repository_dependencies( self ):
'''Verify that each repository can depend on the other without causing an infinite loop.'''
filtering_repository = test_db_util.get_repository_by_name_and_owner( filtering_repository_name, common.test_user_1_name )
diff -r dde899d789b698f29269e521d2abc8a1f1373921 -r 3ffe47cea647ae61a02d74bbff68e0e07bff70e4 test/tool_shed/functional/test_0050_circular_dependencies_4_levels.py
--- a/test/tool_shed/functional/test_0050_circular_dependencies_4_levels.py
+++ b/test/tool_shed/functional/test_0050_circular_dependencies_4_levels.py
@@ -58,9 +58,14 @@
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
self.upload_file( repository,
- 'convert_chars/convert_chars.tar',
+ filename='convert_chars/convert_chars.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded convert_chars tarball.',
strings_displayed=[],
- commit_message='Uploaded convert_chars.tar.' )
+ strings_not_displayed=[] )
def test_0010_create_column_repository( self ):
'''Create and populate convert_chars_0050.'''
category = self.create_category( name=category_name, description=category_description )
@@ -71,9 +76,14 @@
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
self.upload_file( repository,
- 'column_maker/column_maker.tar',
+ filename='column_maker/column_maker.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded column_maker tarball.',
strings_displayed=[],
- commit_message='Uploaded column_maker.tar.' )
+ strings_not_displayed=[] )
def test_0015_create_emboss_datatypes_repository( self ):
'''Create and populate emboss_datatypes_0050.'''
category = self.create_category( name=category_name, description=category_description )
@@ -86,9 +96,14 @@
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
self.upload_file( repository,
- 'emboss/datatypes/datatypes_conf.xml',
+ filename='emboss/datatypes/datatypes_conf.xml',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded datatypes_conf.xml.',
strings_displayed=[],
- commit_message='Uploaded datatypes_conf.xml.' )
+ strings_not_displayed=[] )
def test_0020_create_emboss_repository( self ):
'''Create and populate emboss_0050.'''
category = self.create_category( name=category_name, description=category_description )
@@ -99,18 +114,28 @@
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
self.upload_file( repository,
- 'emboss/emboss.tar',
+ filename='emboss/emboss.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded emboss tarball.',
strings_displayed=[],
- commit_message='Uploaded tool tarball.' )
+ strings_not_displayed=[] )
datatypes_repository = test_db_util.get_repository_by_name_and_owner( emboss_datatypes_repository_name, common.test_user_1_name )
repository_dependencies_path = self.generate_temp_path( 'test_0050', additional_paths=[ 'emboss' ] )
self.generate_repository_dependency_xml( [ datatypes_repository ],
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ),
dependency_description='Emboss depends on the emboss_datatypes repository.' )
self.upload_file( repository,
- 'repository_dependencies.xml',
+ filename='repository_dependencies.xml',
filepath=repository_dependencies_path,
- commit_message='Uploaded dependency on emboss_datatypes.' )
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded dependency on emboss_datatypes.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0025_create_filtering_repository( self ):
'''Create and populate filtering_0050.'''
category = self.create_category( name=category_name, description=category_description )
@@ -121,18 +146,28 @@
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
self.upload_file( filtering_repository,
- 'filtering/filtering_1.1.0.tar',
+ filename='filtering/filtering_1.1.0.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded filtering 1.1.0 tarball.',
strings_displayed=[],
- commit_message='Uploaded filtering.tar.' )
+ strings_not_displayed=[] )
emboss_repository = test_db_util.get_repository_by_name_and_owner( emboss_repository_name, common.test_user_1_name )
repository_dependencies_path = self.generate_temp_path( 'test_0050', additional_paths=[ 'filtering' ] )
self.generate_repository_dependency_xml( [ emboss_repository ],
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ),
dependency_description='Filtering depends on the emboss repository.' )
self.upload_file( filtering_repository,
- 'repository_dependencies.xml',
+ filename='repository_dependencies.xml',
filepath=repository_dependencies_path,
- commit_message='Uploaded dependency on emboss.' )
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded dependency on emboss.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0030_create_freebayes_repository( self ):
'''Create and populate freebayes_0050.'''
category = self.create_category( name=category_name, description=category_description )
@@ -143,9 +178,14 @@
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
self.upload_file( repository,
- 'freebayes/freebayes.tar',
+ filename='freebayes/freebayes.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded freebayes tarball.',
strings_displayed=[],
- commit_message='Uploaded freebayes.tar.' )
+ strings_not_displayed=[] )
def test_0035_create_bismark_repository( self ):
'''Create and populate bismark_0050.'''
category = self.create_category( name=category_name, description=category_description )
@@ -156,10 +196,14 @@
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
self.upload_file( repository,
- 'bismark/bismark.tar',
+ filename='bismark/bismark.tar',
+ filepath=None,
+ valid_tools_only=False,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded bismark tarball.',
strings_displayed=[],
- valid_tools_only=False,
- commit_message='Uploaded bismark.tar.' )
+ strings_not_displayed=[] )
def test_0040_create_and_upload_dependency_definitions( self ):
column_repository = test_db_util.get_repository_by_name_and_owner( column_repository_name, common.test_user_1_name )
convert_repository = test_db_util.get_repository_by_name_and_owner( convert_repository_name, common.test_user_1_name )
diff -r dde899d789b698f29269e521d2abc8a1f1373921 -r 3ffe47cea647ae61a02d74bbff68e0e07bff70e4 test/tool_shed/functional/test_0060_workflows.py
--- a/test/tool_shed/functional/test_0060_workflows.py
+++ b/test/tool_shed/functional/test_0060_workflows.py
@@ -6,6 +6,8 @@
repository_long_description="Long description of Galaxy's filtering tool for test 0060"
workflow_filename = 'Workflow_for_0060_filter_workflow_repository.ga'
workflow_name = 'Workflow for 0060_filter_workflow_repository'
+category_name = 'Test 0060 Workflow Features'
+category_description = 'Test 0060 for workflow features'
class TestToolShedWorkflowFeatures( ShedTwillTestCase ):
'''Test valid and invalid workflows.'''
@@ -26,13 +28,14 @@
self.create_category( name='Test 0060 Workflow Features', description='Test 0060 - Workflow Features' )
def test_0010_create_repository( self ):
"""Create and populate the filtering repository"""
+ category = self.create_category( name=category_name, description=category_description )
self.logout()
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
self.get_or_create_repository( name=repository_name,
description=repository_description,
long_description=repository_long_description,
owner=common.test_user_1_name,
- categories=[ 'Test 0060 Workflow Features' ],
+ category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
def test_0015_upload_workflow( self ):
'''Upload a workflow with a missing tool, and verify that the tool specified is marked as missing.'''
@@ -44,18 +47,27 @@
os.makedirs( workflow_filepath )
file( os.path.join( workflow_filepath, workflow_filename ), 'w+' ).write( workflow )
self.upload_file( repository,
- workflow_filename,
+ filename=workflow_filename,
filepath=workflow_filepath,
- commit_message='Uploaded filtering workflow.' )
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded filtering workflow.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
self.load_workflow_image_in_tool_shed( repository, workflow_name, strings_displayed=[ '#EBBCB2' ] )
def test_0020_upload_tool( self ):
'''Upload the missing tool for the workflow in the previous step, and verify that the error is no longer present.'''
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
self.upload_file( repository,
- 'filtering/filtering_2.2.0.tar',
- commit_message="Uploaded filtering 2.2.0",
- remove_repo_files_not_in_tar='No' )
-# raise Exception( self.get_repository_tip( repository ) )
+ filename='filtering/filtering_2.2.0.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded filtering 2.2.0.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
self.load_workflow_image_in_tool_shed( repository, workflow_name, strings_not_displayed=[ '#EBBCB2' ] )
def test_0025_verify_repository_metadata( self ):
'''Verify that resetting the metadata does not change it.'''
diff -r dde899d789b698f29269e521d2abc8a1f1373921 -r 3ffe47cea647ae61a02d74bbff68e0e07bff70e4 test/tool_shed/functional/test_0070_invalid_tool.py
--- a/test/tool_shed/functional/test_0070_invalid_tool.py
+++ b/test/tool_shed/functional/test_0070_invalid_tool.py
@@ -5,6 +5,7 @@
repository_description = "Galaxy's bismark wrapper"
repository_long_description = "Long description of Galaxy's bismark wrapper"
category_name = 'Test 0070 Invalid Tool Revisions'
+category_description = 'Tests for a repository with invalid tool revisions.'
class TestBismarkRepository( ShedTwillTestCase ):
'''Testing bismark with valid and invalid tool entries.'''
@@ -22,7 +23,7 @@
admin_user_private_role = test_db_util.get_private_role( admin_user )
def test_0005_create_category_and_repository( self ):
"""Create a category for this test suite, then create and populate a bismark repository. It should contain at least one each valid and invalid tool."""
- category = self.create_category( name=category_name, description='Tests for a repository with invalid tool revisions.' )
+ category = self.create_category( name=category_name, description=category_description )
self.logout()
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
repository = self.get_or_create_repository( name=repository_name,
@@ -32,18 +33,25 @@
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
self.upload_file( repository,
- 'bismark/bismark.tar',
+ filename='bismark/bismark.tar',
+ filepath=None,
valid_tools_only=False,
- strings_displayed=[],
- commit_message='Uploaded the tool tarball.' )
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded bismark tarball.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
self.display_manage_repository_page( repository, strings_displayed=[ 'Invalid tools' ] )
invalid_revision = self.get_repository_tip( repository )
self.upload_file( repository,
- 'bismark/bismark_methylation_extractor.xml',
- valid_tools_only=False,
- strings_displayed=[],
- remove_repo_files_not_in_tar='No',
- commit_message='Uploaded an updated tool xml.' )
+ filename='bismark/bismark_methylation_extractor.xml',
+ filepath=None,
+ valid_tools_only=False,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded an updated tool xml.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
valid_revision = self.get_repository_tip( repository )
test_db_util.refresh( repository )
self.check_repository_tools_for_changeset_revision( repository, valid_revision )
diff -r dde899d789b698f29269e521d2abc8a1f1373921 -r 3ffe47cea647ae61a02d74bbff68e0e07bff70e4 test/tool_shed/functional/test_0080_advanced_circular_dependencies.py
--- a/test/tool_shed/functional/test_0080_advanced_circular_dependencies.py
+++ b/test/tool_shed/functional/test_0080_advanced_circular_dependencies.py
@@ -26,8 +26,8 @@
admin_user = test_db_util.get_user( common.admin_email )
assert admin_user is not None, 'Problem retrieving user with email %s from the database' % admin_email
admin_user_private_role = test_db_util.get_private_role( admin_user )
- def test_0005_initiate_category_repositories( self ):
- """Create a category for this test suite and add repositories to it."""
+ def test_0005_create_column_repository( self ):
+ """Create and populate the column_maker repository."""
category = self.create_category( name=category_name, description=category_description )
self.logout()
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
@@ -38,9 +38,21 @@
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
self.upload_file( repository,
- 'column_maker/column_maker.tar',
+ filename='column_maker/column_maker.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded column_maker tarball.',
strings_displayed=[],
- commit_message='Uploaded column_maker.tar.' )
+ strings_not_displayed=[] )
+ def test_0005_create_convert_repository( self ):
+ """Create and populate the convert_chars repository."""
+ self.logout()
+ self.login( email=common.admin_email, username=common.admin_username )
+ category = self.create_category( name=category_name, description=category_description )
+ self.logout()
+ self.login( email=common.test_user_1_email, username=common.test_user_1_name )
repository = self.get_or_create_repository( name=convert_repository_name,
description=convert_repository_description,
long_description=convert_repository_long_description,
@@ -48,9 +60,14 @@
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
self.upload_file( repository,
- 'convert_chars/convert_chars.tar',
+ filename='convert_chars/convert_chars.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded convert_chars tarball.',
strings_displayed=[],
- commit_message='Uploaded convert_chars.tar.' )
+ strings_not_displayed=[] )
def test_0020_create_repository_dependencies( self ):
'''Upload a repository_dependencies.xml file that specifies the current revision of freebayes to the filtering_0040 repository.'''
convert_repository = test_db_util.get_repository_by_name_and_owner( convert_repository_name, common.test_user_1_name )
@@ -60,9 +77,14 @@
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ),
dependency_description='Column maker depends on the convert repository.' )
self.upload_file( column_repository,
- 'repository_dependencies.xml',
- filepath=repository_dependencies_path,
- commit_message='Uploaded dependency on convert' )
+ filename='repository_dependencies.xml',
+ filepath=repository_dependencies_path,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded dependency on convert_chars.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0025_create_dependency_on_filtering( self ):
'''Upload a repository_dependencies.xml file that specifies the current revision of filtering to the freebayes_0040 repository.'''
convert_repository = test_db_util.get_repository_by_name_and_owner( convert_repository_name, common.test_user_1_name )
@@ -72,9 +94,14 @@
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ),
dependency_description='Convert chars depends on the column_maker repository.' )
self.upload_file( convert_repository,
- 'repository_dependencies.xml',
- filepath=repository_dependencies_path,
- commit_message='Uploaded dependency on column' )
+ filename='repository_dependencies.xml',
+ filepath=repository_dependencies_path,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded dependency on column_maker.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0030_verify_repository_dependencies( self ):
'''Verify that each repository can depend on the other without causing an infinite loop.'''
convert_repository = test_db_util.get_repository_by_name_and_owner( convert_repository_name, common.test_user_1_name )
diff -r dde899d789b698f29269e521d2abc8a1f1373921 -r 3ffe47cea647ae61a02d74bbff68e0e07bff70e4 test/tool_shed/functional/test_0090_tool_search.py
--- a/test/tool_shed/functional/test_0090_tool_search.py
+++ b/test/tool_shed/functional/test_0090_tool_search.py
@@ -54,9 +54,14 @@
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
self.upload_file( repository,
- 'bwa/bwa_base.tar',
+ filename='bwa/bwa_base.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded BWA tarball.',
strings_displayed=[],
- commit_message='Uploaded bwa_base.tar.' )
+ strings_not_displayed=[] )
def test_0010_create_bwa_color_repository( self ):
'''Create and populate bwa_color_0090.'''
category = self.create_category( name=category_name, description=category_description )
@@ -69,9 +74,14 @@
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
self.upload_file( repository,
- 'bwa/bwa_color.tar',
+ filename='bwa/bwa_color.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded BWA color tarball.',
strings_displayed=[],
- commit_message='Uploaded bwa_color.tar.' )
+ strings_not_displayed=[] )
def test_0015_create_emboss_datatypes_repository( self ):
'''Create and populate emboss_datatypes_0090.'''
category = self.create_category( name=category_name, description=category_description )
@@ -84,9 +94,14 @@
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
self.upload_file( repository,
- 'emboss/datatypes/datatypes_conf.xml',
+ filename='emboss/datatypes/datatypes_conf.xml',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded datatypes_conf.xml.',
strings_displayed=[],
- commit_message='Uploaded datatypes_conf.xml.' )
+ strings_not_displayed=[] )
def test_0020_create_emboss_repository( self ):
'''Create and populate emboss_0090.'''
category = self.create_category( name=category_name, description=category_description )
@@ -97,18 +112,28 @@
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
self.upload_file( repository,
- 'emboss/emboss.tar',
+ filename='emboss/emboss.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded emboss tarball.',
strings_displayed=[],
- commit_message='Uploaded tool tarball.' )
+ strings_not_displayed=[] )
datatypes_repository = test_db_util.get_repository_by_name_and_owner( emboss_datatypes_repository_name, common.test_user_1_name )
repository_dependencies_path = self.generate_temp_path( 'test_0090', additional_paths=[ 'emboss' ] )
self.generate_repository_dependency_xml( [ datatypes_repository ],
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ),
dependency_description='Emboss depends on the emboss_datatypes repository.' )
self.upload_file( repository,
- 'repository_dependencies.xml',
- filepath=repository_dependencies_path,
- commit_message='Uploaded dependency on emboss_datatypes.' )
+ filename='repository_dependencies.xml',
+ filepath=repository_dependencies_path,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded dependency on emboss_datatypes.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0025_create_filtering_repository( self ):
'''Create and populate filtering_0090.'''
category = self.create_category( name=category_name, description=category_description )
@@ -119,18 +144,28 @@
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
self.upload_file( filtering_repository,
- 'filtering/filtering_1.1.0.tar',
+ filename='filtering/filtering_1.1.0.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded filtering 1.1.0 tarball.',
strings_displayed=[],
- commit_message='Uploaded filtering.tar.' )
+ strings_not_displayed=[] )
emboss_repository = test_db_util.get_repository_by_name_and_owner( emboss_repository_name, common.test_user_1_name )
repository_dependencies_path = self.generate_temp_path( 'test_0090', additional_paths=[ 'filtering' ] )
self.generate_repository_dependency_xml( [ emboss_repository ],
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ),
dependency_description='Filtering depends on the emboss repository.' )
self.upload_file( filtering_repository,
- 'repository_dependencies.xml',
- filepath=repository_dependencies_path,
- commit_message='Uploaded dependency on emboss.' )
+ filename='repository_dependencies.xml',
+ filepath=repository_dependencies_path,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded dependency on emboss.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0030_create_freebayes_repository( self ):
'''Create and populate freebayes_0090.'''
category = self.create_category( name=category_name, description=category_description )
@@ -141,9 +176,14 @@
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
self.upload_file( repository,
- 'freebayes/freebayes.tar',
+ filename='freebayes/freebayes.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded freebayes tarball.',
strings_displayed=[],
- commit_message='Uploaded freebayes.tar.' )
+ strings_not_displayed=[] )
def test_0035_create_and_upload_dependency_definitions( self ):
'''Create and upload repository dependency definitions.'''
bwa_color_repository = test_db_util.get_repository_by_name_and_owner( bwa_color_repository_name, common.test_user_1_name )
diff -r dde899d789b698f29269e521d2abc8a1f1373921 -r 3ffe47cea647ae61a02d74bbff68e0e07bff70e4 test/tool_shed/functional/test_0100_complex_repository_dependencies.py
--- a/test/tool_shed/functional/test_0100_complex_repository_dependencies.py
+++ b/test/tool_shed/functional/test_0100_complex_repository_dependencies.py
@@ -38,9 +38,14 @@
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
self.upload_file( repository,
- 'bwa/complex/tool_dependencies.xml',
+ filename='bwa/complex/tool_dependencies.xml',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded tool_dependencies.xml.',
strings_displayed=[ 'Name, version and type from a tool requirement tag does not match' ],
- commit_message='Uploaded tool_dependencies.xml.' )
+ strings_not_displayed=[] )
self.display_manage_repository_page( repository, strings_displayed=[ 'Tool dependencies', 'may not be', 'in this repository' ] )
def test_0010_create_bwa_base_repository( self ):
'''Create and populate bwa_base_0100.'''
@@ -55,9 +60,14 @@
strings_displayed=[] )
tool_repository = test_db_util.get_repository_by_name_and_owner( bwa_tool_repository_name, common.test_user_1_name )
self.upload_file( repository,
- 'bwa/complex/bwa_base.tar',
+ filename='bwa/complex/bwa_base.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded bwa_base.tar with tool wrapper XML, but without tool dependency XML.',
strings_displayed=[],
- commit_message='Uploaded bwa_base.tar with tool wrapper XML, but without tool dependency XML.' )
+ strings_not_displayed=[] )
def test_0015_generate_complex_repository_dependency_invalid_shed_url( self ):
'''Generate and upload a complex repository definition that specifies an invalid tool shed URL.'''
dependency_path = self.generate_temp_path( 'test_0100', additional_paths=[ 'complex', 'invalid' ] )
@@ -71,34 +81,40 @@
self.generate_invalid_dependency_xml( xml_filename, url, name, owner, changeset_revision, complex=True, package='bwa', version='0.5.9' )
strings_displayed = [ 'Invalid tool shed <b>%s</b> defined' % url ]
self.upload_file( repository,
- 'tool_dependencies.xml',
+ filename='tool_dependencies.xml',
+ filepath=dependency_path,
valid_tools_only=False,
- filepath=dependency_path,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
commit_message='Uploaded dependency on bwa_tool_0100 with invalid url.',
- strings_displayed=strings_displayed )
+ strings_displayed=strings_displayed,
+ strings_not_displayed=[] )
def test_0020_generate_complex_repository_dependency_invalid_repository_name( self ):
'''Generate and upload a complex repository definition that specifies an invalid repository name.'''
dependency_path = self.generate_temp_path( 'test_0100', additional_paths=[ 'complex', 'invalid' ] )
xml_filename = self.get_filename( 'tool_dependencies.xml', filepath=dependency_path )
- repository = test_db_util.get_repository_by_name_and_owner( bwa_base_repository_name, common.test_user_1_name )
+ base_repository = test_db_util.get_repository_by_name_and_owner( bwa_base_repository_name, common.test_user_1_name )
tool_repository = test_db_util.get_repository_by_name_and_owner( bwa_tool_repository_name, common.test_user_1_name )
url = self.url
name = 'invalid_repository!?'
owner = tool_repository.user.username
changeset_revision = self.get_repository_tip( tool_repository )
self.generate_invalid_dependency_xml( xml_filename, url, name, owner, changeset_revision, complex=True, package='bwa', version='0.5.9' )
- strings_displayed = 'Invalid repository name <b>%s</b> defined.' % name
- self.upload_file( repository,
- 'tool_dependencies.xml',
+ strings_displayed = [ 'Invalid repository name <b>%s</b> defined.' % name ]
+ self.upload_file( base_repository,
+ filename='tool_dependencies.xml',
+ filepath=dependency_path,
valid_tools_only=False,
- filepath=dependency_path,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
commit_message='Uploaded dependency on bwa_tool_0100 with invalid repository name.',
- strings_displayed=[ strings_displayed ] )
+ strings_displayed=strings_displayed,
+ strings_not_displayed=[] )
def test_0025_generate_complex_repository_dependency_invalid_owner_name( self ):
'''Generate and upload a complex repository definition that specifies an invalid owner.'''
dependency_path = self.generate_temp_path( 'test_0100', additional_paths=[ 'complex', 'invalid' ] )
xml_filename = self.get_filename( 'tool_dependencies.xml', filepath=dependency_path )
- repository = test_db_util.get_repository_by_name_and_owner( bwa_base_repository_name, common.test_user_1_name )
+ base_repository = test_db_util.get_repository_by_name_and_owner( bwa_base_repository_name, common.test_user_1_name )
tool_repository = test_db_util.get_repository_by_name_and_owner( bwa_tool_repository_name, common.test_user_1_name )
url = self.url
name = tool_repository.name
@@ -106,30 +122,36 @@
changeset_revision = self.get_repository_tip( tool_repository )
self.generate_invalid_dependency_xml( xml_filename, url, name, owner, changeset_revision, complex=True, package='bwa', version='0.5.9' )
strings_displayed = [ 'Invalid owner <b>%s</b> defined' % owner ]
- self.upload_file( repository,
- 'tool_dependencies.xml',
+ self.upload_file( base_repository,
+ filename='tool_dependencies.xml',
+ filepath=dependency_path,
valid_tools_only=False,
- filepath=dependency_path,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
commit_message='Uploaded dependency on bwa_tool_0100 with invalid owner.',
- strings_displayed=strings_displayed )
+ strings_displayed=strings_displayed,
+ strings_not_displayed=[] )
def test_0030_generate_complex_repository_dependency_invalid_changeset_revision( self ):
'''Generate and upload a complex repository definition that specifies an invalid changeset revision.'''
dependency_path = self.generate_temp_path( 'test_0100', additional_paths=[ 'complex', 'invalid' ] )
xml_filename = self.get_filename( 'tool_dependencies.xml', filepath=dependency_path )
- repository = test_db_util.get_repository_by_name_and_owner( bwa_base_repository_name, common.test_user_1_name )
+ base_repository = test_db_util.get_repository_by_name_and_owner( bwa_base_repository_name, common.test_user_1_name )
tool_repository = test_db_util.get_repository_by_name_and_owner( bwa_tool_repository_name, common.test_user_1_name )
url = self.url
name = tool_repository.name
owner = tool_repository.user.username
changeset_revision = '1234abcd'
self.generate_invalid_dependency_xml( xml_filename, url, name, owner, changeset_revision, complex=True, package='bwa', version='0.5.9' )
- strings_displayed = 'Invalid changeset revision <b>%s</b> defined.' % changeset_revision
- self.upload_file( repository,
- 'tool_dependencies.xml',
+ strings_displayed = [ 'Invalid changeset revision <b>%s</b> defined.' % changeset_revision ]
+ self.upload_file( base_repository,
+ filename='tool_dependencies.xml',
+ filepath=dependency_path,
valid_tools_only=False,
- filepath=dependency_path,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
commit_message='Uploaded dependency on bwa_tool_0100 with invalid changeset revision.',
- strings_displayed=[ strings_displayed ] )
+ strings_displayed=strings_displayed,
+ strings_not_displayed=[] )
def test_0035_generate_complex_repository_dependency( self ):
'''Generate and upload a valid tool_dependencies.xml file that specifies bwa_tool_repository_0100.'''
base_repository = test_db_util.get_repository_by_name_and_owner( bwa_base_repository_name, common.test_user_1_name )
@@ -142,10 +164,14 @@
changeset_revision = self.get_repository_tip( tool_repository )
self.generate_repository_dependency_xml( [ tool_repository ], xml_filename, complex=True, package='bwa', version='0.5.9' )
self.upload_file( base_repository,
- 'tool_dependencies.xml',
+ filename='tool_dependencies.xml',
+ filepath=dependency_path,
valid_tools_only=True,
- filepath=dependency_path,
- commit_message='Uploaded valid complex dependency on bwa_tool_0100.' )
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded valid complex dependency on bwa_tool_0100.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
self.check_repository_dependency( base_repository, tool_repository )
self.display_manage_repository_page( base_repository, strings_displayed=[ 'bwa', '0.5.9', 'package' ] )
def test_0040_generate_tool_dependency( self ):
@@ -160,10 +186,14 @@
file( xml_filename, 'w' ).write( file( old_tool_dependency, 'r' )
.read().replace( '__PATH__', self.get_filename( 'bwa/complex' ) ) )
self.upload_file( tool_repository,
- xml_filename,
+ filename=xml_filename,
filepath=new_tool_dependency_path,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded new tool_dependencies.xml.',
strings_displayed=[],
- commit_message='Uploaded new tool_dependencies.xml.' )
+ strings_not_displayed=[] )
# Verify that the dependency display has been updated as a result of the new tool_dependencies.xml file.
self.display_manage_repository_page( base_repository,
strings_displayed=[ self.get_repository_tip( tool_repository ), 'bwa', '0.5.9', 'package' ],
diff -r dde899d789b698f29269e521d2abc8a1f1373921 -r 3ffe47cea647ae61a02d74bbff68e0e07bff70e4 test/tool_shed/functional/test_0110_invalid_simple_repository_dependencies.py
--- a/test/tool_shed/functional/test_0110_invalid_simple_repository_dependencies.py
+++ b/test/tool_shed/functional/test_0110_invalid_simple_repository_dependencies.py
@@ -40,7 +40,15 @@
owner=common.test_user_1_name,
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
- self.upload_file( repository, 'emboss/datatypes/datatypes_conf.xml', commit_message='Uploaded datatypes_conf.xml.' )
+ self.upload_file( repository,
+ filename='emboss/datatypes/datatypes_conf.xml',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded datatypes_conf.xml.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0015_verify_datatypes_in_datatypes_repository( self ):
'''Verify that the emboss_datatypes repository contains datatype entries.'''
repository = test_db_util.get_repository_by_name_and_owner( datatypes_repository_name, common.test_user_1_name )
@@ -54,7 +62,15 @@
owner=common.test_user_1_name,
category_id=self.security.encode_id( category.id ),
strings_displayed=[] )
- self.upload_file( repository, 'emboss/emboss.tar', commit_message='Uploaded emboss_5.tar' )
+ self.upload_file( repository,
+ filename='emboss/emboss.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded emboss tool tarball.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0025_generate_repository_dependency_with_invalid_url( self ):
'''Generate a repository dependency for emboss 5 with an invalid URL.'''
dependency_path = self.generate_temp_path( 'test_0110', additional_paths=[ 'simple' ] )
@@ -68,11 +84,14 @@
self.generate_invalid_dependency_xml( xml_filename, url, name, owner, changeset_revision, complex=False, description='This is invalid.' )
strings_displayed = [ 'Invalid tool shed <b>%s</b> defined for repository <b>%s</b>' % ( url, repository.name ) ]
self.upload_file( emboss_repository,
- 'repository_dependencies.xml',
+ filename='repository_dependencies.xml',
+ filepath=dependency_path,
valid_tools_only=False,
- filepath=dependency_path,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
commit_message='Uploaded dependency on emboss_datatypes_0110 with invalid url.',
- strings_displayed=strings_displayed )
+ strings_displayed=strings_displayed,
+ strings_not_displayed=[] )
def test_0030_generate_repository_dependency_with_invalid_name( self ):
'''Generate a repository dependency for emboss 5 with an invalid name.'''
dependency_path = self.generate_temp_path( 'test_0110', additional_paths=[ 'simple' ] )
@@ -86,11 +105,14 @@
self.generate_invalid_dependency_xml( xml_filename, url, name, owner, changeset_revision, complex=False, description='This is invalid.' )
strings_displayed = [ 'Invalid repository name <b>%s</b> defined.' % name ]
self.upload_file( emboss_repository,
- 'repository_dependencies.xml',
+ filename='repository_dependencies.xml',
+ filepath=dependency_path,
valid_tools_only=False,
- filepath=dependency_path,
- commit_message='Uploaded dependency on emboss_datatypes_0110 with invalid url.',
- strings_displayed=strings_displayed )
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded dependency on emboss_datatypes_0110 with invalid name.',
+ strings_displayed=strings_displayed,
+ strings_not_displayed=[] )
def test_0035_generate_repository_dependency_with_invalid_owner( self ):
'''Generate a repository dependency for emboss 5 with an invalid owner.'''
dependency_path = self.generate_temp_path( 'test_0110', additional_paths=[ 'simple' ] )
@@ -104,11 +126,14 @@
self.generate_invalid_dependency_xml( xml_filename, url, name, owner, changeset_revision, complex=False, description='This is invalid.' )
strings_displayed = [ 'Invalid owner <b>%s</b> defined for repository <b>%s</b>' % ( owner, repository.name ) ]
self.upload_file( emboss_repository,
- 'repository_dependencies.xml',
+ filename='repository_dependencies.xml',
+ filepath=dependency_path,
valid_tools_only=False,
- filepath=dependency_path,
- commit_message='Uploaded dependency on emboss_datatypes_0110 with invalid url.',
- strings_displayed=strings_displayed )
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded dependency on emboss_datatypes_0110 with invalid owner.',
+ strings_displayed=strings_displayed,
+ strings_not_displayed=[] )
def test_0040_generate_repository_dependency_with_invalid_changeset_revision( self ):
'''Generate a repository dependency for emboss 5 with an invalid changeset revision.'''
dependency_path = self.generate_temp_path( 'test_0110', additional_paths=[ 'simple', 'invalid' ] )
@@ -122,8 +147,11 @@
self.generate_invalid_dependency_xml( xml_filename, url, name, owner, changeset_revision, complex=False, description='This is invalid.' )
strings_displayed = [ 'Invalid changeset revision <b>%s</b> defined.' % changeset_revision ]
self.upload_file( emboss_repository,
- 'repository_dependencies.xml',
+ filename='repository_dependencies.xml',
+ filepath=dependency_path,
valid_tools_only=False,
- filepath=dependency_path,
- commit_message='Uploaded dependency on emboss_datatypes_0110 with invalid url.',
- strings_displayed=strings_displayed )
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded dependency on emboss_datatypes_0110 with invalid changeset revision.',
+ strings_displayed=strings_displayed,
+ strings_not_displayed=[] )
diff -r dde899d789b698f29269e521d2abc8a1f1373921 -r 3ffe47cea647ae61a02d74bbff68e0e07bff70e4 test/tool_shed/functional/test_0300_reset_all_metadata.py
--- a/test/tool_shed/functional/test_0300_reset_all_metadata.py
+++ b/test/tool_shed/functional/test_0300_reset_all_metadata.py
@@ -23,15 +23,12 @@
admin_user = test_db_util.get_user( common.admin_email )
assert admin_user is not None, 'Problem retrieving user with email %s from the database' % admin_email
admin_user_private_role = test_db_util.get_private_role( admin_user )
- def test_0005_create_repositories_and_categories( self ):
+ def test_0005_create_filtering_repository( self ):
+ '''Create and populate the filtering_0000 repository.'''
+ self.logout()
+ self.login( email=common.admin_email, username=common.admin_username )
category_0000 = self.create_category( name='Test 0000 Basic Repository Features 1', description='Test 0000 Basic Repository Features 1' )
category_0001 = self.create_category( name='Test 0000 Basic Repository Features 2', description='Test 0000 Basic Repository Features 2' )
- category_0010 = self.create_category( name='Test 0010 Repository With Tool Dependencies', description='Tests for a repository with tool dependencies.' )
- category_0020 = self.create_category( name='Test 0020 Basic Repository Dependencies', description='Testing basic repository dependency features.' )
- category_0030 = self.create_category( name='Test 0030 Repository Dependency Revisions', description='Testing repository dependencies by revision.' )
- category_0040 = self.create_category( name='test_0040_repository_circular_dependencies', description='Testing handling of circular repository dependencies.' )
- category_0050 = self.create_category( name='test_0050_repository_n_level_circular_dependencies', description='Testing handling of circular repository dependencies to n levels.' )
- category_0060 = self.create_category( name='Test 0060 Workflow Features', description='Test 0060 - Workflow Features' )
self.logout()
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
repository = self.get_or_create_repository( name='filtering_0000',
@@ -40,34 +37,119 @@
owner=common.test_user_1_name,
category_id=self.security.encode_id( category_0000.id ) )
if self.repository_is_new( repository ):
- self.upload_file( repository, 'filtering/filtering_1.1.0.tar', commit_message="Uploaded filtering 1.1.0" )
- self.upload_file( repository, 'filtering/filtering_2.2.0.tar', commit_message="Uploaded filtering 2.2.0" )
+ self.upload_file( repository,
+ filename='filtering/filtering_1.1.0.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded filtering 1.1.0 tarball.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ self.upload_file( repository,
+ filename='filtering/filtering_2.2.0.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded filtering 2.2.0 tarball.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ def test_0010_create_freebayes_repository( self ):
+ '''Create and populate the freebayes_0010 repository.'''
+ self.logout()
+ self.login( email=common.admin_email, username=common.admin_username )
+ category_0010 = self.create_category( name='Test 0010 Repository With Tool Dependencies', description='Tests for a repository with tool dependencies.' )
+ self.logout()
+ self.login( email=common.test_user_1_email, username=common.test_user_1_name )
repository = self.get_or_create_repository( name='freebayes_0010',
description="Galaxy's freebayes tool",
long_description="Long description of Galaxy's freebayes tool",
owner=common.test_user_1_name,
- category_id=self.security.encode_id( category_0000.id ),
+ category_id=self.security.encode_id( category_0010.id ),
strings_displayed=[] )
if self.repository_is_new( repository ):
- self.upload_file( repository, 'freebayes/freebayes.xml', valid_tools_only=False, commit_message='Uploaded.', strings_displayed=[] )
- self.upload_file( repository, 'freebayes/tool_data_table_conf.xml.sample', valid_tools_only=False, commit_message='Uploaded.', strings_displayed=[] )
- self.upload_file( repository, 'freebayes/sam_fa_indices.loc.sample', valid_tools_only=False, commit_message='Uploaded.', strings_displayed=[] )
- self.upload_file( repository, 'freebayes/tool_dependencies.xml', commit_message='Uploaded.' )
+ self.upload_file( repository,
+ filename='freebayes/freebayes.xml',
+ filepath=None,
+ valid_tools_only=False,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded freebayes.xml.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ self.upload_file( repository,
+ filename='freebayes/tool_data_table_conf.xml.sample',
+ filepath=None,
+ valid_tools_only=False,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded tool_data_table_conf.xml.sample',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ self.upload_file( repository,
+ filename='freebayes/sam_fa_indices.loc.sample',
+ filepath=None,
+ valid_tools_only=False,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded sam_fa_indices.loc.sample',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ self.upload_file( repository,
+ filename='freebayes/tool_dependencies.xml',
+ filepath=None,
+ valid_tools_only=False,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded tool_dependencies.xml',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ def test_0015_create_emboss_repository( self ):
+ '''Create and populate the emboss_0020 repository.'''
+ self.logout()
+ self.login( email=common.admin_email, username=common.admin_username )
+ category_0020 = self.create_category( name='Test 0020 Basic Repository Dependencies', description='Testing basic repository dependency features.' )
+ self.logout()
+ self.login( email=common.test_user_1_email, username=common.test_user_1_name )
repository = self.get_or_create_repository( name='emboss_datatypes_0020',
description="Galaxy applicable data formats used by Emboss tools.",
long_description="Galaxy applicable data formats used by Emboss tools. This repository contains no tools.",
owner=common.test_user_1_name,
- category_id=self.security.encode_id( category_0010.id ),
+ category_id=self.security.encode_id( category_0020.id ),
strings_displayed=[] )
if self.repository_is_new( repository ):
- self.upload_file( repository, 'emboss/datatypes/datatypes_conf.xml', commit_message='Uploaded datatypes_conf.xml.' )
+ self.upload_file( repository,
+ filename='emboss/datatypes/datatypes_conf.xml',
+ filepath=None,
+ valid_tools_only=False,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded datatypes_conf.xml.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
repository = self.get_or_create_repository( name='emboss_0020',
description='Galaxy wrappers for Emboss version 5.0.0 tools',
long_description='Galaxy wrappers for Emboss version 5.0.0 tools',
owner=common.test_user_1_name,
category_id=self.security.encode_id( category_0020.id ),
strings_displayed=[] )
- self.upload_file( repository, 'emboss/emboss.tar', commit_message='Uploaded emboss_5.tar' )
+ self.upload_file( repository,
+ filename='emboss/emboss.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded emboss.tar',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ def test_0020_create_emboss_datatypes_repository( self ):
+ '''Create and populate the emboss_0030 repository.'''
+ self.logout()
+ self.login( email=common.admin_email, username=common.admin_username )
+ category_0030 = self.create_category( name='Test 0030 Repository Dependency Revisions', description='Testing repository dependencies by revision.' )
+ self.logout()
+ self.login( email=common.test_user_1_email, username=common.test_user_1_name )
datatypes_repository = self.get_or_create_repository( name='emboss_datatypes_0030',
description=datatypes_repository_description,
long_description=datatypes_repository_long_description,
@@ -75,55 +157,114 @@
category_id=self.security.encode_id( category_0030.id ),
strings_displayed=[] )
if self.repository_is_new( datatypes_repository ):
- self.upload_file( datatypes_repository, 'emboss/datatypes/datatypes_conf.xml', commit_message='Uploaded datatypes_conf.xml.' )
+ self.upload_file( datatypes_repository,
+ filename='emboss/datatypes/datatypes_conf.xml',
+ filepath=None,
+ valid_tools_only=False,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded datatypes_conf.xml.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
emboss_5_repository = self.get_or_create_repository( name='emboss_5_0030',
description=emboss_repository_description,
long_description=emboss_repository_long_description,
owner=common.test_user_1_name,
category_id=self.security.encode_id( category_0030.id ),
strings_displayed=[] )
- self.upload_file( emboss_5_repository, 'emboss/emboss.tar', commit_message='Uploaded emboss.tar' )
+ self.upload_file( emboss_5_repository,
+ filename='emboss/emboss.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded emboss.tar',
+ strings_displayed=[],
+ strings_not_displayed=[] )
repository_dependencies_path = self.generate_temp_path( 'test_0330', additional_paths=[ 'emboss', '5' ] )
self.generate_repository_dependency_xml( [ datatypes_repository ],
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ) )
self.upload_file( emboss_5_repository,
- 'repository_dependencies.xml',
+ filename='repository_dependencies.xml',
filepath=repository_dependencies_path,
- commit_message='Uploaded repository_dependencies.xml' )
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded repository_dependencies.xml',
+ strings_displayed=[],
+ strings_not_displayed=[] )
emboss_6_repository = self.get_or_create_repository( name='emboss_6_0030',
description=emboss_repository_description,
long_description=emboss_repository_long_description,
owner=common.test_user_1_name,
category_id=self.security.encode_id( category_0030.id ),
strings_displayed=[] )
- self.upload_file( emboss_6_repository, 'emboss/emboss.tar', commit_message='Uploaded emboss.tar' )
+ self.upload_file( emboss_6_repository,
+ filename='emboss/emboss.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded emboss.tar',
+ strings_displayed=[],
+ strings_not_displayed=[] )
repository_dependencies_path = self.generate_temp_path( 'test_0330', additional_paths=[ 'emboss', '6' ] )
self.generate_repository_dependency_xml( [ datatypes_repository ],
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ) )
self.upload_file( emboss_6_repository,
- 'repository_dependencies.xml',
+ filename='repository_dependencies.xml',
filepath=repository_dependencies_path,
- commit_message='Uploaded repository_dependencies.xml' )
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded repository_dependencies.xml',
+ strings_displayed=[],
+ strings_not_displayed=[] )
emboss_repository = self.get_or_create_repository( name='emboss_0030',
description=emboss_repository_description,
long_description=emboss_repository_long_description,
owner=common.test_user_1_name,
category_id=self.security.encode_id( category_0030.id ),
strings_displayed=[] )
- self.upload_file( emboss_repository, 'emboss/emboss.tar', commit_message='Uploaded emboss.tar' )
+ self.upload_file( emboss_repository,
+ filename='emboss/emboss.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded emboss.tar',
+ strings_displayed=[],
+ strings_not_displayed=[] )
repository_dependencies_path = self.generate_temp_path( 'test_0330', additional_paths=[ 'emboss', '5' ] )
self.generate_repository_dependency_xml( [ emboss_5_repository ],
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ) )
self.upload_file( emboss_repository,
- 'repository_dependencies.xml',
+ filename='repository_dependencies.xml',
filepath=repository_dependencies_path,
- commit_message='Uploaded repository_dependencies.xml' )
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded repository_dependencies.xml',
+ strings_displayed=[],
+ strings_not_displayed=[] )
self.generate_repository_dependency_xml( [ emboss_6_repository ],
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ) )
self.upload_file( emboss_repository,
- 'repository_dependencies.xml',
+ filename='repository_dependencies.xml',
filepath=repository_dependencies_path,
- commit_message='Uploaded repository_dependencies.xml' )
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded repository_dependencies.xml',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ def test_0025_create_freebayes_repository( self ):
+ '''Create and populate the freebayes_0040 repository.'''
+ self.logout()
+ self.login( email=common.admin_email, username=common.admin_username )
+ category_0040 = self.create_category( name='test_0040_repository_circular_dependencies', description='Testing handling of circular repository dependencies.' )
+ self.logout()
+ self.login( email=common.test_user_1_email, username=common.test_user_1_name )
repository = self.get_or_create_repository( name='freebayes_0040',
description="Galaxy's freebayes tool",
long_description="Long description of Galaxy's freebayes tool",
@@ -131,14 +272,30 @@
category_id=self.security.encode_id( category_0040.id ),
strings_displayed=[] )
if self.repository_is_new( repository ):
- self.upload_file( repository, 'freebayes/freebayes.tar', commit_message='Uploaded freebayes.tar.' )
+ self.upload_file( repository,
+ filename='freebayes/freebayes.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded freebayes tarball.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
repository = self.get_or_create_repository( name='filtering_0040',
description="Galaxy's filtering tool",
long_description="Long description of Galaxy's filtering tool",
owner=common.test_user_1_name,
category_id=self.security.encode_id( category_0040.id ),
strings_displayed=[] )
- self.upload_file( repository, 'filtering/filtering_1.1.0.tar', commit_message='Uploaded filtering.tar.' )
+ self.upload_file( repository,
+ filename='filtering/filtering_1.1.0.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded filtering 1.1.0 tarball.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
freebayes_repository = test_db_util.get_repository_by_name_and_owner( 'freebayes_0040', common.test_user_1_name )
filtering_repository = test_db_util.get_repository_by_name_and_owner( 'filtering_0040', common.test_user_1_name )
repository_dependencies_path = self.generate_temp_path( 'test_0340', additional_paths=[ 'dependencies' ] )
@@ -146,16 +303,33 @@
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ),
dependency_description='Filtering 1.1.0 depends on the freebayes repository.' )
self.upload_file( filtering_repository,
- 'repository_dependencies.xml',
+ filename='repository_dependencies.xml',
filepath=repository_dependencies_path,
- commit_message='Uploaded dependency on freebayes' )
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded repository_dependencies.xml specifying freebayes',
+ strings_displayed=[],
+ strings_not_displayed=[] )
self.generate_repository_dependency_xml( [ filtering_repository ],
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ),
dependency_description='Freebayes depends on the filtering repository.' )
self.upload_file( freebayes_repository,
- 'repository_dependencies.xml',
+ filename='repository_dependencies.xml',
filepath=repository_dependencies_path,
- commit_message='Uploaded dependency on filtering' )
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded repository_dependencies.xml specifying filtering',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ def test_0030_create_emboss_repository( self ):
+ '''Create and populate the emboss_0050 repository.'''
+ self.logout()
+ self.login( email=common.admin_email, username=common.admin_username )
+ category_0050 = self.create_category( name='test_0050_repository_n_level_circular_dependencies', description='Testing handling of circular repository dependencies to n levels.' )
+ self.logout()
+ self.login( email=common.test_user_1_email, username=common.test_user_1_name )
datatypes_repository = self.get_or_create_repository( name='emboss_datatypes_0050',
description="Datatypes for emboss",
long_description="Long description of Emboss' datatypes",
@@ -181,41 +355,100 @@
owner=common.test_user_1_name,
category_id=self.security.encode_id( category_0050.id ),
strings_displayed=[] )
- self.upload_file( datatypes_repository, 'emboss/datatypes/datatypes_conf.xml', commit_message='Uploaded datatypes_conf.xml.' )
- self.upload_file( emboss_repository, 'emboss/emboss.tar', commit_message='Uploaded tool tarball.' )
- self.upload_file( freebayes_repository, 'freebayes/freebayes.tar', commit_message='Uploaded freebayes.tar.' )
- self.upload_file( filtering_repository, 'filtering/filtering_1.1.0.tar', commit_message='Uploaded filtering.tar.' )
+ self.upload_file( datatypes_repository,
+ filename='emboss/datatypes/datatypes_conf.xml',
+ filepath=None,
+ valid_tools_only=False,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded datatypes_conf.xml.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ self.upload_file( emboss_repository,
+ filename='emboss/emboss.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded emboss.tar',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ self.upload_file( freebayes_repository,
+ filename='freebayes/freebayes.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded freebayes tarball.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ self.upload_file( filtering_repository,
+ filename='filtering/filtering_1.1.0.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded filtering 1.1.0 tarball.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
repository_dependencies_path = self.generate_temp_path( 'test_0350', additional_paths=[ 'emboss' ] )
self.generate_repository_dependency_xml( [ datatypes_repository ],
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ),
dependency_description='Emboss depends on the emboss_datatypes repository.' )
self.upload_file( emboss_repository,
- 'repository_dependencies.xml',
+ filename='repository_dependencies.xml',
filepath=repository_dependencies_path,
- commit_message='Uploaded dependency on emboss_datatypes.' )
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded repository_dependencies.xml',
+ strings_displayed=[],
+ strings_not_displayed=[] )
repository_dependencies_path = self.generate_temp_path( 'test_0350', additional_paths=[ 'filtering' ] )
self.generate_repository_dependency_xml( [ emboss_repository ],
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ),
dependency_description='Filtering depends on the emboss repository.' )
self.upload_file( filtering_repository,
- 'repository_dependencies.xml',
+ filename='repository_dependencies.xml',
filepath=repository_dependencies_path,
- commit_message='Uploaded dependency on emboss.' )
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded repository_dependencies.xml',
+ strings_displayed=[],
+ strings_not_displayed=[] )
repository_dependencies_path = self.generate_temp_path( 'test_0350', additional_paths=[ 'freebayes' ] )
self.generate_repository_dependency_xml( [ filtering_repository ],
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ),
dependency_description='Emboss depends on the filtering repository.' )
self.upload_file( emboss_repository,
- 'repository_dependencies.xml',
+ filename='repository_dependencies.xml',
filepath=repository_dependencies_path,
- commit_message='Uploaded dependency on filtering.' )
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded repository_dependencies.xml',
+ strings_displayed=[],
+ strings_not_displayed=[] )
self.generate_repository_dependency_xml( [ datatypes_repository, emboss_repository, filtering_repository, freebayes_repository ],
self.get_filename( 'repository_dependencies.xml', filepath=repository_dependencies_path ),
dependency_description='Freebayes depends on the filtering repository.' )
self.upload_file( freebayes_repository,
- 'repository_dependencies.xml',
+ filename='repository_dependencies.xml',
filepath=repository_dependencies_path,
- commit_message='Uploaded dependency on filtering.' )
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded repository_dependencies.xml',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ def test_0035_create_filtering_repository( self ):
+ '''Create and populate the filtering_0060 repository.'''
+ self.logout()
+ self.login( email=common.admin_email, username=common.admin_username )
+ category_0060 = self.create_category( name='Test 0060 Workflow Features', description='Test 0060 - Workflow Features' )
+ self.logout()
+ self.login( email=common.test_user_1_email, username=common.test_user_1_name )
workflow_repository = self.get_or_create_repository( name='filtering_0060',
description="Galaxy's filtering tool",
long_description="Long description of Galaxy's filtering tool",
@@ -226,16 +459,28 @@
workflow = file( self.get_filename( 'filtering_workflow/Workflow_for_0060_filter_workflow_repository.ga' ), 'r' ).read()
workflow = workflow.replace( '__TEST_TOOL_SHED_URL__', self.url.replace( 'http://', '' ) )
workflow_filepath = self.generate_temp_path( 'test_0360', additional_paths=[ 'filtering_workflow' ] )
- os.makedirs( workflow_filepath )
+ if not os.path.exists( workflow_filepath ):
+ os.makedirs( workflow_filepath )
file( os.path.join( workflow_filepath, workflow_filename ), 'w+' ).write( workflow )
self.upload_file( workflow_repository,
- workflow_filename,
+ filename=workflow_filename,
filepath=workflow_filepath,
- commit_message='Uploaded filtering workflow.' )
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded filtering workflow.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
self.upload_file( workflow_repository,
- 'filtering/filtering_2.2.0.tar',
- commit_message='Uploaded filtering tool.' )
- def test_0010_reset_metadata_on_all_repositories( self ):
+ filename='filtering/filtering_2.2.0.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded filtering 2.2.0 tarball.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ def test_0040_reset_metadata_on_all_repositories( self ):
'''Reset metadata on all repositories, then verify that it has not changed.'''
self.logout()
self.login( email=common.admin_email, username=common.admin_username )
diff -r dde899d789b698f29269e521d2abc8a1f1373921 -r 3ffe47cea647ae61a02d74bbff68e0e07bff70e4 test/tool_shed/functional/test_0400_repository_component_reviews.py
--- a/test/tool_shed/functional/test_0400_repository_component_reviews.py
+++ b/test/tool_shed/functional/test_0400_repository_component_reviews.py
@@ -100,7 +100,15 @@
owner=common.test_user_1_name,
category_id=self.security.encode_id( category.id ),
strings_displayed=strings_displayed )
- self.upload_file( repository, 'filtering/filtering_1.1.0.tar', commit_message="Uploaded filtering 1.1.0" )
+ self.upload_file( repository,
+ filename='filtering/filtering_1.1.0.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded filtering 1.1.0 tarball.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0020_review_initial_revision_data_types( self ):
'''Review the datatypes component for the current tip revision.'''
"""
@@ -396,7 +404,15 @@
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
user = test_db_util.get_user( common.test_user_2_email )
- self.upload_file( repository, 'readme.txt', commit_message="Uploaded readme.txt" )
+ self.upload_file( repository,
+ filename='readme.txt',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded readme.txt.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0095_review_new_changeset_readme_component( self ):
'''Update the filtering repository's readme component review to reflect the presence of the readme file.'''
"""
@@ -452,10 +468,15 @@
"""
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
user = test_db_util.get_user( common.test_user_2_email )
- self.upload_file( repository,
- 'filtering/filtering_test_data.tar',
- commit_message="Uploaded test data.",
- remove_repo_files_not_in_tar='No' )
+ self.upload_file( repository,
+ filename='filtering/filtering_test_data.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded filtering 1.1.0 tarball.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0110_review_new_changeset_functional_tests( self ):
'''Update the filtering repository's readme component review to reflect the presence of the readme file.'''
"""
@@ -509,9 +530,14 @@
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
user = test_db_util.get_user( common.test_user_2_email )
self.upload_file( repository,
- 'filtering/filtering_2.2.0.tar',
- commit_message="Uploaded filtering 2.2.0",
- remove_repo_files_not_in_tar='No' )
+ filename='filtering/filtering_2.2.0.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded filtering 2.2.0 tarball.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0125_review_new_changeset_functional_tests( self ):
'''Update the filtering repository's review to apply to the new changeset with filtering 2.2.0.'''
"""
diff -r dde899d789b698f29269e521d2abc8a1f1373921 -r 3ffe47cea647ae61a02d74bbff68e0e07bff70e4 test/tool_shed/functional/test_1000_install_basic_repository.py
--- a/test/tool_shed/functional/test_1000_install_basic_repository.py
+++ b/test/tool_shed/functional/test_1000_install_basic_repository.py
@@ -32,10 +32,42 @@
owner=common.test_user_1_name,
category_id=self.security.encode_id( category.id ) )
if self.repository_is_new( repository ):
- self.upload_file( repository, 'filtering/filtering_1.1.0.tar', commit_message="Uploaded filtering 1.1.0" )
- self.upload_file( repository, 'filtering/filtering_0000.txt', commit_message="Uploaded readme for 1.1.0", remove_repo_files_not_in_tar='No' )
- self.upload_file( repository, 'filtering/filtering_2.2.0.tar', commit_message="Uploaded filtering 2.2.0", remove_repo_files_not_in_tar='No' )
- self.upload_file( repository, 'readme.txt', commit_message="Uploaded readme for 2.2.0", remove_repo_files_not_in_tar='No' )
+ self.upload_file( repository,
+ filename='filtering/filtering_1.1.0.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded filtering 1.1.0 tarball.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ self.upload_file( repository,
+ filename='filtering/filtering_0000.txt',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded readme for 1.1.0',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ self.upload_file( repository,
+ filename='filtering/filtering_2.2.0.tar',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=True,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded filtering 2.2.0 tarball.',
+ strings_displayed=[],
+ strings_not_displayed=[] )
+ self.upload_file( repository,
+ filename='readme.txt',
+ filepath=None,
+ valid_tools_only=True,
+ uncompress_file=False,
+ remove_repo_files_not_in_tar=False,
+ commit_message='Uploaded readme for 2.2.0',
+ strings_displayed=[],
+ strings_not_displayed=[] )
def test_0010_browse_tool_sheds( self ):
"""Browse the available tool sheds in this Galaxy instance."""
self.galaxy_logout()
This diff is so big that we needed to truncate the remainder.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: greg: Fix yet another import in the Galaxy update manager.
by Bitbucket 13 Feb '13
by Bitbucket 13 Feb '13
13 Feb '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/dde899d789b6/
changeset: dde899d789b6
user: greg
date: 2013-02-13 22:35:32
summary: Fix yet another import in the Galaxy update manager.
affected #: 1 file
diff -r 29c1b1b78ea55bbcff28cd33338e2a765efb2e08 -r dde899d789b698f29269e521d2abc8a1f1373921 lib/galaxy/tool_shed/update_manager.py
--- a/lib/galaxy/tool_shed/update_manager.py
+++ b/lib/galaxy/tool_shed/update_manager.py
@@ -4,6 +4,7 @@
import threading, urllib2, logging
from galaxy.util import string_as_bool
import galaxy.util.shed_util as shed_util
+import galaxy.util.shed_util_common as suc
from galaxy.model.orm import and_
log = logging.getLogger( __name__ )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
13 Feb '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/29c1b1b78ea5/
changeset: 29c1b1b78ea5
user: greg
date: 2013-02-13 20:39:44
summary: Enhance the process for setting metadata on tool shed repositories to better accommodate recently introduced support for the repository dependecny definition and tool dependency definition Galaxy utilities.
affected #: 1 file
diff -r b6241599d1d0bbb4b9ba670bde9fbb421ef6c396 -r 29c1b1b78ea55bbcff28cd33338e2a765efb2e08 lib/galaxy/util/shed_util_common.py
--- a/lib/galaxy/util/shed_util_common.py
+++ b/lib/galaxy/util/shed_util_common.py
@@ -631,38 +631,51 @@
ancestor_tools = ancestor_metadata_dict.get( 'tools', [] )
ancestor_guids = [ tool_dict[ 'guid' ] for tool_dict in ancestor_tools ]
ancestor_guids.sort()
+ ancestor_readme_files = ancestor_metadata_dict.get( 'readme_files', [] )
ancestor_repository_dependencies_dict = ancestor_metadata_dict.get( 'repository_dependencies', {} )
ancestor_repository_dependencies = ancestor_repository_dependencies_dict.get( 'repository_dependencies', [] )
- ancestor_tool_dependencies = ancestor_metadata_dict.get( 'tool_dependencies', [] )
+ ancestor_tool_dependencies = ancestor_metadata_dict.get( 'tool_dependencies', {} )
ancestor_workflows = ancestor_metadata_dict.get( 'workflows', [] )
current_datatypes = current_metadata_dict.get( 'datatypes', [] )
current_tools = current_metadata_dict.get( 'tools', [] )
current_guids = [ tool_dict[ 'guid' ] for tool_dict in current_tools ]
current_guids.sort()
+ current_readme_files = current_metadata_dict.get( 'readme_files', [] )
current_repository_dependencies_dict = current_metadata_dict.get( 'repository_dependencies', {} )
current_repository_dependencies = current_repository_dependencies_dict.get( 'repository_dependencies', [] )
- current_tool_dependencies = current_metadata_dict.get( 'tool_dependencies', [] )
+ current_tool_dependencies = current_metadata_dict.get( 'tool_dependencies', {} )
current_workflows = current_metadata_dict.get( 'workflows', [] )
# Handle case where no metadata exists for either changeset.
no_datatypes = not ancestor_datatypes and not current_datatypes
+ no_readme_files = not ancestor_readme_files and not current_readme_files
no_repository_dependencies = not ancestor_repository_dependencies and not current_repository_dependencies
- # Note: we currently don't need to check tool_dependencies since we're checking for guids - tool_dependencies always require tools (currently).
+ # Tool dependencies can define orphan dependencies in the tool shed.
no_tool_dependencies = not ancestor_tool_dependencies and not current_tool_dependencies
no_tools = not ancestor_guids and not current_guids
no_workflows = not ancestor_workflows and not current_workflows
- if no_datatypes and no_repository_dependencies and no_tool_dependencies and no_tools and no_workflows:
+ if no_datatypes and no_readme_files and no_repository_dependencies and no_tool_dependencies and no_tools and no_workflows:
return 'no metadata'
+ # Uncomment the following if we decide that README files should affect how installable repository revisions are defined. See the NOTE in the
+ # compare_readme_files() method.
+ # readme_file_comparision = compare_readme_files( ancestor_readme_files, current_readme_files )
repository_dependency_comparison = compare_repository_dependencies( ancestor_repository_dependencies, current_repository_dependencies )
+ tool_dependency_comparison = compare_tool_dependencies( ancestor_tool_dependencies, current_tool_dependencies )
workflow_comparison = compare_workflows( ancestor_workflows, current_workflows )
datatype_comparison = compare_datatypes( ancestor_datatypes, current_datatypes )
# Handle case where all metadata is the same.
- if ancestor_guids == current_guids and repository_dependency_comparison == 'equal' and workflow_comparison == 'equal' and datatype_comparison == 'equal':
+ if ancestor_guids == current_guids and \
+ repository_dependency_comparison == 'equal' and \
+ tool_dependency_comparison == 'equal' and \
+ workflow_comparison == 'equal' and \
+ datatype_comparison == 'equal':
return 'equal'
# Handle case where ancestor metadata is a subset of current metadata.
+ # readme_file_is_subset = readme_file_comparision in [ 'equal', 'subset' ]
repository_dependency_is_subset = repository_dependency_comparison in [ 'equal', 'subset' ]
+ tool_dependency_is_subset = tool_dependency_comparison in [ 'equal', 'subset' ]
workflow_dependency_is_subset = workflow_comparison in [ 'equal', 'subset' ]
datatype_is_subset = datatype_comparison in [ 'equal', 'subset' ]
- if repository_dependency_is_subset and workflow_dependency_is_subset and datatype_is_subset:
+ if repository_dependency_is_subset and tool_dependency_is_subset and workflow_dependency_is_subset and datatype_is_subset:
is_subset = True
for guid in ancestor_guids:
if guid not in current_guids:
@@ -694,6 +707,25 @@
else:
return 'subset'
return 'not equal and not subset'
+def compare_readme_files( ancestor_readme_files, current_readme_files ):
+ """Determine if ancestor_readme_files is equal to or a subset of current_readme_files."""
+ # NOTE: Although repository README files are considered a Galaxy utility similar to tools, repository dependency definition files, etc.,
+ # we don't define installable repository revisions based on changes to README files. To understand why, consider the following scenario:
+ # 1. Upload the filtering tool to a new repository - this will result in installable revision 0.
+ # 2. Upload a README file to the repository - this will move the installable revision from revision 0 to revision 1.
+ # 3. Delete the README file from the repository - this will move the installable revision from revision 1 to revision 2.
+ # The above scenario is the current behavior, and that is why this method is not currently called. This method exists only in case we decide
+ # to change this current behavior.
+ # The lists of readme files looks something like: ["database/community_files/000/repo_2/readme.txt"]
+ if len( ancestor_readme_files ) <= len( current_readme_files ):
+ for ancestor_readme_file in ancestor_readme_files:
+ if ancestor_readme_file not in current_readme_files:
+ return 'not equal and not subset'
+ if len( ancestor_readme_files ) == len( current_readme_files ):
+ return 'equal'
+ else:
+ return 'subset'
+ return 'not equal and not subset'
def compare_repository_dependencies( ancestor_repository_dependencies, current_repository_dependencies ):
"""Determine if ancestor_repository_dependencies is the same as or a subset of current_repository_dependencies."""
# The list of repository_dependencies looks something like: [["http://localhost:9009", "emboss_datatypes", "test", "ab03a2a5f407"]].
@@ -717,6 +749,25 @@
else:
return 'subset'
return 'not equal and not subset'
+def compare_tool_dependencies( ancestor_tool_dependencies, current_tool_dependencies ):
+ """Determine if ancestor_tool_dependencies is the same as or a subset of current_tool_dependencies."""
+ # The tool_dependencies dictionary looks something like:
+ # {'bwa/0.5.9': {'readme': 'some string', 'version': '0.5.9', 'type': 'package', 'name': 'bwa'}}
+ if len( ancestor_tool_dependencies ) <= len( current_tool_dependencies ):
+ for ancestor_td_key, ancestor_requirements_dict in ancestor_tool_dependencies.items():
+ if ancestor_td_key in current_tool_dependencies:
+ # The only values that could have changed between the 2 dictionaries are the "readme" or "type" values. Changing the readme value
+ # makes no difference. Changing the type will change the installation process, but for now we'll assume it was a typo, so new metadata
+ # shouldn't be generated.
+ continue
+ else:
+ return 'not equal and not subset'
+ # At this point we know that ancestor_tool_dependencies is at least a subset of current_tool_dependencies.
+ if len( ancestor_tool_dependencies ) == len( current_tool_dependencies ):
+ return 'equal'
+ else:
+ return 'subset'
+ return 'not equal and not subset'
def compare_workflows( ancestor_workflows, current_workflows ):
"""Determine if ancestor_workflows is the same as current_workflows or if ancestor_workflows is a subset of current_workflows."""
if len( ancestor_workflows ) <= len( current_workflows ):
@@ -730,9 +781,7 @@
found_in_current = False
for current_workflow_tup in current_workflows:
current_workflow_dict = current_workflow_tup[1]
- # Assume that if the name and number of steps are euqal,
- # then the workflows are the same. Of course, this may
- # not be true...
+ # Assume that if the name and number of steps are euqal, then the workflows are the same. Of course, this may not be true...
if current_workflow_dict[ 'name' ] == ancestor_workflow_name and len( current_workflow_dict[ 'steps' ] ) == num_ancestor_workflow_steps:
found_in_current = True
break
@@ -1070,7 +1119,11 @@
else:
original_repository_metadata = None
readme_file_names = get_readme_file_names( repository.name )
- metadata_dict = { 'shed_config_filename' : shed_config_dict.get( 'config_filename' ) }
+ if app.name == 'galaxy':
+ # Shed related tool panel configs are only relevant to Galaxy.
+ metadata_dict = { 'shed_config_filename' : shed_config_dict.get( 'config_filename' ) }
+ else:
+ metadata_dict = {}
readme_files = []
invalid_file_tups = []
invalid_tool_configs = []
@@ -2862,42 +2915,158 @@
containers_dict[ 'tool_dependencies' ] = root_container
containers_dict[ 'missing_tool_dependencies' ] = None
return containers_dict
-def new_repository_dependency_metadata_required( trans, repository, metadata_dict ):
+def new_datatypes_metadata_required( trans, repository_metadata, metadata_dict ):
"""
- Compare the last saved metadata for each repository dependency in the repository with the new metadata in metadata_dict to determine if a new
- repository_metadata table record is required or if the last saved metadata record can be updated instead.
+ Compare the last saved metadata for each datatype in the repository with the new metadata in metadata_dict to determine if a new
+ repository_metadata table record is required or if the last saved metadata record can be updated for datatypes instead.
"""
- if 'repository_dependencies' in metadata_dict:
- repository_metadata = get_latest_repository_metadata( trans, repository.id )
+ # Datatypes are stored in metadata as a list of dictionaries that looks like:
+ # [{'dtype': 'galaxy.datatypes.data:Text', 'subclass': 'True', 'extension': 'acedb'}]
+ if 'datatypes' in metadata_dict:
+ current_datatypes = metadata_dict[ 'datatypes' ]
if repository_metadata:
metadata = repository_metadata.metadata
if metadata:
- if 'repository_dependencies' in metadata:
- saved_repository_dependencies = metadata[ 'repository_dependencies' ][ 'repository_dependencies' ]
- new_repository_dependencies = metadata_dict[ 'repository_dependencies' ][ 'repository_dependencies' ]
+ if 'datatypes' in metadata:
+ ancestor_datatypes = metadata[ 'datatypes' ]
# The saved metadata must be a subset of the new metadata.
- for new_repository_dependency_metadata in new_repository_dependencies:
- if new_repository_dependency_metadata not in saved_repository_dependencies:
- return True
- for saved_repository_dependency_metadata in saved_repository_dependencies:
- if saved_repository_dependency_metadata not in new_repository_dependencies:
- return True
+ datatype_comparison = compare_datatypes( ancestor_datatypes, current_datatypes )
+ if datatype_comparison == 'not equal and not subset':
+ return True
+ else:
+ return False
+ else:
+ # The new metadata includes datatypes, but the stored metadata does not, so we can update the stored metadata.
+ return False
else:
- # We have repository metadata that does not include metadata for any repository dependencies in the
- # repository, so we can update the existing repository metadata.
+ # There is no stored metadata, so we can update the metadata column in the repository_metadata table.
return False
else:
- # There is no saved repository metadata, so we need to create a new repository_metadata table record.
+ # There is no stored repository metadata, so we need to create a new repository_metadata table record.
return True
- # The received metadata_dict includes no metadata for repository dependencies, so a new repository_metadata table record is not needed.
+ # The received metadata_dict includes no metadata for datatypes, so a new repository_metadata table record is not needed.
return False
-def new_tool_metadata_required( trans, repository, metadata_dict ):
+def new_metadata_required_for_utilities( trans, repository, new_tip_metadata_dict ):
+ """
+ Galaxy utilities currently consist of datatypes, repository_dependency definitions, tools, tool_dependency definitions and exported
+ Galaxy workflows. This method compares the last stored repository_metadata record associated with the received repository against the
+ contents of the received new_tip_metadata_dict and returns True or False for the union set of Galaxy utilities contained in both metadata
+ dictionaries. The metadata contained in new_tip_metadata_dict may not be a subset of that contained in the last stored repository_metadata
+ record associated with the received repository because one or more Galaxy utilities may have been deleted from the repository in the new tip.
+ """
+ repository_metadata = get_latest_repository_metadata( trans, repository.id )
+ datatypes_required = new_datatypes_metadata_required( trans, repository_metadata, new_tip_metadata_dict )
+ # Uncomment the following if we decide that README files should affect how installable repository revisions are defined. See the NOTE in the
+ # compare_readme_files() method.
+ # readme_files_required = new_readme_files_metadata_required( trans, repository_metadata, new_tip_metadata_dict )
+ repository_dependencies_required = new_repository_dependency_metadata_required( trans, repository_metadata, new_tip_metadata_dict )
+ tools_required = new_tool_metadata_required( trans, repository_metadata, new_tip_metadata_dict )
+ tool_dependencies_required = new_tool_dependency_metadata_required( trans, repository_metadata, new_tip_metadata_dict )
+ workflows_required = new_workflow_metadata_required( trans, repository_metadata, new_tip_metadata_dict )
+ if datatypes_required or repository_dependencies_required or tools_required or tool_dependencies_required or workflows_required:
+ return True
+ return False
+def new_readme_files_metadata_required( trans, repository_metadata, metadata_dict ):
+ """
+ Compare the last saved metadata for each readme file in the repository with the new metadata in metadata_dict to determine if a new
+ repository_metadata table record is required or if the last saved metadata record can be updated for readme files instead.
+ """
+ # Repository README files are kind of a special case because they have no effect on reproducibility. We'll simply inspect the file names to
+ # determine if any that exist in the saved metadata are eliminated from the new metadata in the received metadata_dict.
+ if 'readme_files' in metadata_dict:
+ current_readme_files = metadata_dict[ 'readme_files' ]
+ if repository_metadata:
+ metadata = repository_metadata.metadata
+ if metadata:
+ if 'readme_files' in metadata:
+ ancestor_readme_files = metadata[ 'readme_files' ]
+ # The saved metadata must be a subset of the new metadata.
+ readme_file_comparison = compare_readme_files( ancestor_readme_files, current_readme_files )
+ if readme_file_comparison == 'not equal and not subset':
+ return True
+ else:
+ return False
+ else:
+ # The new metadata includes readme_files, but the stored metadata does not, so we can update the stored metadata.
+ return False
+ else:
+ # There is no stored metadata, so we can update the metadata column in the repository_metadata table.
+ return False
+ else:
+ # There is no stored repository metadata, so we need to create a new repository_metadata table record.
+ return True
+ # The received metadata_dict includes no metadata for readme_files, so a new repository_metadata table record is not needed.
+ return False
+def new_repository_dependency_metadata_required( trans, repository_metadata, metadata_dict ):
+ """
+ Compare the last saved metadata for each repository dependency in the repository with the new metadata in metadata_dict to determine if a new
+ repository_metadata table record is required or if the last saved metadata record can be updated for repository_dependencies instead.
+ """
+ if repository_metadata:
+ metadata = repository_metadata.metadata
+ if 'repository_dependencies' in metadata:
+ saved_repository_dependencies = metadata[ 'repository_dependencies' ][ 'repository_dependencies' ]
+ new_repository_dependencies_metadata = metadata_dict.get( 'repository_dependencies', None )
+ if new_repository_dependencies_metadata:
+ new_repository_dependencies = metadata_dict[ 'repository_dependencies' ][ 'repository_dependencies' ]
+ # The saved metadata must be a subset of the new metadata.
+ for new_repository_dependency_metadata in new_repository_dependencies:
+ if new_repository_dependency_metadata not in saved_repository_dependencies:
+ return True
+ for saved_repository_dependency_metadata in saved_repository_dependencies:
+ if saved_repository_dependency_metadata not in new_repository_dependencies:
+ return True
+ else:
+ # The repository_dependencies.xml file must have been deleted, so create a new repository_metadata record so we always have
+ # access to the deleted file.
+ return True
+ else:
+ if 'repository_dependencies' in metadata_dict:
+ # There is no saved repository metadata, so we need to create a new repository_metadata record.
+ return True
+ else:
+ # The received metadata_dict includes no metadata for repository dependencies, so a new repository_metadata record is not needed.
+ return False
+def new_tool_dependency_metadata_required( trans, repository_metadata, metadata_dict ):
+ """
+ Compare the last saved metadata for each tool dependency in the repository with the new metadata in metadata_dict to determine if a new
+ repository_metadata table record is required or if the last saved metadata record can be updated for tool_dependencies instead.
+ """
+ if repository_metadata:
+ metadata = repository_metadata.metadata
+ if metadata:
+ if 'tool_dependencies' in metadata:
+ saved_tool_dependencies = metadata[ 'tool_dependencies' ]
+ new_tool_dependencies = metadata_dict.get( 'tool_dependencies', None )
+ if new_tool_dependencies:
+ # The saved metadata must be a subset of the new metadata.
+ for new_repository_dependency_metadata in new_tool_dependencies:
+ if new_repository_dependency_metadata not in saved_tool_dependencies:
+ return True
+ for saved_repository_dependency_metadata in saved_tool_dependencies:
+ if saved_repository_dependency_metadata not in new_tool_dependencies:
+ return True
+ else:
+ # The tool_dependencies.xml file must have been deleted, so create a new repository_metadata record so we always have
+ # access to the deleted file.
+ return True
+ else:
+ # We have repository metadata that does not include metadata for any tool dependencies in the repository, so we can update
+ # the existing repository metadata.
+ return False
+ else:
+ if 'tool_dependencies' in metadata_dict:
+ # There is no saved repository metadata, so we need to create a new repository_metadata record.
+ return True
+ else:
+ # The received metadata_dict includes no metadata for tool dependencies, so a new repository_metadata record is not needed.
+ return False
+def new_tool_metadata_required( trans, repository_metadata, metadata_dict ):
"""
Compare the last saved metadata for each tool in the repository with the new metadata in metadata_dict to determine if a new repository_metadata
table record is required, or if the last saved metadata record can be updated instead.
"""
if 'tools' in metadata_dict:
- repository_metadata = get_latest_repository_metadata( trans, repository.id )
if repository_metadata:
metadata = repository_metadata.metadata
if metadata:
@@ -2921,22 +3090,23 @@
for new_tool_metadata_dict in metadata_dict[ 'tools' ]:
if new_tool_metadata_dict[ 'id' ] not in saved_tool_ids:
return True
+ else:
+ # The new metadata includes tools, but the stored metadata does not, so we can update the stored metadata.
+ return False
else:
- # We have repository metadata that does not include metadata for any tools in the
- # repository, so we can update the existing repository metadata.
+ # There is no stored metadata, so we can update the metadata column in the repository_metadata table.
return False
else:
- # There is no saved repository metadata, so we need to create a new repository_metadata table record.
+ # There is no stored repository metadata, so we need to create a new repository_metadata table record.
return True
# The received metadata_dict includes no metadata for tools, so a new repository_metadata table record is not needed.
return False
-def new_workflow_metadata_required( trans, repository, metadata_dict ):
+def new_workflow_metadata_required( trans, repository_metadata, metadata_dict ):
"""
Currently everything about an exported workflow except the name is hard-coded, so there's no real way to differentiate versions of
exported workflows. If this changes at some future time, this method should be enhanced accordingly.
"""
if 'workflows' in metadata_dict:
- repository_metadata = get_latest_repository_metadata( trans, repository.id )
if repository_metadata:
# The repository has metadata, so update the workflows value - no new record is needed.
return False
@@ -3206,9 +3376,9 @@
persist=False )
# We'll only display error messages for the repository tip (it may be better to display error messages for each installable changeset revision).
if current_changeset_revision == repository.tip( trans.app ):
- invalid_file_tups.extend( invalid_tups )
+ invalid_file_tups.extend( invalid_tups )
if current_metadata_dict:
- if not metadata_changeset_revision and not metadata_dict:
+ if metadata_changeset_revision is None and metadata_dict is None:
# We're at the first change set in the change log.
metadata_changeset_revision = current_changeset_revision
metadata_dict = current_metadata_dict
@@ -3344,17 +3514,15 @@
updating_installed_repository=False,
persist=False )
if metadata_dict:
- downloadable = is_downloadable( metadata_dict )
repository_metadata = None
- if new_repository_dependency_metadata_required( trans, repository, metadata_dict ) or \
- new_tool_metadata_required( trans, repository, metadata_dict ) or \
- new_workflow_metadata_required( trans, repository, metadata_dict ):
+ if new_metadata_required_for_utilities( trans, repository, metadata_dict ):
# Create a new repository_metadata table row.
repository_metadata = create_or_update_repository_metadata( trans, encoded_id, repository, repository.tip( trans.app ), metadata_dict )
# If this is the first record stored for this repository, see if we need to send any email alerts.
if len( repository.downloadable_revisions ) == 1:
handle_email_alerts( trans, repository, content_alert_str='', new_repo_alert=True, admin_only=False )
else:
+ # Update the latest stored repository metadata with the contents and attributes of metadata_dict.
repository_metadata = get_latest_repository_metadata( trans, repository.id )
if repository_metadata:
downloadable = is_downloadable( metadata_dict )
@@ -3365,7 +3533,7 @@
trans.sa_session.add( repository_metadata )
trans.sa_session.flush()
else:
- # There are no tools in the repository, and we're setting metadata on the repository tip.
+ # There are no metadata records associated with the repository.
repository_metadata = create_or_update_repository_metadata( trans, encoded_id, repository, repository.tip( trans.app ), metadata_dict )
if 'tools' in metadata_dict and repository_metadata and status != 'error':
# Set tool versions on the new downloadable change set. The order of the list of changesets is critical, so we use the repo's changelog.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/499ce7fb3821/
changeset: 499ce7fb3821
branch: bugfixes
user: dannon
date: 2013-02-13 19:28:47
summary: Close branch bugfixes from PR#120
affected #: 0 files
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b6241599d1d0/
changeset: b6241599d1d0
user: jgoecks
date: 2013-02-13 19:19:55
summary: Python 2.5 compatibility fix.
affected #: 1 file
diff -r a6710d64e2d8081e07050696e377c5f864dd1f9f -r b6241599d1d0bbb4b9ba670bde9fbb421ef6c396 lib/galaxy/tools/data/__init__.py
--- a/lib/galaxy/tools/data/__init__.py
+++ b/lib/galaxy/tools/data/__init__.py
@@ -244,7 +244,7 @@
separator_char = (lambda c: '<TAB>' if c == '\t' else c)(self.separator)
rval = []
- for i, line in enumerate( reader, start=1 ):
+ for i, line in enumerate( reader ):
if line.lstrip().startswith( self.comment_char ):
continue
line = line.rstrip( "\n\r" )
@@ -255,7 +255,7 @@
else:
log.warn( "Line %i in tool data table '%s' is invalid (HINT: "
"'%s' characters must be used to separate fields):\n%s"
- % ( i, self.name, separator_char, line ) )
+ % ( ( i + 1 ), self.name, separator_char, line ) )
return rval
def get_entry( self, query_attr, query_val, return_attr ):
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/c8b7dfb1e76d/
changeset: c8b7dfb1e76d
branch: bugfixes
user: Bjoern Gruening
date: 2013-02-09 16:48:20
summary: Display the toolshed tools in the workflow search.
affected #: 1 file
diff -r 506484344db3a370f8ae24096041d38557d1967e -r c8b7dfb1e76d45532a339592f72c57918fbe6ba6 templates/webapps/galaxy/workflow/editor.mako
--- a/templates/webapps/galaxy/workflow/editor.mako
+++ b/templates/webapps/galaxy/workflow/editor.mako
@@ -93,12 +93,12 @@
$(".toolSectionWrapper").find(".toolTitle").hide();
if ( data.length != 0 ) {
// Map tool ids to element ids and join them.
- var s = $.map( data, function( n, i ) { return "#link-" + n; } ).join( ", " );
+ var s = $.map( data, function( n, i ) { return "link-" + n; } );
// First pass to show matching tools and their parents.
- $(s).each( function() {
+ $(s).each( function(index,id) {
// Add class to denote match.
- $(this).parent().addClass("search_match");
- $(this).parent().show().parent().parent().show().parent().show();
+ $("[id='"+id+"']").parent().addClass("search_match");
+ $("[id='"+id+"']").parent().show().parent().parent().show().parent().show();
});
// Hide labels that have no visible children.
$(".toolPanelLabel").each( function() {
https://bitbucket.org/galaxy/galaxy-central/commits/a6710d64e2d8/
changeset: a6710d64e2d8
user: dannon
date: 2013-02-13 19:15:00
summary: Merged in BjoernGruening/galaxy-central-bgruening/bugfixes (pull request #120)
Display the toolshed tools in the workflow search.
affected #: 1 file
diff -r 0ea9f5196fde94701cf2ec8404e9e33e53c51d0e -r a6710d64e2d8081e07050696e377c5f864dd1f9f templates/webapps/galaxy/workflow/editor.mako
--- a/templates/webapps/galaxy/workflow/editor.mako
+++ b/templates/webapps/galaxy/workflow/editor.mako
@@ -93,12 +93,12 @@
$(".toolSectionWrapper").find(".toolTitle").hide();
if ( data.length != 0 ) {
// Map tool ids to element ids and join them.
- var s = $.map( data, function( n, i ) { return "#link-" + n; } ).join( ", " );
+ var s = $.map( data, function( n, i ) { return "link-" + n; } );
// First pass to show matching tools and their parents.
- $(s).each( function() {
+ $(s).each( function(index,id) {
// Add class to denote match.
- $(this).parent().addClass("search_match");
- $(this).parent().show().parent().parent().show().parent().show();
+ $("[id='"+id+"']").parent().addClass("search_match");
+ $("[id='"+id+"']").parent().show().parent().parent().show().parent().show();
});
// Hide labels that have no visible children.
$(".toolPanelLabel").each( function() {
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/c8b7dfb1e76d/
changeset: c8b7dfb1e76d
branch: bugfixes
user: Bjoern Gruening
date: 2013-02-09 16:48:20
summary: Display the toolshed tools in the workflow search.
affected #: 1 file
diff -r 506484344db3a370f8ae24096041d38557d1967e -r c8b7dfb1e76d45532a339592f72c57918fbe6ba6 templates/webapps/galaxy/workflow/editor.mako
--- a/templates/webapps/galaxy/workflow/editor.mako
+++ b/templates/webapps/galaxy/workflow/editor.mako
@@ -93,12 +93,12 @@
$(".toolSectionWrapper").find(".toolTitle").hide();
if ( data.length != 0 ) {
// Map tool ids to element ids and join them.
- var s = $.map( data, function( n, i ) { return "#link-" + n; } ).join( ", " );
+ var s = $.map( data, function( n, i ) { return "link-" + n; } );
// First pass to show matching tools and their parents.
- $(s).each( function() {
+ $(s).each( function(index,id) {
// Add class to denote match.
- $(this).parent().addClass("search_match");
- $(this).parent().show().parent().parent().show().parent().show();
+ $("[id='"+id+"']").parent().addClass("search_match");
+ $("[id='"+id+"']").parent().show().parent().parent().show().parent().show();
});
// Hide labels that have no visible children.
$(".toolPanelLabel").each( function() {
https://bitbucket.org/galaxy/galaxy-central/commits/a6710d64e2d8/
changeset: a6710d64e2d8
user: dannon
date: 2013-02-13 19:15:00
summary: Merged in BjoernGruening/galaxy-central-bgruening/bugfixes (pull request #120)
Display the toolshed tools in the workflow search.
affected #: 1 file
diff -r 0ea9f5196fde94701cf2ec8404e9e33e53c51d0e -r a6710d64e2d8081e07050696e377c5f864dd1f9f templates/webapps/galaxy/workflow/editor.mako
--- a/templates/webapps/galaxy/workflow/editor.mako
+++ b/templates/webapps/galaxy/workflow/editor.mako
@@ -93,12 +93,12 @@
$(".toolSectionWrapper").find(".toolTitle").hide();
if ( data.length != 0 ) {
// Map tool ids to element ids and join them.
- var s = $.map( data, function( n, i ) { return "#link-" + n; } ).join( ", " );
+ var s = $.map( data, function( n, i ) { return "link-" + n; } );
// First pass to show matching tools and their parents.
- $(s).each( function() {
+ $(s).each( function(index,id) {
// Add class to denote match.
- $(this).parent().addClass("search_match");
- $(this).parent().show().parent().parent().show().parent().show();
+ $("[id='"+id+"']").parent().addClass("search_match");
+ $("[id='"+id+"']").parent().show().parent().parent().show().parent().show();
});
// Hide labels that have no visible children.
$(".toolPanelLabel").each( function() {
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: carlfeberhard: Patch base.less for select2-container, min-width; Fix .hgignore to handle new static/style path
by Bitbucket 13 Feb '13
by Bitbucket 13 Feb '13
13 Feb '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/0ea9f5196fde/
changeset: 0ea9f5196fde
user: carlfeberhard
date: 2013-02-13 19:12:33
summary: Patch base.less for select2-container, min-width; Fix .hgignore to handle new static/style path
affected #: 3 files
diff -r 06b9f3ddce047c8db70e892732441a35cc91b241 -r 0ea9f5196fde94701cf2ec8404e9e33e53c51d0e .hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -79,7 +79,7 @@
# CSS build artifacts.
*/variables.less
-static/june_2007_style/blue/base_sprites.less
+static/style/blue/base_sprites.less
# Testing
selenium-server.jar
diff -r 06b9f3ddce047c8db70e892732441a35cc91b241 -r 0ea9f5196fde94701cf2ec8404e9e33e53c51d0e static/style/base.less
--- a/static/style/base.less
+++ b/static/style/base.less
@@ -5,6 +5,10 @@
@import "fontawesome/font-awesome.less";
@import "select2.less";
+/* fix for zero width select2 - remove when fixed there */
+.select2-container {
+ min-width: 256px;
+}
// Mixins
diff -r 06b9f3ddce047c8db70e892732441a35cc91b241 -r 0ea9f5196fde94701cf2ec8404e9e33e53c51d0e static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -886,7 +886,8 @@
.select2-result-selectable .select2-match,.select2-result-unselectable .select2-result-selectable .select2-match{text-decoration:underline;}
.select2-result-unselectable .select2-match{text-decoration:none;}
.select2-offscreen{position:absolute;left:-10000px;}
-@media only screen and (-webkit-min-device-pixel-ratio:1.5){.select2-search input,.select2-search-choice-close,.select2-container .select2-choice abbr,.select2-container .select2-choice div b{background-image:url(select2x2.png) !important;background-repeat:no-repeat !important;background-size:60px 40px !important;} .select2-search input{background-position:100% -21px !important;}}.unselectable{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;}
+@media only screen and (-webkit-min-device-pixel-ratio:1.5){.select2-search input,.select2-search-choice-close,.select2-container .select2-choice abbr,.select2-container .select2-choice div b{background-image:url(select2x2.png) !important;background-repeat:no-repeat !important;background-size:60px 40px !important;} .select2-search input{background-position:100% -21px !important;}}.select2-container{min-width:256px;}
+.unselectable{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;}
.parent-width{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:100%;*width:90%;}
.clear{*zoom:1;}.clear:before,.clear:after{display:table;content:"";line-height:0;}
.clear:after{clear:both;}
@@ -1078,7 +1079,7 @@
.action-button [class^="fa-icon-"].fa-icon-spin.icon-large,.action-button [class*=" fa-icon-"].fa-icon-spin.icon-large{height:.75em;}
a.action-button{text-decoration:none;}
.action-button>img{vertical-align:middle;}
-.action-button:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);color:inherit;}
+.action-button:active{color:inherit;}
.menubutton{*display:inline;*zoom:1;padding:4px 12px;margin-bottom:0;font-size:12px;line-height:16px;text-align:center;vertical-align:middle;color:#333333;text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #ffffff, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #ffffff, #e6e6e6);background-image:-o-linear-gradient(top, #ffffff, #e6e6e6);background-image:linear-gradient(to bottom, #ffffff, #e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #999999;*border:0;border-bottom-color:#808080;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*margin-left:.3em;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);border-color:#c5c5c5;border-color:rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25);padding:2px 10px 2px;border-color:#999999;border-color:rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4);display:inline-block;cursor:pointer;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;}.menubutton:hover,.menubutton:active,.menubutton.active,.menubutton.disabled,.menubutton[disabled]{color:#333333;background-color:#e6e6e6;*background-color:#d9d9d9;}
.menubutton:active,.menubutton.active{background-color:#cccccc \9;}
.menubutton:hover,.menubutton:active,.menubutton.active,.menubutton.disabled,.menubutton[disabled]{color:#333333;background-color:#e6e6e6;*background-color:#d9d9d9;}
@@ -1092,7 +1093,7 @@
.menubutton [class^="fa-icon-"],.menubutton [class*=" fa-icon-"]{display:inline;line-height:.6em;}.menubutton [class^="fa-icon-"].fa-icon-spin,.menubutton [class*=" fa-icon-"].fa-icon-spin{display:inline-block;}
.menubutton [class^="fa-icon-"].pull-left.fa-icon-2x,.menubutton [class*=" fa-icon-"].pull-left.fa-icon-2x,.menubutton [class^="fa-icon-"].pull-right.fa-icon-2x,.menubutton [class*=" fa-icon-"].pull-right.fa-icon-2x{margin-top:.35em;}
.menubutton [class^="fa-icon-"].fa-icon-spin.icon-large,.menubutton [class*=" fa-icon-"].fa-icon-spin.icon-large{height:.75em;}
-.menubutton:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);color:inherit;}
+.menubutton:active{color:inherit;}
.menubutton:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}
.menubutton a{text-decoration:none;}
.menubutton .label,.menubutton>label{position:relative;display:inline-block;border-right:none;text-decoration:none;text-align:left;max-height:32px;line-height:16px;overflow:hidden;text-overflow:ellipsis;}
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/06b9f3ddce04/
changeset: 06b9f3ddce04
user: greg
date: 2013-02-13 18:40:11
summary: Fix tool shed functional test that uploaded a tar archive without properly setting the option to not remove files from the repository that are not included in the uploaded archive. This resulted in setting metadata on the repository after upload in such a way that functional tests were not properly testing behavior.
affected #: 1 file
diff -r 6b10699dc0950691097400e83fa6b51e35501e6f -r 06b9f3ddce047c8db70e892732441a35cc91b241 test/tool_shed/functional/test_0400_repository_component_reviews.py
--- a/test/tool_shed/functional/test_0400_repository_component_reviews.py
+++ b/test/tool_shed/functional/test_0400_repository_component_reviews.py
@@ -452,7 +452,10 @@
"""
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
user = test_db_util.get_user( common.test_user_2_email )
- self.upload_file( repository, 'filtering/filtering_test_data.tar', commit_message="Uploaded test data." )
+ self.upload_file( repository,
+ 'filtering/filtering_test_data.tar',
+ commit_message="Uploaded test data.",
+ remove_repo_files_not_in_tar='No' )
def test_0110_review_new_changeset_functional_tests( self ):
'''Update the filtering repository's readme component review to reflect the presence of the readme file.'''
"""
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
3 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/91c6fa5712b5/
changeset: 91c6fa5712b5
user: jmchilton
date: 2013-02-10 18:13:51
summary: Add optional "upload" attribute to tool definitions.
When extracting workflows, such tools are treated as inputs. This eliminates the need for the hack of hardcoding 'upload1' in tools.py and allows multiple upload tools to exist and function properly when extracting workflows.
affected #: 2 files
diff -r 506484344db3a370f8ae24096041d38557d1967e -r 91c6fa5712b5eaac805b576418de699e216fa384 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -1085,7 +1085,7 @@
if requirements_elem:
self.parse_requirements( requirements_elem )
# Determine if this tool can be used in workflows
- self.is_workflow_compatible = self.check_workflow_compatible()
+ self.is_workflow_compatible = self.check_workflow_compatible(root)
# Trackster configuration.
trackster_conf = root.find( "trackster_conf" )
if trackster_conf is not None:
@@ -1653,7 +1653,7 @@
version = requirement_elem.get( "version", None )
requirement = ToolRequirement( name=name, type=type, version=version )
self.requirements.append( requirement )
- def check_workflow_compatible( self ):
+ def check_workflow_compatible( self, root ):
"""
Determine if a tool can be used in workflows. External tools and the
upload tool are currently not supported by workflows.
@@ -1666,9 +1666,7 @@
# right now
if self.tool_type.startswith( 'data_source' ):
return False
- # HACK: upload is (as always) a special case becuase file parameters
- # can't be persisted.
- if self.id == "upload1":
+ if util.string_as_bool( root.get( "upload", "False" ) ):
return False
# TODO: Anyway to capture tools that dynamically change their own
# outputs?
diff -r 506484344db3a370f8ae24096041d38557d1967e -r 91c6fa5712b5eaac805b576418de699e216fa384 tools/data_source/upload.xml
--- a/tools/data_source/upload.xml
+++ b/tools/data_source/upload.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<tool name="Upload File" id="upload1" version="1.1.3">
+<tool name="Upload File" id="upload1" version="1.1.3" upload="true"><description>
from your computer
</description>
https://bitbucket.org/galaxy/galaxy-central/commits/46b01a48a40d/
changeset: 46b01a48a40d
user: jmchilton
date: 2013-02-13 17:45:56
summary: Based on input from natefoo, replace root tool tag "upload" with inverse tag "workflow_compatible". Adjust logic in tools module accordingly.
affected #: 2 files
diff -r 91c6fa5712b5eaac805b576418de699e216fa384 -r 46b01a48a40d70ec5d5fa9c3a21a3e2dec4cee24 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -1666,7 +1666,7 @@
# right now
if self.tool_type.startswith( 'data_source' ):
return False
- if util.string_as_bool( root.get( "upload", "False" ) ):
+ if not util.string_as_bool( root.get( "workflow_compatible", "True" ) ):
return False
# TODO: Anyway to capture tools that dynamically change their own
# outputs?
diff -r 91c6fa5712b5eaac805b576418de699e216fa384 -r 46b01a48a40d70ec5d5fa9c3a21a3e2dec4cee24 tools/data_source/upload.xml
--- a/tools/data_source/upload.xml
+++ b/tools/data_source/upload.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<tool name="Upload File" id="upload1" version="1.1.3" upload="true">
+<tool name="Upload File" id="upload1" version="1.1.3" workflow_compatible="false"><description>
from your computer
</description>
https://bitbucket.org/galaxy/galaxy-central/commits/6b10699dc095/
changeset: 6b10699dc095
user: natefoo
date: 2013-02-13 17:51:56
summary: Merged in jmchilton/galaxy-central-allow-additional-upload-tools (pull request #122)
Add optional "upload" attribute to tool definitions.
affected #: 2 files
diff -r c19fa5da36cc51fd5ee6005ed801a7e2c9aba229 -r 6b10699dc0950691097400e83fa6b51e35501e6f lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -1097,7 +1097,7 @@
if requirements_elem:
self.parse_requirements( requirements_elem )
# Determine if this tool can be used in workflows
- self.is_workflow_compatible = self.check_workflow_compatible()
+ self.is_workflow_compatible = self.check_workflow_compatible(root)
# Trackster configuration.
trackster_conf = root.find( "trackster_conf" )
if trackster_conf is not None:
@@ -1665,7 +1665,7 @@
version = requirement_elem.get( "version", None )
requirement = ToolRequirement( name=name, type=type, version=version )
self.requirements.append( requirement )
- def check_workflow_compatible( self ):
+ def check_workflow_compatible( self, root ):
"""
Determine if a tool can be used in workflows. External tools and the
upload tool are currently not supported by workflows.
@@ -1678,9 +1678,7 @@
# right now
if self.tool_type.startswith( 'data_source' ):
return False
- # HACK: upload is (as always) a special case becuase file parameters
- # can't be persisted.
- if self.id == "upload1":
+ if not util.string_as_bool( root.get( "workflow_compatible", "True" ) ):
return False
# TODO: Anyway to capture tools that dynamically change their own
# outputs?
diff -r c19fa5da36cc51fd5ee6005ed801a7e2c9aba229 -r 6b10699dc0950691097400e83fa6b51e35501e6f tools/data_source/upload.xml
--- a/tools/data_source/upload.xml
+++ b/tools/data_source/upload.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<tool name="Upload File" id="upload1" version="1.1.3">
+<tool name="Upload File" id="upload1" version="1.1.3" workflow_compatible="false"><description>
from your computer
</description>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
13 Feb '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/c19fa5da36cc/
changeset: c19fa5da36cc
user: jgoecks
date: 2013-02-13 17:04:54
summary: Improved documentation in bowtie2 loc file.
affected #: 1 file
diff -r 7bf8f6a1da9c7d6148712e574f16a34a2c6e1525 -r c19fa5da36cc51fd5ee6005ed801a7e2c9aba229 tool-data/bowtie2_indices.loc.sample
--- a/tool-data/bowtie2_indices.loc.sample
+++ b/tool-data/bowtie2_indices.loc.sample
@@ -1,37 +1,37 @@
-#This is a sample file distributed with Galaxy that enables tools
-#to use a directory of Bowtie2 indexed sequences data files. You will
-#need to create these data files and then create a bowtie_indices.loc
-#file similar to this one (store it in this directory) that points to
-#the directories in which those files are stored. The bowtie2_indices.loc
-#file has this format (longer white space characters are TAB characters):
+# bowtie2_indices.loc.sample
+# This is a *.loc.sample file distributed with Galaxy that enables tools
+# to use a directory of indexed data files. This one is for Bowtie2 and Tophat2.
+# See the wiki: http://wiki.galaxyproject.org/Admin/NGS%20Local%20Setup
+# First create these data files and save them in your own data directory structure.
+# Then, create a bowtie_indices.loc file to use those indexes with tools.
+# Copy this file, save it with the same name (minus the .sample),
+# follow the format examples, and store the result in this directory.
+# The file should include an one line entry for each index set.
+# The path points to the "basename" for the set, not a specific file.
+# It has four text columns seperated by TABS.
#
-#<unique_build_id><dbkey><display_name><file_base_path>
+# <unique_build_id><dbkey><display_name><file_base_path>
#
-#So, for example, if you had hg18 indexed stored in
-#/depot/data2/galaxy/bowtie2/hg18/,
-#then the bowtie2_indices.loc entry would look like this:
+# So, for example, if you had hg18 indexes stored in:
#
-#hg18 hg18 hg18 /depot/data2/galaxy/bowtie2/hg18/hg18
+# /depot/data2/galaxy/hg19/bowtie2/
#
-#and your /depot/data2/galaxy/bowtie2/hg18/ directory
-#would contain hg18.*.ebwt files:
+# containing hg19 genome and hg19.*.bt2 files, such as:
+# -rw-rw-r-- 1 james james 914M Feb 10 18:56 hg19canon.fa
+# -rw-rw-r-- 1 james james 914M Feb 10 18:56 hg19canon.1.bt2
+# -rw-rw-r-- 1 james james 683M Feb 10 18:56 hg19canon.2.bt2
+# -rw-rw-r-- 1 james james 3.3K Feb 10 16:54 hg19canon.3.bt2
+# -rw-rw-r-- 1 james james 683M Feb 10 16:54 hg19canon.4.bt2
+# -rw-rw-r-- 1 james james 914M Feb 10 20:45 hg19canon.rev.1.bt2
+# -rw-rw-r-- 1 james james 683M Feb 10 20:45 hg19canon.rev.2.bt2
#
-#-rw-r--r-- 1 james universe 830134 2005-09-13 10:12 hg18.1.ebwt
-#-rw-r--r-- 1 james universe 527388 2005-09-13 10:12 hg18.2.ebwt
-#-rw-r--r-- 1 james universe 269808 2005-09-13 10:12 hg18.3.ebwt
-#...etc...
+# then the bowtie2_indices.loc entry could look like this:
#
-#Your bowtie2_indices.loc file should include an entry per line for each
-#index set you have stored. The "file" in the path does not actually
-#exist, but it is the prefix for the actual index files. For example:
+#hg19 hg19 Human (hg19) /depot/data2/galaxy/hg19/bowtie2/hg19canon
#
-#hg18canon hg18 hg18 Canonical /depot/data2/galaxy/bowtie2/hg18/hg18canon
-#hg18full hg18 hg18 Full /depot/data2/galaxy/bowtie2/hg18/hg18full
-#/orig/path/hg19 hg19 hg19 /depot/data2/galaxy/bowtie2/hg19/hg19
-#...etc...
+#More examples:
#
-#Note that for backwards compatibility with workflows, the unique ID of
-#an entry must be the path that was in the original loc file, because that
-#is the value stored in the workflow for that parameter. That is why the
-#hg19 entry above looks odd. New genomes can be better-looking.
+#mm10 mm10 Mouse (mm10) /depot/data2/galaxy/mm10/bowtie2/mm10
+#dm3 dm3 D. melanogaster (dm3) /depot/data2/galaxy/mm10/bowtie2/dm3
#
+#
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: inithello: Tool shed functional test enhancements and documentation.
by Bitbucket 13 Feb '13
by Bitbucket 13 Feb '13
13 Feb '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/7bf8f6a1da9c/
changeset: 7bf8f6a1da9c
user: inithello
date: 2013-02-13 16:58:10
summary: Tool shed functional test enhancements and documentation.
affected #: 3 files
diff -r 3eff396a81d833a2dcabce2fd34b53badf707984 -r 7bf8f6a1da9c7d6148712e574f16a34a2c6e1525 test/tool_shed/base/test_db_util.py
--- a/test/tool_shed/base/test_db_util.py
+++ b/test/tool_shed/base/test_db_util.py
@@ -1,9 +1,11 @@
-import galaxy.model
+import galaxy.model, logging
import galaxy.webapps.community.model as model
from galaxy.model.orm import *
from galaxy.webapps.community.model.mapping import context as sa_session
from galaxy.model.mapping import context as ga_session
+log = logging.getLogger( 'test.tool_shed.test_db_util' )
+
def delete_obj( obj ):
sa_session.delete( obj )
sa_session.flush()
@@ -57,10 +59,44 @@
if role.name == user.email and role.description == 'Private Role for %s' % user.email:
return role
raise AssertionError( "Private role not found for user '%s'" % user.email )
+def get_repository_reviews( repository_id, reviewer_user_id=None, changeset_revision=None ):
+ if reviewer_user_id and changeset_revision:
+ reviews = sa_session.query( model.RepositoryReview ) \
+ .filter( and_( model.RepositoryReview.table.c.repository_id == repository_id,
+ model.RepositoryReview.table.c.deleted == False,
+ model.RepositoryReview.table.c.changeset_revision == changeset_revision,
+ model.RepositoryReview.table.c.user_id == reviewer_user_id ) ) \
+ .all()
+ elif reviewer_user_id:
+ reviews = sa_session.query( model.RepositoryReview ) \
+ .filter( and_( model.RepositoryReview.table.c.repository_id == repository_id,
+ model.RepositoryReview.table.c.deleted == False,
+ model.RepositoryReview.table.c.user_id == reviewer_user_id ) ) \
+ .all()
+ else:
+ reviews = sa_session.query( model.RepositoryReview ) \
+ .filter( and_( model.RepositoryReview.table.c.repository_id == repository_id,
+ model.RepositoryReview.table.c.deleted == False ) ) \
+ .all()
+ return reviews
+def get_reviews_ordered_by_changeset_revision( repository_id, changelog_tuples, reviewer_user_id=None ):
+ reviews = get_repository_reviews( repository_id, reviewer_user_id=reviewer_user_id )
+ ordered_reviews = []
+ for ctx_rev, changeset_hash in changelog_tuples:
+ for review in reviews:
+ if str( review.changeset_revision ) == str( changeset_hash ):
+ ordered_reviews.append( review )
+ return ordered_reviews
def get_repository_by_id( repository_id ):
return sa_session.query( model.Repository ) \
.filter( model.Repository.table.c.id == repository_id ) \
.first()
+def get_repository_downloadable_revisions( repository_id ):
+ revisions = sa_session.query( model.RepositoryMetadata ) \
+ .filter( and_( model.RepositoryMetadata.table.c.repository_id == repository_id,
+ model.RepositoryMetadata.table.c.downloadable == True ) ) \
+ .all()
+ return revisions
def get_repository_review_by_user_id_changeset_revision( user_id, repository_id, changeset_revision ):
review = sa_session.query( model.RepositoryReview ) \
.filter( and_( model.RepositoryReview.table.c.user_id == user_id,
diff -r 3eff396a81d833a2dcabce2fd34b53badf707984 -r 7bf8f6a1da9c7d6148712e574f16a34a2c6e1525 test/tool_shed/base/twilltestcase.py
--- a/test/tool_shed/base/twilltestcase.py
+++ b/test/tool_shed/base/twilltestcase.py
@@ -493,6 +493,14 @@
return os.path.abspath( os.path.join( filepath, filename ) )
else:
return os.path.abspath( os.path.join( self.file_dir, filename ) )
+ def get_last_reviewed_revision_by_user( self, user, repository ):
+ changelog_tuples = self.get_repository_changelog_tuples( repository )
+ reviews = test_db_util.get_reviews_ordered_by_changeset_revision( repository.id, changelog_tuples, reviewer_user_id = user.id )
+ if reviews:
+ last_review = reviews[ -1 ]
+ else:
+ last_review = None
+ return last_review
def get_or_create_repository( self, owner=None, strings_displayed=[], strings_not_displayed=[], **kwd ):
repository = test_db_util.get_repository_by_name_and_owner( kwd[ 'name' ], owner )
if repository is None:
@@ -508,9 +516,13 @@
return self.hgweb_config_manager.get_entry( lhs )
except:
raise Exception( "Entry for repository %s missing in hgweb config file %s." % ( lhs, self.hgweb_config_manager.hgweb_config ) )
- def get_repository_changelog( self, repository ):
+ def get_repository_changelog_tuples( self, repository ):
repo = hg.repository( ui.ui(), self.get_repo_path( repository ) )
- return [ ( repo.changectx( changeset ), changeset ) for changeset in repo.changelog ]
+ changelog_tuples = []
+ for changeset in repo.changelog:
+ ctx = repo.changectx( changeset )
+ changelog_tuples.append( ( ctx.rev(), repo.changectx( changeset ) ) )
+ return changelog_tuples
def get_repository_datatypes_count( self, repository ):
metadata = self.get_repository_metadata( repository )[0].metadata
if 'datatypes' not in metadata:
diff -r 3eff396a81d833a2dcabce2fd34b53badf707984 -r 7bf8f6a1da9c7d6148712e574f16a34a2c6e1525 test/tool_shed/functional/test_0400_repository_component_reviews.py
--- a/test/tool_shed/functional/test_0400_repository_component_reviews.py
+++ b/test/tool_shed/functional/test_0400_repository_component_reviews.py
@@ -5,10 +5,45 @@
repository_description = 'Galaxy filtering tool for test 0400'
repository_long_description = 'Long description of Galaxy filtering tool for test 0400'
+'''
+1. Create users.
+2. Grant reviewer role to test_user_2.
+3. Check that the review components that are to be tested are defined in this tool shed instance.
+4. Create a repository, owned by test_user_1, to be reviewed by test_user_2.
+5. Review the datatypes component on the repository.
+6. Check that no other components besides datatypes display as reviewed.
+7. Review the functional tests component on the repository.
+8. Check that only functional tests and datatypes display as reviewed.
+9. Review the readme component on the repository.
+10. Check that only functional tests, datatypes, and readme display as reviewed.
+11. Review the repository dependencies component.
+12. Check that only repository dependencies, functional tests, datatypes, and readme display as reviewed.
+13. Review the tool dependencies component.
+14. Check that only tool dependencies, repository dependencies, functional tests, datatypes, and readme display as reviewed.
+15. Review the tools component.
+16. Check that only tools, tool dependencies, repository dependencies, functional tests, datatypes, and readme display as reviewed.
+17. Review the workflows component.
+18. Check that all components display as reviewed.
+19. Upload readme.txt to the repository.
+20. Copy the previous review, and update the readme component review to reflect the existence of a readme file.
+21. Check that the readme component review has been updated, and the other component reviews are present.
+22. Upload test data to the repository. This will also create a new changeset revision.
+23. Review the functional tests component on the repository, copying the other components from the previous review.
+24. Verify that the functional tests component review has been updated, and as in step 21, the other reviews are unchanged.
+25. Upload a new version of the tool.
+26. Review the new revision's functional tests component.
+27. Verify that the functional tests component review displays correctly.
+'''
+
class TestRepositoryComponentReviews( ShedTwillTestCase ):
'''Test repository component review features.'''
def test_0000_initiate_users( self ):
"""Create necessary user accounts and login as an admin user."""
+ """
+ We are at step 1.
+ Create all the user accounts that are needed for this test script to run independently of other test.
+ Previously created accounts will not be re-created.
+ """
self.logout()
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
test_user_1 = test_db_util.get_user( common.test_user_1_email )
@@ -26,11 +61,21 @@
admin_user_private_role = test_db_util.get_private_role( admin_user )
def test_0005_grant_reviewer_role( self ):
'''Grant the repository reviewer role to test_user_2.'''
+ """
+ We are at step 2.
+ We now have an admin user (admin_user) and two non-admin users (test_user_1 and test_user_2). Grant the repository
+ reviewer role to test_user_2, who will not be the owner of the reviewed repositories.
+ """
reviewer_role = test_db_util.get_role_by_name( 'Repository Reviewer' )
test_user_2 = test_db_util.get_user( common.test_user_2_email )
self.grant_role_to_user( test_user_2, reviewer_role )
def test_0010_verify_repository_review_components( self ):
'''Ensure that the required review components exist.'''
+ """
+ We are at step 3.
+ We now have an admin user (admin_user) and two non-admin users (test_user_1 and test_user_2). Grant the repository
+ reviewer role to test_user_2, who will not be the owner of the reviewed repositories.
+ """
strings_not_displayed=[ 'Repository dependencies' ]
self.manage_review_components( strings_not_displayed=strings_not_displayed )
self.add_repository_review_component( name='Repository dependencies',
@@ -39,6 +84,11 @@
self.manage_review_components( strings_displayed=strings_displayed )
def test_0015_create_repository( self ):
"""Create and populate the filtering repository"""
+ """
+ We are at step 4.
+ Log in as test_user_1 and create the filtering repository, then upload a basic set of
+ components to be reviewed in subsequent tests.
+ """
category = self.create_category( name='Test 0400 Repository Component Reviews', description='Test 0400 Repository Component Reviews' )
self.logout()
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
@@ -53,21 +103,32 @@
self.upload_file( repository, 'filtering/filtering_1.1.0.tar', commit_message="Uploaded filtering 1.1.0" )
def test_0020_review_initial_revision_data_types( self ):
'''Review the datatypes component for the current tip revision.'''
+ """
+ We are at step 5.
+ Log in as test_user_2 and review the data types component of the filtering repository owned by test_user_1.
# Review this revision:
# Data types (N/A)
- # Functional tests (One star, comment 'functional tests missing')
- # README (N/A)
- # Repository dependencies (N/A)
- # Tool dependencies (N/A)
- # Tools (5 stars, good review)
- # Workflows (N/A)
+ """
self.logout()
self.login( email=common.test_user_2_email, username=common.test_user_2_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
+ # The create_repository_review method takes a dict( component label=review contents ).
+ # If review_contents is empty, it marks that component as not applicable. The review
+ # contents dict should have the structure:
+ # {
+ # rating: 1-5,
+ # comment: <text>
+ # approved: yes/no
+ # private: yes/no
+ # }
review_contents_dict = { 'Data types': dict() }
self.create_repository_review( repository, review_contents_dict )
def test_0025_verify_datatype_review( self ):
'''Verify that the datatypes component review displays correctly.'''
+ """
+ We are at step 6.
+ Log in as test_user_1 and check that the filtering repository only has a review for the data types component.
+ """
self.logout()
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
@@ -76,11 +137,28 @@
strings_not_displayed = [ 'Functional tests', 'README', 'Repository dependencies', 'Tool dependencies', 'Tools', 'Workflows' ]
self.verify_repository_reviews( repository, reviewer=user, strings_displayed=strings_displayed )
def test_0030_review_initial_revision_functional_tests( self ):
- '''Review the datatypes component for the current tip revision.'''
+ '''Review the functional tests component for the current tip revision.'''
+ """
+ We are at step 7.
+ Log in as test_user_2 and review the functional tests component for this repository. Since the repository
+ has not been altered, this will update the existing review to add a component.
+ # Review this revision:
+ # Data types (N/A)
+ # Functional tests (One star, comment 'functional tests missing')
+ """
self.logout()
self.login( email=common.test_user_2_email, username=common.test_user_2_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
user = test_db_util.get_user( common.test_user_2_email )
+ # The create_repository_review method takes a dict( component label=review contents ).
+ # If review_contents is empty, it marks that component as not applicable. The review
+ # contents dict should have the structure:
+ # {
+ # rating: 1-5,
+ # comment: <text>
+ # approved: yes/no
+ # private: yes/no
+ # }
review_contents_dict = { 'Functional tests': dict( rating=1, comment='Functional tests missing', approved='no', private='yes' ) }
self.review_repository( repository, review_contents_dict, user )
# def test_0030_verify_review_display( self ):
@@ -89,7 +167,13 @@
# self.logout()
# self.login( email=common.test_user_3_email, username=common.test_user_3_name )
def test_0035_verify_functional_test_review( self ):
- '''Verify that the datatypes component review displays correctly.'''
+ '''Verify that the functional tests component review displays correctly.'''
+ """
+ We are at step 8.
+ Log in as test_user_1 and check that the filtering repository now has reviews
+ for the data types and functional tests components. Since the functional tests component was not marked as 'Not applicable',
+ also check for the review comment.
+ """
self.logout()
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
@@ -99,14 +183,35 @@
self.verify_repository_reviews( repository, reviewer=user, strings_displayed=strings_displayed )
def test_0040_review_readme( self ):
'''Review the readme component for the current tip revision.'''
+ """
+ We are at step 9.
+ Log in as test_user_2 and update the review with the readme component marked as 'Not applicable'.
+ # Review this revision:
+ # Data types (N/A)
+ # Functional tests (One star, comment 'functional tests missing')
+ # README (N/A)
+ """
self.logout()
self.login( email=common.test_user_2_email, username=common.test_user_2_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
user = test_db_util.get_user( common.test_user_2_email )
+ # The create_repository_review method takes a dict( component label=review contents ).
+ # If review_contents is empty, it marks that component as not applicable. The review
+ # contents dict should have the structure:
+ # {
+ # rating: 1-5,
+ # comment: <text>
+ # approved: yes/no
+ # private: yes/no
+ # }
review_contents_dict = { 'README': dict() }
self.review_repository( repository, review_contents_dict, user )
def test_0045_verify_readme_review( self ):
- '''Verify that the datatypes component review displays correctly.'''
+ '''Verify that the readme component review displays correctly.'''
+ """
+ We are at step 10.
+ Log in as test_user_1 and verify that the repository component reviews now include a review for the readme component.
+ """
self.logout()
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
@@ -116,14 +221,37 @@
self.verify_repository_reviews( repository, reviewer=user, strings_displayed=strings_displayed )
def test_0050_review_repository_dependencies( self ):
'''Review the repository dependencies component for the current tip revision.'''
+ """
+ We are at step 11.
+ Log in as test_user_2 and update the review with the repository dependencies component marked as 'Not applicable'.
+ # Review this revision:
+ # Data types (N/A)
+ # Functional tests (One star, comment 'functional tests missing')
+ # README (N/A)
+ # Repository dependencies (N/A)
+ """
self.logout()
self.login( email=common.test_user_2_email, username=common.test_user_2_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
user = test_db_util.get_user( common.test_user_2_email )
+ # The create_repository_review method takes a dict( component label=review contents ).
+ # If review_contents is empty, it marks that component as not applicable. The review
+ # contents dict should have the structure:
+ # {
+ # rating: 1-5,
+ # comment: <text>
+ # approved: yes/no
+ # private: yes/no
+ # }
review_contents_dict = { 'Repository dependencies': dict() }
self.review_repository( repository, review_contents_dict, user )
def test_0055_verify_repository_dependency_review( self ):
- '''Verify that the datatypes component review displays correctly.'''
+ '''Verify that the repository dependencies component review displays correctly.'''
+ """
+ We are at step 12.
+ Log in as test_user_1 and verify that the repository component reviews now include a review
+ for the repository dependencies component.
+ """
self.logout()
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
@@ -133,14 +261,38 @@
self.verify_repository_reviews( repository, reviewer=user, strings_displayed=strings_displayed )
def test_0060_review_tool_dependencies( self ):
'''Review the tool dependencies component for the current tip revision.'''
+ """
+ We are at step 13.
+ Log in as test_user_2 and update the review with the tool dependencies component marked as 'Not applicable'.
+ # Review this revision:
+ # Data types (N/A)
+ # Functional tests (One star, comment 'functional tests missing')
+ # README (N/A)
+ # Repository dependencies (N/A)
+ # Tool dependencies (N/A)
+ """
self.logout()
self.login( email=common.test_user_2_email, username=common.test_user_2_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
user = test_db_util.get_user( common.test_user_2_email )
+ # The create_repository_review method takes a dict( component label=review contents ).
+ # If review_contents is empty, it marks that component as not applicable. The review
+ # contents dict should have the structure:
+ # {
+ # rating: 1-5,
+ # comment: <text>
+ # approved: yes/no
+ # private: yes/no
+ # }
review_contents_dict = { 'Tool dependencies': dict() }
self.review_repository( repository, review_contents_dict, user )
def test_0065_verify_tool_dependency_review( self ):
- '''Verify that the datatypes component review displays correctly.'''
+ '''Verify that the tool dependencies component review displays correctly.'''
+ """
+ We are at step 14.
+ Log in as test_user_1 and verify that the repository component reviews now include a review
+ for the tool dependencies component.
+ """
self.logout()
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
@@ -150,14 +302,40 @@
self.verify_repository_reviews( repository, reviewer=user, strings_displayed=strings_displayed )
def test_0070_review_tools( self ):
'''Review the tools component for the current tip revision.'''
+ """
+ We are at step 15.
+ Log in as test_user_2 and update the review with the tools component given
+ a favorable review, with 5 stars, and approved status.
+ # Review this revision:
+ # Data types (N/A)
+ # Functional tests (One star, comment 'functional tests missing')
+ # README (N/A)
+ # Repository dependencies (N/A)
+ # Tool dependencies (N/A)
+ # Tools (5 stars, good review)
+ """
self.logout()
self.login( email=common.test_user_2_email, username=common.test_user_2_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
user = test_db_util.get_user( common.test_user_2_email )
+ # The create_repository_review method takes a dict( component label=review contents ).
+ # If review_contents is empty, it marks that component as not applicable. The review
+ # contents dict should have the structure:
+ # {
+ # rating: 1-5,
+ # comment: <text>
+ # approved: yes/no
+ # private: yes/no
+ # }
review_contents_dict = { 'Tools': dict( rating=5, comment='Excellent tool, easy to use.', approved='yes', private='no' ) }
self.review_repository( repository, review_contents_dict, test_db_util.get_user( common.test_user_2_email ) )
def test_0075_verify_tools_review( self ):
- '''Verify that the datatypes component review displays correctly.'''
+ '''Verify that the tools component review displays correctly.'''
+ """
+ We are at step 16.
+ Log in as test_user_1 and verify that the repository component reviews now include a review
+ for the tools component. As before, check for the presence of the comment on this review.
+ """
self.logout()
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
@@ -167,14 +345,40 @@
self.verify_repository_reviews( repository, reviewer=user, strings_displayed=strings_displayed )
def test_0080_review_workflows( self ):
'''Review the workflows component for the current tip revision.'''
+ """
+ We are at step 17.
+ Log in as test_user_2 and update the review with the workflows component marked as 'Not applicable'.
+ # Review this revision:
+ # Data types (N/A)
+ # Functional tests (One star, comment 'functional tests missing')
+ # README (N/A)
+ # Repository dependencies (N/A)
+ # Tool dependencies (N/A)
+ # Tools (5 stars, good review)
+ # Workflows (N/A)
+ """
self.logout()
self.login( email=common.test_user_2_email, username=common.test_user_2_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
user = test_db_util.get_user( common.test_user_2_email )
+ # The create_repository_review method takes a dict( component label=review contents ).
+ # If review_contents is empty, it marks that component as not applicable. The review
+ # contents dict should have the structure:
+ # {
+ # rating: 1-5,
+ # comment: <text>
+ # approved: yes/no
+ # private: yes/no
+ # }
review_contents_dict = { 'Workflows': dict() }
self.review_repository( repository, review_contents_dict, user )
def test_0085_verify_workflows_review( self ):
- '''Verify that the datatypes component review displays correctly.'''
+ '''Verify that the workflows component review displays correctly.'''
+ """
+ We are at step 18.
+ Log in as test_user_1 and verify that the repository component reviews now include a review
+ for the workflows component.
+ """
self.logout()
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
@@ -183,6 +387,11 @@
self.verify_repository_reviews( repository, reviewer=user, strings_displayed=strings_displayed )
def test_0090_upload_readme_file( self ):
'''Upload a readme file to the filtering repository.'''
+ """
+ We are at step 19.
+ Log in as test_user_1, the repository owner, and upload readme.txt to the repository. This will create
+ a new changeset revision for this repository, which will need to be reviewed.
+ """
self.logout()
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
@@ -190,21 +399,42 @@
self.upload_file( repository, 'readme.txt', commit_message="Uploaded readme.txt" )
def test_0095_review_new_changeset_readme_component( self ):
'''Update the filtering repository's readme component review to reflect the presence of the readme file.'''
+ """
+ We are at step 20.
+ There is now a new changeset revision in the repository's changelog, but it has no review associated with it.
+ Get the previously reviewed changeset hash, and pass that and the review id to the create_repository_review
+ method, in order to copy the previous review's contents. Then update the new review to reflect the presence of
+ a readme file.
+ """
self.logout()
self.login( email=common.test_user_2_email, username=common.test_user_2_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
user = test_db_util.get_user( common.test_user_2_email )
- # Get the changeset immediately prior to the tip, and pass it to the create review method.
- changelog = self.get_repository_changelog( repository )
- changeset_revision, ctx_revision = changelog[-2]
- previous_review = test_db_util.get_repository_review_by_user_id_changeset_revision( user.id, repository.id, str( changeset_revision ) )
+ # Get the last changeset revision that has a review associated with it.
+ last_review = self.get_last_reviewed_revision_by_user( user, repository )
+ if last_review is None:
+ raise AssertionError( 'Previous review expected, none found.' )
+ # The create_repository_review method takes a dict( component label=review contents ).
+ # If review_contents is empty, it marks that component as not applicable. The review
+ # contents dict should have the structure:
+ # {
+ # rating: 1-5,
+ # comment: <text>
+ # approved: yes/no
+ # private: yes/no
+ # }
review_contents_dict = { 'README': dict( rating=5, comment='Clear and concise readme file, a true pleasure to read.', approved='yes', private='no' ) }
self.create_repository_review( repository,
review_contents_dict,
changeset_revision=self.get_repository_tip( repository ),
- copy_from=( str( changeset_revision ), previous_review.id ) )
+ copy_from=( str( last_review.changeset_revision ), last_review.id ) )
def test_0100_verify_readme_review( self ):
'''Verify that the readme component review displays correctly.'''
+ """
+ We are at step 21.
+ Log in as the repository owner (test_user_1) and check the repository component reviews to
+ verify that the readme component is now reviewed and approved.
+ """
self.logout()
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
@@ -213,28 +443,51 @@
self.verify_repository_reviews( repository, reviewer=user, strings_displayed=strings_displayed )
def test_0105_upload_test_data( self ):
'''Upload the missing test data to the filtering repository.'''
- self.logout()
- self.login( email=common.test_user_1_email, username=common.test_user_1_name )
+ """
+ We are at step 22.
+ Remain logged in as test_user_1 and upload test data to the repository. This will also create a
+ new changeset revision that needs to be reviewed. This will replace the changeset hash associated with
+ the last dowloadable revision, but the last repository review will still be associated with the
+ last dowloadable revision hash.
+ """
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
user = test_db_util.get_user( common.test_user_2_email )
self.upload_file( repository, 'filtering/filtering_test_data.tar', commit_message="Uploaded test data." )
def test_0110_review_new_changeset_functional_tests( self ):
'''Update the filtering repository's readme component review to reflect the presence of the readme file.'''
+ """
+ We are at step 23.
+ Log in as test_user_2 and get the last reviewed changeset hash, and pass that and the review id to
+ the create_repository_review method, then update the copied review to approve the functional tests
+ component.
+ """
self.logout()
self.login( email=common.test_user_2_email, username=common.test_user_2_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
user = test_db_util.get_user( common.test_user_2_email )
# Get the changeset immediately prior to the tip, and pass it to the create review method.
- changelog = self.get_repository_changelog( repository )
- changeset_revision, ctx_revision = changelog[-2]
- previous_review = test_db_util.get_repository_review_by_user_id_changeset_revision( user.id, repository.id, str( changeset_revision ) )
+ last_review = self.get_last_reviewed_revision_by_user( user, repository )
+ # The create_repository_review method takes a dict( component label=review contents ).
+ # If review_contents is empty, it marks that component as not applicable. The review
+ # contents dict should have the structure:
+ # {
+ # rating: 1-5,
+ # comment: <text>
+ # approved: yes/no
+ # private: yes/no
+ # }
review_contents_dict = { 'Functional tests': dict( rating=5, comment='A good set of functional tests.', approved='yes', private='no' ) }
self.create_repository_review( repository,
review_contents_dict,
changeset_revision=self.get_repository_tip( repository ),
- copy_from=( str( changeset_revision ), previous_review.id ) )
+ copy_from=( str( last_review.changeset_revision ), last_review.id ) )
def test_0115_verify_functional_tests_review( self ):
'''Verify that the functional tests component review displays correctly.'''
+ """
+ We are at step 24.
+ Log in as the repository owner, test_user_1, and verify that the new revision's functional tests component
+ review has been updated with an approved status and favorable comment.
+ """
self.logout()
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
@@ -243,6 +496,11 @@
self.verify_repository_reviews( repository, reviewer=user, strings_displayed=strings_displayed )
def test_0120_upload_new_tool_version( self ):
'''Upload filtering 2.2.0 to the filtering repository.'''
+ """
+ We are at step 25.
+ Log in as test_user_1 and upload a new version of the tool to the filtering repository. This will create
+ a new downloadable revision, with no associated repository component reviews.
+ """
self.logout()
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
@@ -253,22 +511,38 @@
remove_repo_files_not_in_tar='No' )
def test_0125_review_new_changeset_functional_tests( self ):
'''Update the filtering repository's review to apply to the new changeset with filtering 2.2.0.'''
+ """
+ We are at step 26.
+ Log in as test_user_2 and copy the last review for this repository to the new changeset. Then
+ update the tools component review to refer to the new tool version.
+ """
self.logout()
self.login( email=common.test_user_2_email, username=common.test_user_2_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
user = test_db_util.get_user( common.test_user_2_email )
- # Get the changeset immediately prior to the tip, and pass it to the create review method.
- changelog = self.get_repository_changelog( repository )
- changeset_revision, ctx_revision = changelog[-2]
- previous_review = test_db_util.get_repository_review_by_user_id_changeset_revision( user.id, repository.id, str( changeset_revision ) )
+ last_review = self.get_last_reviewed_revision_by_user( user, repository )
# Something needs to change so that the review will save.
+ # The create_repository_review method takes a dict( component label=review contents ).
+ # If review_contents is empty, it marks that component as not applicable. The review
+ # contents dict should have the structure:
+ # {
+ # rating: 1-5,
+ # comment: <text>
+ # approved: yes/no
+ # private: yes/no
+ # }
review_contents_dict = { 'Tools': dict( rating=5, comment='Version 2.2.0 does the impossible and improves this tool.', approved='yes', private='yes' ) }
self.create_repository_review( repository,
review_contents_dict,
changeset_revision=self.get_repository_tip( repository ),
- copy_from=( str( changeset_revision ), previous_review.id ) )
+ copy_from=( str( last_review.changeset_revision ), last_review.id ) )
def test_0135_verify_review_for_new_version( self ):
'''Verify that the reviews display correctly for this changeset revision.'''
+ """
+ We are at step 27.
+ Log in as test_user_1 and check that the tools component review is for filtering 2.2.0, but that the other component
+ reviews had their contents copied from the last reviewed changeset.
+ """
self.logout()
self.login( email=common.test_user_1_email, username=common.test_user_1_name )
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/4b1a5865d413/
changeset: 4b1a5865d413
user: Kyle Ellrott
date: 2013-02-08 01:54:06
summary: Adding variable 'host_url' to provide qualified URL of host to tool help section.
affected #: 1 file
diff -r ce9789a35356da2b2ee4ae723506d5af57a0ce69 -r 4b1a5865d413005668b4a3c2c590c7dddb09205d templates/webapps/galaxy/tool_form.mako
--- a/templates/webapps/galaxy/tool_form.mako
+++ b/templates/webapps/galaxy/tool_form.mako
@@ -345,7 +345,7 @@
tool_help = tool.help
# Help is Mako template, so render using current static path.
- tool_help = tool_help.render( static_path=h.url_for( '/static' ) )
+ tool_help = tool_help.render( static_path=h.url_for( '/static' ), host_url=h.url_for('/', qualified=True) )
# Convert to unicode to display non-ascii characters.
if type( tool_help ) is not unicode:
https://bitbucket.org/galaxy/galaxy-central/commits/3eff396a81d8/
changeset: 3eff396a81d8
user: dannon
date: 2013-02-13 15:47:21
summary: Merged in kellrott/galaxy-central (pull request #119)
Adding variable 'host_url' to provide qualified URL of host to tool help section.
affected #: 1 file
diff -r 2f8989a1a16001e5dfcded4e0526ef3e2d6f55f9 -r 3eff396a81d833a2dcabce2fd34b53badf707984 templates/webapps/galaxy/tool_form.mako
--- a/templates/webapps/galaxy/tool_form.mako
+++ b/templates/webapps/galaxy/tool_form.mako
@@ -345,7 +345,7 @@
tool_help = tool.help
# Help is Mako template, so render using current static path.
- tool_help = tool_help.render( static_path=h.url_for( '/static' ) )
+ tool_help = tool_help.render( static_path=h.url_for( '/static' ), host_url=h.url_for('/', qualified=True) )
# Convert to unicode to display non-ascii characters.
if type( tool_help ) is not unicode:
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: jgoecks: Tool data tables: (a) add spaces between function per PEP8 and (b) add warning when an invalid line is found in tool data table.
by Bitbucket 12 Feb '13
by Bitbucket 12 Feb '13
12 Feb '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/2f8989a1a160/
changeset: 2f8989a1a160
user: jgoecks
date: 2013-02-13 00:44:06
summary: Tool data tables: (a) add spaces between function per PEP8 and (b) add warning when an invalid line is found in tool data table.
affected #: 1 file
diff -r 04b8060562f865fa5b3ec6dac4ecfe590bd3ec07 -r 2f8989a1a16001e5dfcded4e0526ef3e2d6f55f9 lib/galaxy/tools/data/__init__.py
--- a/lib/galaxy/tools/data/__init__.py
+++ b/lib/galaxy/tools/data/__init__.py
@@ -158,6 +158,7 @@
def __init__( self, config_element, tool_data_path ):
super( TabularToolDataTable, self ).__init__( config_element, tool_data_path )
self.configure_and_load( config_element, tool_data_path )
+
def configure_and_load( self, config_element, tool_data_path ):
"""
Configure and load table from an XML element.
@@ -196,11 +197,14 @@
self.missing_index_file = filename
log.warn( "Cannot find index file '%s' for tool data table '%s'" % ( filename, self.name ) )
self.data = all_rows
+
def handle_found_index_file( self, filename ):
self.missing_index_file = None
self.data.extend( self.parse_file_fields( open( filename ) ) )
+
def get_fields( self ):
return self.data
+
def parse_column_spec( self, config_element ):
"""
Parse column definitions, which can either be a set of 'column' elements
@@ -230,14 +234,17 @@
assert 'value' in self.columns, "Required 'value' column missing from column def"
if 'name' not in self.columns:
self.columns['name'] = self.columns['value']
+
def parse_file_fields( self, reader ):
"""
Parse separated lines from file and return a list of tuples.
TODO: Allow named access to fields using the column names.
"""
+ separator_char = (lambda c: '<TAB>' if c == '\t' else c)(self.separator)
+
rval = []
- for line in reader:
+ for i, line in enumerate( reader, start=1 ):
if line.lstrip().startswith( self.comment_char ):
continue
line = line.rstrip( "\n\r" )
@@ -245,6 +252,10 @@
fields = line.split( self.separator )
if self.largest_index < len( fields ):
rval.append( fields )
+ else:
+ log.warn( "Line %i in tool data table '%s' is invalid (HINT: "
+ "'%s' characters must be used to separate fields):\n%s"
+ % ( i, self.name, separator_char, line ) )
return rval
def get_entry( self, query_attr, query_val, return_attr ):
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: inithello: Tool shed functional tests for malformed XML in tool_dependencies.xml.
by Bitbucket 12 Feb '13
by Bitbucket 12 Feb '13
12 Feb '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/04b8060562f8/
changeset: 04b8060562f8
user: inithello
date: 2013-02-12 21:00:28
summary: Tool shed functional tests for malformed XML in tool_dependencies.xml.
affected #: 3 files
diff -r 01e73b11a46f87b03af29581603378b06187051d -r 04b8060562f865fa5b3ec6dac4ecfe590bd3ec07 test/tool_shed/functional/test_0010_repository_with_tool_dependencies.py
--- a/test/tool_shed/functional/test_0010_repository_with_tool_dependencies.py
+++ b/test/tool_shed/functional/test_0010_repository_with_tool_dependencies.py
@@ -63,20 +63,28 @@
'freebayes/sam_fa_indices.loc.sample',
strings_displayed=[],
commit_message='Uploaded tool data table .loc file.' )
- def test_0025_upload_invalid_tool_dependency_xml( self ):
+ def test_0025_upload_malformed_tool_dependency_xml( self ):
+ '''Upload tool_dependencies.xml with bad characters in the readme tag.'''
+ repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
+ self.upload_file( repository,
+ os.path.join( 'freebayes', 'malformed_tool_dependencies', 'tool_dependencies.xml' ),
+ valid_tools_only=False,
+ strings_displayed=[ 'Exception attempting to parse tool_dependencies.xml', 'not well-formed' ],
+ commit_message='Uploaded malformed tool dependency XML.' )
+ def test_0030_upload_invalid_tool_dependency_xml( self ):
'''Upload tool_dependencies.xml defining version 0.9.5 of the freebayes package.'''
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
self.upload_file( repository,
os.path.join( 'freebayes', 'invalid_tool_dependencies', 'tool_dependencies.xml' ),
strings_displayed=[ 'Name, version and type from a tool requirement tag does not match' ],
commit_message='Uploaded invalid tool dependency XML.' )
- def test_0030_upload_valid_tool_dependency_xml( self ):
+ def test_0035_upload_valid_tool_dependency_xml( self ):
'''Upload tool_dependencies.xml defining version 0.9.4_9696d0ce8a962f7bb61c4791be5ce44312b81cf8 of the freebayes package.'''
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
self.upload_file( repository,
os.path.join( 'freebayes', 'tool_dependencies.xml' ),
commit_message='Uploaded valid tool dependency XML.' )
- def test_0035_verify_tool_dependencies( self ):
+ def test_0040_verify_tool_dependencies( self ):
'''Verify that the uploaded tool_dependencies.xml specifies the correct package versions.'''
repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name )
self.display_manage_repository_page( repository,
diff -r 01e73b11a46f87b03af29581603378b06187051d -r 04b8060562f865fa5b3ec6dac4ecfe590bd3ec07 test/tool_shed/functional/test_1010_install_repository_with_tool_dependencies.py
--- a/test/tool_shed/functional/test_1010_install_repository_with_tool_dependencies.py
+++ b/test/tool_shed/functional/test_1010_install_repository_with_tool_dependencies.py
@@ -57,6 +57,11 @@
commit_message="Uploaded invalid_tool_dependencies/tool_dependencies.xml.",
remove_repo_files_not_in_tar='No' )
self.upload_file( repository,
+ os.path.join( 'freebayes', 'malformed_tool_dependencies', 'tool_dependencies.xml' ),
+ valid_tools_only=False,
+ strings_displayed=[ 'Exception attempting to parse tool_dependencies.xml', 'not well-formed' ],
+ commit_message='Uploaded malformed tool dependency XML.' )
+ self.upload_file( repository,
'freebayes/tool_dependencies.xml',
valid_tools_only=False,
commit_message="Uploaded tool_dependencies.xml",
diff -r 01e73b11a46f87b03af29581603378b06187051d -r 04b8060562f865fa5b3ec6dac4ecfe590bd3ec07 test/tool_shed/test_data/freebayes/malformed_tool_dependencies/tool_dependencies.xml
--- /dev/null
+++ b/test/tool_shed/test_data/freebayes/malformed_tool_dependencies/tool_dependencies.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<tool_dependency>
+ <package name="freebayes" version="0.9.5">
+ <install version="1.0">
+ <actions>
+ <action type="shell_command">git clone --recursive git://github.com/ekg/freebayes.git</action>
+ <action type="shell_command">git reset --hard 9696d0ce8a962f7bb61c4791be5ce44312b81cf8</action>
+ <action type="shell_command">make</action>
+ <action type="move_directory_files">
+ <source_directory>bin</source_directory>
+ <destination_directory>$INSTALL_DIR/bin</destination_directory>
+ </action>
+ <action type="set_environment">
+ <environment_variable name="PATH" action="prepend_to">$INSTALL_DIR/bin</environment_variable>
+ </action>
+ </actions>
+ </install>
+ <readme>
+FreeBayes requires g++ and the standard C and C++ development libraries.
+Additionally, cmake is required for building the BamTools API.
+ </readme>
+ </package>
+ <package name="samtools" version="0.2.15">
+ <install version="1.0">
+ <actions>
+ <action type="download_by_url">http://sourceforge.net/projects/samtools/files/samtools/0.1.18/samtools-0.1…</action>
+ <action type="shell_command">sed -i .bak -e 's/-lcurses/-lncurses/g' Makefile</action>
+ <action type="shell_command">make</action>
+ <action type="move_file">
+ <source>samtools</source>
+ <destination>$INSTALL_DIR/bin</destination>
+ </action>
+ <action type="move_file">
+ <source>misc/maq2sam-long</source>
+ <destination>$INSTALL_DIR/bin</destination>
+ </action>
+ <action type="set_environment">
+ <environment_variable name="PATH" action="prepend_to">$INSTALL_DIR/bin</environment_variable>
+ </action>
+ </actions>
+ </install>
+ <readme>
+This readme tag has invalid XML ><
+ </readme>
+ </package>
+</tool_dependency>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: carlfeberhard: Incorporate headless browser testing using CasperJS (casperjs.org) into galaxy functional testing
by Bitbucket 12 Feb '13
by Bitbucket 12 Feb '13
12 Feb '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/01e73b11a46f/
changeset: 01e73b11a46f
user: carlfeberhard
date: 2013-02-12 20:36:48
summary: Incorporate headless browser testing using CasperJS (casperjs.org) into galaxy functional testing
affected #: 7 files
diff -r ba8c49884f7daab5df8b62bd631157058c7ee910 -r 01e73b11a46f87b03af29581603378b06187051d test/casperjs/casperjs_runner.py
--- /dev/null
+++ b/test/casperjs/casperjs_runner.py
@@ -0,0 +1,324 @@
+"""Test runner for casperjs headless browser tests with the Galaxy distribution.
+
+Allows integration of casperjs tests with buildbot, run_functional_tests.sh
+
+Tests can be run in any of the following ways:
+* casperjs mytests.js --url='http://localhost:8080'
+* python casperjs_runner.py
+* nosetests
+* sh run_functional_tests.sh test/casperjs/test_runner
+* sh run_functional_tests.sh
+
+Note: that you can enable (lots) of debugging info using cli options:
+* casperjs usertests.js --url='http://localhost:8080' --verbose=true --logLevel=debug
+
+(see casperjs.org for more information)
+"""
+# -------------------------------------------------------------------- can't do 2.5
+import sys
+( major, minor, micro, releaselevel, serial ) = sys.version_info
+if minor < 6:
+ msg = 'casperjs requires python 2.6 or newer. Using: %s' %( sys.version )
+ try:
+ # if nose is installed do a skip test
+ from nose.plugins.skip import SkipTest
+ raise SkipTest( msg )
+ except ImportError, i_err:
+ raise AssertionError( msg )
+
+# --------------------------------------------------------------------
+import os
+import subprocess
+import json
+import errno
+import re
+
+import unittest
+from server_env import TestEnvironment
+
+import pprint
+import logging
+logging.basicConfig( stream=sys.stderr, name=__name__ )
+log = logging.getLogger( __name__ )
+
+# ==================================================================== MODULE VARS
+_PATH_TO_HEADLESS = 'casperjs'
+
+_TODO = """
+ get data back from js scripts (uploaded files, etc.)
+ use returned json to output list of failed assertions if code == 2
+"""
+
+# ====================================================================
+class HeadlessJSJavascriptError( Exception ):
+ """An error that occurrs in the javascript test file.
+ """
+ pass
+
+class CasperJSTestCase( unittest.TestCase ):
+ """Casper tests running in a unittest framework.
+ """
+ # casper uses a lot of escape codes to colorize output - these capture those and allow removal
+ escape_code_compiled_pattern = None
+ escape_code_pattern = r'\x1b\[[\d|;]+m'
+
+ # info on where to get casper js - shown when the exec can't be found
+ casper_info = """
+ CasperJS is a navigation scripting & testing utility for PhantomJS, written in Javascript.
+ More information is available at: casperjs.org
+ """
+
+ # debugging flag - set to true to have casperjs tests output with --verbose=true and --logLevel=debug
+ debug = False
+ # bit of a hack - this is the beginning of the last string when capserjs --verbose=true --logLevel=debug
+ # use this to get subprocess to stop waiting for output
+ casper_done_str = '[info] [phantom] Done'
+
+ # convert js test results to unittest.TestResults
+ results_adapter = None #CasperJsonToUnittestResultsConverter()
+
+ # ---------------------------------------------------------------- run the js script
+ def run_js_script( self, rel_script_path, *args, **kwargs ):
+ """Start the headless browser tests in a separate process and use both
+ the subprocess return code and the stdout output (formatted as JSON)
+ to determine which tests failed and which passed.
+ """
+ log.debug( 'beginning headless browser tests: %s', rel_script_path )
+ process_command_list = self.build_command_line( rel_script_path, *args, **kwargs )
+ log.debug( 'process_command_list: %s', str( process_command_list ) )
+ try:
+ process = subprocess.Popen( process_command_list, shell=False,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE )
+
+ # output from the browser (stderr only) immediately
+ while process.poll() == None:
+ stderr_msg = process.stderr.readline()
+ stderr_msg = self.strip_escape_codes( stderr_msg.strip() )
+ log.debug( '(%s): %s', rel_script_path, stderr_msg )
+ if stderr_msg.startswith( self.casper_done_str ):
+ break
+
+ # stdout is assumed to have the json test data/results
+ ( stdout_output, stderr_output ) = process.communicate()
+ #log.debug( '%s stdout output:\n%s', rel_script_path, stdout_output )
+ #log.debug( '%s stderr output:\n%s', rel_script_path, stderr_output )
+
+ log.debug( 'process.returncode: %d', process.returncode )
+ if process.returncode == 1:
+ #TODO: this is a fail on first effect
+ raise self.browser_error_to_exception( rel_script_path, stdout_output )
+
+ # couldn't find the headless browser,
+ # provide information (as it won't be included by default with galaxy)
+ except OSError, os_err:
+ if os_err.errno == errno.ENOENT:
+ log.error( 'No path to headless browser executable: %s\n'
+ + 'These tests were designed to use the following headless browser:\n%s',
+ self.exec_path, self.casper_info )
+ raise
+
+ self.handle_js_results( stdout_output )
+
+ def build_command_line( self, rel_script_path, *args, **kwargs ):
+ """Build the headless browser command line list for subprocess.
+ """
+ command_line_list = [ self.exec_path ]
+
+ # make rel_script_path an absolute path (when this is not run from it's dir - i.e. run_functional_tests.sh)
+ curr_dir = os.path.dirname( __file__ )
+ script_path = os.path.join( curr_dir, rel_script_path )
+ command_line_list.append( script_path )
+
+ # let browser know where the server is (from the TestEnvironment created in setUp)
+ command_line_list.append( '--url=' + self.env.url )
+
+ # add the return json only option
+ # - has script send normal output to stderr and results, errors, logs to stdout as json
+ command_line_list.append( '--return-json' )
+
+ # check flag to output (very) verbose debugging messages from casperjs and tests
+ if self.debug:
+ command_line_list.extend([ '--verbose=true', '--logLevel=debug' ])
+
+ #TODO: allow casperjs cli options ('--includes='), ?in args, kwargs?
+ command_line_list.extend( args )
+
+ # send extra data - encode kwargs as json to pass to casper for decoding
+ command_line_list.append( json.dumps( kwargs ) )
+ return command_line_list
+
+ def strip_escape_codes( self, msg ):
+ """Removes colorizing escape codes from casper output strings.
+ """
+ if not self.escape_code_compiled_pattern:
+ self.escape_code_compiled_pattern = re.compile( self.escape_code_pattern )
+ return re.sub( self.escape_code_compiled_pattern, '', msg )
+
+ # ---------------------------------------------------------------- convert js error to python error
+ def browser_error_to_exception( self, script_path, stdout_output ):
+ """Converts the headless' error from JSON into a more informative
+ python HeadlessJSJavascriptError.
+ """
+ get_error = lambda d: d[ 'errors' ][0]
+ get_msg = lambda err: err[ 'msg' ]
+ get_trace = lambda err: err[ 'backtrace' ]
+ try:
+ # assume it's json and located in errors (and first)
+ js_test_results = json.loads( stdout_output )
+ last_error = get_error( js_test_results )
+ err_string = ( "%s\n%s" %( get_msg( last_error ),
+ self.browser_backtrace_to_string( get_trace( last_error ) ) ) )
+
+ # if we couldn't parse json from what's returned on the error, raise a vanilla exc
+ except Exception, exc:
+ log.debug( '(failed to parse error returned from %s: %s)', _PATH_TO_HEADLESS, str( exc ) )
+ return HeadlessJSJavascriptError(
+ "ERROR in headless browser script %s" %( script_path ) )
+
+ # otherwise, raise with msg and backtrace
+ return HeadlessJSJavascriptError( err_string )
+
+ def browser_backtrace_to_string( self, backtrace ):
+ """Converts list of trace dictionaries (as might be returned from
+ json results) to a string similar to a python backtrace.
+ """
+ template = ' File "%s", line %s, in %s'
+ traces = []
+ for trace in backtrace:
+ traces.append( template %( trace[ 'file' ], trace[ 'line' ], trace[ 'function' ] ) )
+ return '\n'.join( traces )
+
+ # ---------------------------------------------------------------- results
+ def handle_js_results( self, results ):
+ """Handle the results of the js tests by either converting them
+ with the results adapter or checking for a failure list.
+ """
+ # if given an adapter - use it
+ if self.results_adapter:
+ self.results_adapter.convert( results, self )
+
+ # - otherwise, assert no failures found
+ else:
+ js_test_results = json.loads( results )
+ failures = js_test_results[ 'testResults' ][ 'failures' ]
+ assert len( failures ) == 0, (
+ "Some assertions failed in the headless browser tests (see the log for details)" )
+
+ # ---------------------------------------------------------------- TestCase overrides
+ def setUp( self ):
+ # set up the env for each test
+ self.env = TestEnvironment.instance()
+ self.exec_path = _PATH_TO_HEADLESS
+
+ def run( self, result=None ):
+ # wrap this in order to save ref to result
+ #TODO: gotta be a better way
+ self.result = result
+ unittest.TestCase.run( self, result=result )
+
+
+# ==================================================================== RESULTS CONVERSION
+class CasperJsonToUnittestResultsConverter( object ):
+ """Convert casper failures, success to individual unittest.TestResults
+ """
+ #TODO: So far I can add result instances - but each has the id, shortDescription
+ # of the TestCase.testMethod that called it. Can't find out how to change these.
+
+ def convert( self, json_results, test ):
+ """Converts JSON test results into unittest.TestResults.
+
+ precondition: test should have attribute 'result' which
+ is a unittest.TestResult (for that test).
+ """
+ results_dict = json.loads( json_results )
+ failures = results_dict[ 'testResults' ][ 'failures' ]
+ passes = results_dict[ 'testResults' ][ 'passes' ]
+ self.add_json_failures_to_results( failures, test )
+ self.add_json_successes_to_results( passes, test )
+
+ def add_json_failures_to_results( self, failures, test ):
+ """Converts JSON test failures.
+ """
+ #precondition: result should be an attr of test (a TestResult)
+ #TODO: no way to change test.desc, name in output?
+ for failure in failures:
+ #TODO: doesn't change shortDescription
+ #if 'standard' in failure:
+ # self.__doc__ = failure[ 'standard' ]
+ test.result.addFailure( test, self.casper_failure_to_unittest_failure( failure ) )
+ test.result.testsRun += 1
+
+ def casper_failure_to_unittest_failure( self, casper_failure, failure_class=AssertionError ):
+ """Returns a casper test failure (in dictionary form) as a 3-tuple of
+ the form used by unittest.TestResult.addFailure.
+
+ Used to add failures to a casperjs TestCase.
+ """
+ #TODO: this is all too elaborate
+ fail_type = casper_failure[ 'type' ]
+ values = json.dumps( casper_failure[ 'values' ] )
+ desc = casper_failure[ 'standard' ]
+ if 'messgae' in casper_failure:
+ desc = capser_failure[ 'message' ]
+ failure_msg = "(%s) %s: %s" %( fail_type, desc, values )
+ #TODO: tb is empty ([]) - can we get file info from casper, covert to py trace?
+ return ( failure_class, failure_msg, [] )
+
+ def add_json_successes_to_results( self, successes, test ):
+ """Converts JSON test successes.
+ """
+ for success in successes:
+ ## attempt to re-write test result description - doesn't work
+ #if 'standard' in success:
+ # self.__doc__ = success[ 'standard' ]
+ test.result.addSuccess( test )
+ test.result.testsRun += 1
+
+
+# ==================================================================== MODULE FIXTURE
+#NOTE: nose will run these automatically
+def setup_module():
+ log.debug( '\n--------------- setting up module' )
+
+def teardown_module():
+ log.debug( '\n--------------- tearing down module' )
+
+
+# ==================================================================== TESTCASE EXAMPLE
+# these could be broken out into other files - shouldn't be necc. ATM
+class UserTests( CasperJSTestCase ):
+ """TestCase that uses javascript and a headless browser to test dynamic pages.
+ """
+ def test_10_registration( self ):
+ """User registration tests: register new user, logout, attempt bad registrations.
+ """
+ # all keywords will be compiled into a single JSON obj and passed to the server
+ self.run_js_script( 'registration-tests.js', self.env.url,
+ testuser={ 'email': 'test1(a)test.test', 'password': '123456' })
+ #TODO:?? could theoretically do db cleanup, checks here with SQLALX
+ #TODO: have run_js_script return other persistant fixture data (uploaded files, etc.)
+
+ def test_20_login( self ):
+ """User log in tests.
+ """
+ self.run_js_script( 'login-tests.js', self.env.url,
+ testuser={ 'email': 'test1(a)test.test', 'password': '123456' })
+
+
+class ToolTests( CasperJSTestCase ):
+ """(Minimal) casperjs tests for tools.
+ """
+ #debug = True
+ def test_10_upload( self ):
+ """Tests uploading files
+ """
+ self.run_js_script( 'upload-tests.js' )
+
+
+# ==================================================================== MAIN
+if __name__ == '__main__':
+ log.setLevel( logging.DEBUG )
+ setup_module()
+ #TODO: server_env config doesn't work with unittest's lame main fn
+ unittest.main()
+ # teardown_module() isn't called when unittest.main is used
diff -r ba8c49884f7daab5df8b62bd631157058c7ee910 -r 01e73b11a46f87b03af29581603378b06187051d test/casperjs/login-tests.js
--- /dev/null
+++ b/test/casperjs/login-tests.js
@@ -0,0 +1,142 @@
+// have to handle errors here - or phantom/casper won't bail but _HANG_
+//TODO: global error handler?
+try {
+ var utils = require( 'utils' ),
+ xpath = require( 'casper' ).selectXPath,
+ format = utils.format,
+
+ //...if there's a better way - please let me know, universe
+ scriptDir = require( 'system' ).args[3]
+ // remove the script filename
+ .replace( /[\w|\.|\-|_]*$/, '' )
+ // if given rel. path, prepend the curr dir
+ .replace( /^(?!\/)/, './' ),
+ spaceghost = require( scriptDir + 'spaceghost' ).create({
+ // script options here (can be overridden by CLI)
+ //verbose: true,
+ //logLevel: debug,
+ scriptDir: scriptDir
+ });
+
+ spaceghost.start();
+
+} catch( error ){
+ console.debug( error );
+ phantom.exit( 1 );
+}
+
+// ===================================================================
+/* TODO:
+ move selectors and assertText strings into global object for easier editing
+
+
+*/
+// =================================================================== globals and helpers
+var email = spaceghost.getRandomEmail(),
+ password = '123456';
+if( spaceghost.fixtureData.testUser ){
+ email = spaceghost.fixtureData.testUser.email;
+ password = spaceghost.fixtureData.testUser.password;
+}
+
+// =================================================================== TESTS
+spaceghost.thenOpen( spaceghost.baseUrl, function(){
+ this.test.comment( 'loading galaxy homepage' );
+ // can we load galaxy?
+ this.test.assertTitle( 'Galaxy' );
+});
+
+// ------------------------------------------------------------------- should work
+
+// register a user (again...)
+spaceghost.then( function(){
+ this.test.comment( 'registering: ' + email );
+ spaceghost.registerUser( email, password );
+});
+// capture a sshot
+//spaceghost.then( function(){
+// this.clickLabel( 'User' );
+// this.capture( 'register.png' );
+//});
+
+// log them out - check for empty logged in text
+spaceghost.then( function(){
+ this.test.comment( 'logging out: ' + email );
+ spaceghost.logout();
+});
+spaceghost.then( function(){
+ this.test.assertSelectorDoesntHaveText(
+ xpath( '//a[contains(text(),"Logged in as")]/span["id=#user-email"]' ), /\w/ );
+ this.test.assert( spaceghost.loggedInAs() === '', 'loggedInAs() is empty string' );
+});
+
+// log them back in - check for email in logged in text
+spaceghost.then( function(){
+ this.test.comment( 'logging back in: ' + email );
+ spaceghost._submitLogin( email, password ); //No such user
+});
+spaceghost.then( function(){
+ this.test.assertSelectorHasText(
+ xpath( '//a[contains(text(),"Logged in as")]/span["id=#user-email"]' ), email );
+ this.test.assert( spaceghost.loggedInAs() === email, 'loggedInAs() matches email' );
+});
+
+// finally log back out for next tests
+spaceghost.then( function(){
+ this.test.comment( 'logging out: ' + email );
+ spaceghost.logout();
+});
+
+// ------------------------------------------------------------------- shouldn't work
+// can't log in: users that don't exist, bad emails, sql injection (hurhur)
+var badEmails = [ 'test2(a)test.org', 'test', '', "'; SELECT * FROM galaxy_user WHERE 'u' = 'u';" ];
+spaceghost.each( badEmails, function( self, badEmail ){
+ self.then( function(){
+ this.test.comment( 'attempting bad email: ' + badEmail );
+ this._submitLogin( badEmail, password );
+ });
+ self.then(function(){
+ this.assertErrorMessage( 'No such user' );
+ });
+});
+
+// can't use passwords that wouldn't be accepted in registration
+var badPasswords = [ '1234', '', '; SELECT * FROM galaxy_user' ];
+spaceghost.each( badPasswords, function( self, badPassword ){
+ self.then( function(){
+ this.test.comment( 'attempting bad password: ' + badPassword );
+ this._submitLogin( email, badPassword );
+ });
+ self.then(function(){
+ this.assertErrorMessage( 'Invalid password' );
+ });
+});
+
+// ------------------------------------------------------------------- test yoself
+// these versions are for conv. use in other tests, they should throw errors if used improperly
+spaceghost.then( function(){
+ this.assertStepsRaise( 'GalaxyError: LoginError', function(){
+ this.then( function(){
+ this.test.comment( 'testing (js) error thrown on bad email' );
+ this.login( 'nihilist', '1234' );
+ });
+ });
+});
+
+spaceghost.then( function(){
+ this.assertStepsRaise( 'GalaxyError: LoginError', function(){
+ this.then( function(){
+ this.test.comment( 'testing (js) error thrown on bad password' );
+ this.login( email, '1234' );
+ });
+ });
+});
+
+spaceghost.then( function(){
+ this.logout();
+});
+
+// ===================================================================
+spaceghost.run( function(){
+ this.test.done();
+});
diff -r ba8c49884f7daab5df8b62bd631157058c7ee910 -r 01e73b11a46f87b03af29581603378b06187051d test/casperjs/registration-tests.js
--- /dev/null
+++ b/test/casperjs/registration-tests.js
@@ -0,0 +1,182 @@
+// have to handle errors here - or phantom/casper won't bail but _HANG_
+try {
+ var utils = require( 'utils' ),
+ xpath = require( 'casper' ).selectXPath,
+ format = utils.format,
+
+ //...if there's a better way - please let me know, universe
+ scriptDir = require( 'system' ).args[3]
+ // remove the script filename
+ .replace( /[\w|\.|\-|_]*$/, '' )
+ // if given rel. path, prepend the curr dir
+ .replace( /^(?!\/)/, './' ),
+ spaceghost = require( scriptDir + 'spaceghost' ).create({
+ // script options here (can be overridden by CLI)
+ //verbose: true,
+ //logLevel: debug,
+ scriptDir: scriptDir
+ });
+
+ spaceghost.start();
+
+} catch( error ){
+ console.debug( error );
+ phantom.exit( 1 );
+}
+
+
+// ===================================================================
+/* TODO:
+ move selectors and assertText strings into global object for easier editing
+ pass email, etc. for first (successful) registration (for use with other tests)
+
+
+*/
+// =================================================================== globals and helpers
+var email = spaceghost.getRandomEmail(),
+ password = '123456',
+ confirm = password,
+ username = 'test' + Date.now();
+
+// =================================================================== TESTS
+spaceghost.thenOpen( spaceghost.baseUrl, function(){
+ this.test.comment( 'loading galaxy homepage' );
+ // can we load galaxy?
+ this.test.assertTitle( 'Galaxy' );
+ // xpath selector use:
+ this.test.assertExists( xpath( "//div[@id='masthead']" ), 'found masthead' );
+});
+
+// failing tests for...testing...the tests
+//spaceghost.thenOpen( spaceghost.baseUrl, function(){
+// this.test.comment( 'loading galaxy homepage' );
+// // can we load galaxy?
+// this.test.assertTitle( 'Blorgo' );
+// // xpath selector use:
+// this.test.assertExists( xpath( "//div[@id='facebook']" ), 'found facebook' );
+//});
+
+
+// ------------------------------------------------------------------- register a new user
+spaceghost.then( function(){
+ this.test.comment( 'registering user: ' + email );
+ this._submitUserRegistration( email, password, username, confirm );
+});
+spaceghost.thenOpen( spaceghost.baseUrl, function(){
+ this.clickLabel( 'User' );
+ this.test.assertSelectorHasText( 'a #user-email', email, '#user-email === ' + email );
+});
+
+
+// ------------------------------------------------------------------- log out that user
+spaceghost.then( function(){
+ this.test.comment( 'logging out user: ' + email );
+ this.logout();
+});
+spaceghost.then( function(){
+ this.debug( 'email:' + this.getElementInfo( 'a #user-email' ).html );
+ this.test.assert( !this.getElementInfo( 'a #user-email' ).html, '#user-email is empty' );
+});
+
+
+// ------------------------------------------------------------------- bad user registrations
+spaceghost.then( function(){
+ this.test.comment( 'attempting to re-register user: ' + email );
+ this._submitUserRegistration( email, password, username, confirm );
+});
+spaceghost.then(function(){
+ this.assertErrorMessage( 'User with that email already exists' );
+});
+
+// emails must be in the form -(a)-.- (which is an email on main, btw)
+var badEmails = [ 'bob', 'bob@', 'bob@idontwanttocleanup', 'bob.cantmakeme' ];
+spaceghost.each( badEmails, function( self, badEmail ){
+ self.then( function(){
+ this.test.comment( 'attempting bad email: ' + badEmail );
+ this._submitUserRegistration( badEmail, password, username, confirm );
+ });
+ self.then(function(){
+ this.assertErrorMessage( 'Enter a real email address' );
+ });
+});
+
+// passwords must be at least 6 chars long
+var badPasswords = [ '1234' ];
+spaceghost.each( badPasswords, function( self, badPassword ){
+ self.then( function(){
+ this.test.comment( 'attempting bad password: ' + badPassword );
+ this._submitUserRegistration( spaceghost.getRandomEmail(), badPassword, username, confirm );
+ });
+ self.then(function(){
+ this.assertErrorMessage( 'Use a password of at least 6 characters' );
+ });
+});
+
+// and confirm must match
+var badConfirms = [ '1234', '12345678', '123456 7', '' ];
+spaceghost.each( badConfirms, function( self, badConfirm ){
+ self.then( function(){
+ this.test.comment( 'attempting bad password confirmation: ' + badConfirm );
+ this._submitUserRegistration( spaceghost.getRandomEmail(), password, username, badConfirm );
+ });
+ self.then(function(){
+ this.assertErrorMessage( 'Passwords do not match' );
+ });
+});
+
+// usernames must be >=4 chars...
+//NOTE: that short username errors only show AFTER checking for existing/valid emails
+// so: we need to generate new emails for each one
+spaceghost.then( function(){
+ var newEmail = spaceghost.getRandomEmail(),
+ badUsername = 'bob';
+ this.test.comment( 'attempting short username: ' + badUsername );
+ this._submitUserRegistration( newEmail, password, badUsername, confirm );
+});
+spaceghost.then(function(){
+ this.assertErrorMessage( 'Public name must be at least 4 characters in length' );
+});
+
+// ...and be lower-case letters, numbers and '-'...
+var badUsernames = [ 'BOBERT', 'Robert Paulson', 'bobert!', 'bob_dobbs' ];
+spaceghost.each( badUsernames, function( self, badUsername ){
+ self.then( function(){
+ var newEmail = spaceghost.getRandomEmail();
+ this.test.comment( 'attempting bad username: ' + badUsername );
+ this._submitUserRegistration( newEmail, password, badUsername, confirm );
+ });
+ self.then(function(){
+ this.assertErrorMessage( "Public name must contain only lower-case letters, numbers and '-'" );
+ });
+});
+
+// ...and the name can't be used already
+spaceghost.then( function(){
+ var newEmail = spaceghost.getRandomEmail();
+ this.test.comment( 'attempting previously used username with new user: ' + newEmail );
+ this._submitUserRegistration( newEmail, password, username, confirm );
+});
+spaceghost.then(function(){
+ this.assertErrorMessage( 'Public name is taken; please choose another' );
+});
+
+
+// ------------------------------------------------------------------- test the tests
+// these versions are for conv. use in other tests, they should throw errors if used improperly
+spaceghost.then( function(){
+ this.assertStepsRaise( 'GalaxyError: RegistrationError', function(){
+ this.then( function(){
+ this.test.comment( 'testing (js) error thrown on bad email' );
+ this.registerUser( '@internet', '123456', 'ignobel' );
+ });
+ });
+});
+
+spaceghost.then( function(){
+ this.logout();
+});
+
+// ===================================================================
+spaceghost.run( function(){
+ this.test.done();
+});
diff -r ba8c49884f7daab5df8b62bd631157058c7ee910 -r 01e73b11a46f87b03af29581603378b06187051d test/casperjs/server_env.py
--- /dev/null
+++ b/test/casperjs/server_env.py
@@ -0,0 +1,97 @@
+"""
+Classes to handle fetching the proper environment and urls for the selenium
+tests to run against.
+"""
+
+import os
+import logging
+log = logging.getLogger( __name__ )
+
+class TestEnvironment( object ):
+ """Provides basic information on the server being tested.
+
+ Implemented as a singleton class so that it may persist between tests
+ without needing to be reset/re-created.
+ """
+ _instance = None
+
+ ENV_PROTOCOL = None
+ ENV_HOST = 'GALAXY_TEST_HOST'
+ ENV_PORT = 'GALAXY_TEST_PORT'
+ ENV_HISTORY_ID = 'GALAXY_TEST_HISTORY_ID'
+ ENV_FILE_DIR = 'GALAXY_TEST_FILE_DIR'
+ ENV_TOOL_SHED_TEST_FILE = 'GALAXY_TOOL_SHED_TEST_FILE'
+ ENV_SAVED_FILES_DIR = 'GALAXY_TEST_SAVE'
+
+ DEFAULT_PROTOCOL = 'http'
+ DEFAULT_HOST = 'localhost'
+ DEFAULT_PORT = '8080'
+
+ @classmethod
+ def instance( cls, config=None ):
+ # singleton pattern
+ if( ( not cls._instance )
+ or ( config ) ):
+ log.debug( 'creating singleton instance of "%s", config: %s', str( cls ), str( config ) )
+ cls._instance = cls( config )
+ return cls._instance
+
+ @classmethod
+ def get_server_url( cls ):
+ return cls.instance().url
+
+ def __init__( self, env_config_dict=None ):
+ self.config = env_config_dict or {}
+
+ self.protocol = self._get_setting_from_config_or_env( 'protocol', self.ENV_PROTOCOL, self.DEFAULT_PROTOCOL )
+ self.host = self._get_setting_from_config_or_env( 'host', self.ENV_HOST, self.DEFAULT_HOST )
+ self.port = self._get_setting_from_config_or_env( 'port', self.ENV_PORT, self.DEFAULT_PORT )
+
+ self.history_id = self._get_setting_from_config_or_env( 'history_id', self.ENV_HISTORY_ID, default=None )
+ self.file_dir = self._get_setting_from_config_or_env( 'file_dir', self.ENV_FILE_DIR, default=None )
+
+ self.tool_shed_test_file = self._get_setting_from_config_or_env(
+ 'tool_shed_test_file', self.ENV_TOOL_SHED_TEST_FILE, default=None )
+ self.shed_tools_dict = self._get_shed_tools_dict()
+
+ self.keepOutdir = self._get_setting_from_config_or_env( 'keepOutdir', self.ENV_SAVED_FILES_DIR, default=None )
+ self._init_saved_files_dir()
+
+ def _get_setting_from_config_or_env( self, config_name, env_name, default=False ):
+ """Try to get a setting from (in order):
+ TestEnvironment.config, the os env, or some default (if not False).
+ """
+ config = self.config.get( config_name, None )
+ env = os.environ.get( env_name, None )
+ if( ( not ( config or env ) )
+ and ( default == False ) ):
+ raise AttributeError( '"%s" was not set via config or %s or default' %( config_name, env_name ) )
+ return config or env or default
+
+ def _get_shed_tools_dict( self ):
+ """Read the shed tools from the tool shed test file if given,
+ otherwise an empty dict.
+ """
+ if self.tool_shed_test_file:
+ f = open( self.tool_shed_test_file, 'r' )
+ text = f.read()
+ f.close()
+ return from_json_string( text )
+ else:
+ return {}
+
+ def _init_saved_files_dir( self ):
+ """Set up the desired directory to save test output
+ """
+ if self.keepOutdir > '':
+ try:
+ os.makedirs( self.keepOutdir )
+ except:
+ log.debug( 'unable to create saved files directory: %s' %( self.keepOutDir ) )
+
+ @property
+ def url( self ):
+ url = '%s://%s' %( self.protocol, self.host )
+ if self.port and self.port != 80:
+ url += ':%s' %( str( self.port ) )
+ return url
diff -r ba8c49884f7daab5df8b62bd631157058c7ee910 -r 01e73b11a46f87b03af29581603378b06187051d test/casperjs/spaceghost.js
--- /dev/null
+++ b/test/casperjs/spaceghost.js
@@ -0,0 +1,1030 @@
+/* TODO:
+ Use in test command
+
+ bug: assertStepsRaise raise errors (all the way) when used in 'casperjs test .'
+
+ Does it run:
+ casperjs usertests.js --url='http://localhost:8080'
+ casperjs usertests.js --url='http://localhost:8080' --return-json
+ casperjs usertests.js --url='http://localhost:8080' --verbose=true --logLevel=debug
+ casperjs test test/casperjs --url='http://localhost:8080'
+ python casperjs_runner.py
+ nosetests
+ sh run_functional_tests.sh test/casperjs/
+ sh run_functional_tests.sh
+ (buildbot)
+
+ BUGS:
+ echo doesn't seem to work with python
+ trace not showing for errors here
+
+ what if:
+ does an error saving a sshot bail the entire suite?
+
+ Do the above handle:
+ test script errors
+ page errors (evaluate, find element, etc.)
+ failures
+ passes
+ python errors
+
+ Does test_runner:
+ aggregate properly (passes, failures)
+ fail on first = false
+
+ Test:
+ screenshotting
+ save html/sshots to GALAXY_TEST_SAVE (test_runner)
+
+ can we pass the entire test_env (instead of just url) from test_runner to sg?
+ support method chaining pattern
+ move selectors, text to class level (spaceghost)
+
+ modules?
+ May want to move common functions into PageObject-like subs of sg, e.g.:
+ spaceghost.loginPage.logout()
+ spaceghost.masthead.userMenu().login() // to click User -> Login
+
+ more conv. functions:
+ withMainFrame( callback )
+ getMessageInfo returns *message elementInfo or null
+
+ frames in casper are a PITA (as are steps in gen.): is there a better way to select within a frame w/o a step?
+ waitFor (with progress and finally): a gen. form of waitForHdaState
+
+*/
+// ===================================================================
+/** Extended version of casper object for use with Galaxy
+ */
+
+// ------------------------------------------------------------------- modules
+var Casper = require( 'casper' ).Casper;
+var utils = require( 'utils' );
+
+// ------------------------------------------------------------------- inheritance
+/**
+ */
+function SpaceGhost(){
+ SpaceGhost.super_.apply( this, arguments );
+ this.init.apply( this, arguments );
+}
+utils.inherits( SpaceGhost, Casper );
+
+//console.debug( 'CasperError:' + CasperError );
+
+// ------------------------------------------------------------------- error types
+PageError.prototype = new CasperError();
+PageError.prototype.constructor = CasperError;
+function PageError(){
+ CasperError.apply( this, arguments );
+ this.name = "PageError";
+}
+
+GalaxyError.prototype = new CasperError();
+GalaxyError.prototype.constructor = CasperError;
+function GalaxyError(){
+ CasperError.apply( this, arguments );
+ this.name = "GalaxyError";
+}
+
+AlertError.prototype = new CasperError();
+AlertError.prototype.constructor = CasperError;
+function AlertError(){
+ CasperError.apply( this, arguments );
+ this.name = "AlertError";
+}
+
+// =================================================================== METHODS / OVERRIDES
+// ------------------------------------------------------------------- set up
+/** More initialization: cli, event handlers, etc.
+ * @param {Object} options option hash
+ */
+SpaceGhost.prototype.init = function init( options ){
+ //console.debug( 'init, options:', JSON.stringify( options, null, 2 ) );
+
+ //NOTE: cli will override in-script options
+ this._setOptionsFromCli();
+
+ // save errors for later output (needs to go before process CLI)
+ this.errors = [];
+ this.on( 'error', function( msg, backtrace ){
+ //this.debug( 'adding error to stack: ' + msg + ', trace:' + JSON.stringify( backtrace, null, 2 ) );
+ this.errors.push({ msg: msg, backtrace: backtrace });
+ });
+ this._processCLIArguments();
+ this._setUpEventHandlers();
+
+ // inject these scripts by default
+ this.debug( 'this.options.scriptDir:' + this.options.scriptDir );
+ this.options.clientScripts = [
+ this.options.scriptDir + '../../static/scripts/libs/jquery/jquery.js'
+ //...
+ ].concat( this.options.clientScripts );
+ this.debug( 'clientScripts:\n' + this.jsonStr( this.options.clientScripts ) );
+
+};
+
+/** Allow CLI arguments to set options if the proper option name is used.
+ * @example:
+ * casperjs myscript.js --verbose=true --logLevel=debug
+ */
+SpaceGhost.prototype._setOptionsFromCli = function setOptionsFromCli(){
+ // get and remove any casper options passed on the command line
+ for( var optionName in this.options ){
+ if( this.cli.has( optionName ) ){
+ //console.debug( optionName + ':' + this.options[ optionName ] + ',' + this.cli.get( optionName ) );
+ this.options[ optionName ] = this.cli.get( optionName );
+ this.cli.drop( optionName );
+ }
+ }
+};
+
+// ------------------------------------------------------------------- cli args and options
+SpaceGhost.prototype._saveHtmlOnErrorHandler = function _saveHtmlOnErrorHandler( msg, backtrace ){
+ // needs to output to a file in GALAXY_SAVE
+ //this.debugHTML();
+};
+
+SpaceGhost.prototype._saveTextOnErrorHandler = function _saveTextOnErrorHandler( msg, backtrace ){
+ // needs to output to a file in GALAXY_SAVE
+ //this.debugPage();
+};
+
+SpaceGhost.prototype._saveScreenOnErrorHandler = function _saveScreenOnErrorHandler( msg, backtrace ){
+ // needs to output to a pic in GALAXY_SAVE
+ //var filename = ...??
+ //?? this.getCurrentUrl(), this.getCurrent
+ //this.capture( filename );
+};
+
+
+/** Set up any SG specific options passed in on the cli.
+ */
+SpaceGhost.prototype._processCLIArguments = function _processCLIArguments(){
+ //TODO: init these programmitically
+ var CLI_OPTIONS = {
+ returnJsonOnly : { defaultsTo: false, flag: 'return-json', help: 'send output to stderr, json to stdout' },
+ raisePageError : { defaultsTo: true, flag: 'page-error', help: 'raise errors thrown on the page' },
+ errorOnAlert : { defaultsTo: false, flag: 'error-on-alert', help: 'throw errors when a page calls alert' },
+ failOnAlert : { defaultsTo: true, flag: 'fail-on-alert', help: 'fail a test when a page calls alert' }
+ //screenOnError : { defaultsTo: false, flag: 'error-screen', help: 'capture a screenshot on a page error' },
+ //textOnError : { defaultsTo: false, flag: 'error-text', help: 'output page text on a page error' },
+ //htmlOnError : { defaultsTo: false, flag: 'error-html', help: 'output page html on a page error' }
+ };
+
+ // --url parameter required (the url of the server to test with)
+ if( !this.cli.has( 'url' ) ){
+ this.die( 'Test server URL is required - ' +
+ 'Usage: capserjs <test_script.js> --url=<test_server_url>', 1 );
+ }
+ this.baseUrl = this.cli.get( 'url' );
+
+ // --return-json: supress all output except for JSON logs, test results, and errors at finish
+ // this switch allows a testing suite to send JSON data back via stdout (w/o logs, echos interferring)
+ this.options.returnJsonOnly = CLI_OPTIONS.returnJsonOnly.defaultsTo;
+ if( this.cli.has( CLI_OPTIONS.returnJsonOnly.flag ) ){
+ this.options.returnJsonOnly = true;
+
+ //this._suppressOutput();
+ this._redirectOutputToStderr();
+
+ // output json on fail-first error
+ this.on( 'error', function( msg, backtrace ){
+ //console.debug( 'return-json caught error' );
+ if( spaceghost.options.exitOnError ){
+ this.outputStateAsJson();
+ spaceghost.exit( 1 );
+ }
+ });
+ // non-error finshes/json-output are handled in run() for now
+ }
+
+ // --error-on-alert=false: don't throw an error if the page calls alert (default: true)
+ this.options.raisePageError = CLI_OPTIONS.raisePageError.defaultsTo;
+ if( this.cli.has( CLI_OPTIONS.raisePageError.flag ) ){
+ this.options.raisePageError = this.cli.get( CLI_OPTIONS.raisePageError.flag );
+ }
+
+ // --error-on-alert=false: don't throw an error if the page calls alert (default: true)
+ this.options.errorOnAlert = CLI_OPTIONS.errorOnAlert.defaultsTo;
+ if( this.cli.has( CLI_OPTIONS.errorOnAlert.flag ) ){
+ this.options.errorOnAlert = this.cli.get( CLI_OPTIONS.errorOnAlert.flag );
+ }
+
+ // --fail-on-alert=false: don't fail a test if the page calls alert (default: true)
+ this.options.failOnAlert = CLI_OPTIONS.failOnAlert.defaultsTo;
+ if( this.cli.has( CLI_OPTIONS.failOnAlert.flag ) ){
+ this.options.failOnAlert = this.cli.get( CLI_OPTIONS.failOnAlert.flag );
+ }
+
+ /* not implemented
+ // --error-page: print the casper.debugPage (the page's text) output on an error
+ if( this.cli.has( 'error-page' ) ){
+ this.on( 'page.error', this._saveTextOnErrorHandler );
+
+ // --error-html: print the casper.debugHTML (the page's html) output on an error (mut.exc w error-text)
+ } else if( this.cli.has( 'error-html' ) ){
+ this.on( 'page.error', this._saveHtmlOnErrorHandler );
+ }
+
+ // --error-screen: print the casper.debugPage (the page's text) output on an error
+ if( this.cli.has( 'error-screen' ) ){
+ this.on( 'page.error', this._saveScreenOnErrorHandler );
+ }
+ */
+
+ // get any fixture data passed in as JSON in args
+ // (NOTE: currently the 2nd arg (with the url being 1st?)
+ this.fixtureData = ( this.cli.has( 1 ) )?( JSON.parse( this.cli.get( 1 ) ) ):( {} );
+ this.debug( 'fixtureData:' + this.jsonStr( this.fixtureData ) );
+
+};
+
+/** Suppress the normal output from the casper object (echo, errors)
+ */
+SpaceGhost.prototype._suppressOutput = function _suppressOutput(){
+ // currently (1.0) the only way to suppress test pass/fail messages
+ // (no way to re-route to log either - circular)
+ this.echo = function( msg ){};
+
+ //this.removeListener( 'error', this.listeners( 'error' )[0] );
+ // clear the casper listener that outputs formatted error messages
+ this.removeListener( 'error', this.listeners( 'error' )[1] );
+};
+
+/** Suppress the normal output from the casper object (echo, errors)
+ */
+SpaceGhost.prototype._redirectOutputToStderr = function _redirectOutputToStderr(){
+ // currently (1.0) the only way to suppress test pass/fail messages
+ // (no way to re-route to log either - circular)
+ var spaceghost = this;
+ this.echo = function( msg ){
+ spaceghost.stderr( msg );
+ };
+
+ //this.removeListener( 'error', this.listeners( 'error' )[0] );
+ // clear the casper listener that outputs formatted error messages
+ this.removeListener( 'error', this.listeners( 'error' )[1] );
+};
+
+/** Outputs logs, test results and errors in a single JSON formatted object.
+ */
+SpaceGhost.prototype.outputStateAsJson = function outputStateAsJson(){
+ var returnedJSON = {
+ logs: this.result,
+ testResults: this.test.testResults,
+ errors: this.errors
+ };
+ // use phantomjs console since echo can't be used (suppressed - see init)
+ console.debug( JSON.stringify( returnedJSON, null, 2 ) );
+};
+
+
+// ------------------------------------------------------------------- event handling
+//note: using non-anon fns to allow removal if needed
+// most of these are stubs (w logging) for later expansion
+
+/** Event handler for failed page loads
+ */
+SpaceGhost.prototype._loadFailedHandler = function _loadFailedHandler( object ){
+ this.error( 'load.failed: ' + spaceghost.jsonStr( object ) );
+ //TODO: throw error?
+};
+
+/** Event handler for page errors (js) - throws test scope as PageError
+ * NOTE: this has some special handling for DOM exc 12 which some casper selectors are throwing
+ * (even tho the selector still works)
+ */
+SpaceGhost.prototype._pageErrorHandler = function _pageErrorHandler( msg, backtrace ){
+ // add a page error handler to catch page errors (what we're most interested with here)
+ // normally, casper seems to let these pass unhandled
+ //console.debug( 'page.error:' + msg );
+
+ //TODO:!! lots of casper selectors are throwing this - even tho they still work
+ if( msg === 'SYNTAX_ERR: DOM Exception 12: An invalid or illegal string was specified.' ){
+ void( 0 ); // no op
+
+ } else if( this.options.raisePageError ){
+ //console.debug( '(page) Error: ' + msg );
+ //this.bypassOnError = true;
+
+ // ugh - these bounce back and forth between here and phantom.page.onError
+ // if we don't do this replace you end up with 'PageError: PageError: PageError: ...'
+ // I haven't found a great way to prevent the bouncing
+ msg = msg.replace( 'PageError: ', '' );
+ throw new PageError( msg, backtrace );
+ }
+};
+
+/** Event handler for console messages from the page.
+ */
+SpaceGhost.prototype._pageConsoleHandler = function _pageConsoleHandler(){
+ // remote.message
+ var DELIM = '-';
+ this.debug( this + '(page console) "' + Array.prototype.join.call( arguments, DELIM ) + '"' );
+};
+
+/** Event handler for alerts
+ */
+SpaceGhost.prototype._alertHandler = function _alertHandler( message ){
+ // casper info level already has outputs these
+ //this.warning( this + '(page alert)\n"' + message + '"' );
+ var ALERT_MARKER = '(page alert) ';
+
+ // either throw an error or fail the test
+ //console.debug( 'this.options.errorOnAlert: ' + this.options.errorOnAlert );
+ this.stderr( 'this.options.failOnAlert: ' + this.options.failOnAlert );
+ if( this.options.errorOnAlert ){
+ throw new PageError( ALERT_MARKER + message );
+
+ } else if( this.options.failOnAlert ){
+ //this.test.fail( ALERT_MARKER + message );
+ //this.test.fail();
+ this.test.assert( false, 'found alert message' );
+ //this.stderr( 'this.options.failOnAlert: ' + this.options.failOnAlert );
+ }
+};
+
+/** Event handler for navigation requested (loading of frames, redirects(?))
+ */
+SpaceGhost.prototype._navHandler = function _navHandler( url, navigationType, navigationLocked, isMainFrame ){
+ this.debug( 'navigation.requested: ' + url );
+};
+
+/** Set up event handlers.
+ */
+SpaceGhost.prototype._setUpEventHandlers = function _setUpEventHandlers(){
+ //console.debug( '_setUpEventHandlers' );
+
+ // ........................ page errors
+ this.on( 'page.error', this._pageErrorHandler );
+ //this.on( 'load.failed', this._loadFailedHandler );
+
+ // ........................ page info/debugging
+ // these are already displayed at the casper info level
+
+ //this.on( 'remote.message', this._pageConsoleHandler );
+ this.on( 'remote.alert', this._alertHandler );
+
+ // these are already displayed at the casper debug level
+ //this.on( 'navigation.requested', this._navHandler );
+
+};
+
+// ------------------------------------------------------------------- page control
+/** An override of casper.open specifically for Galaxy.
+ * (Currently only used to change language headers)
+ */
+SpaceGhost.prototype.open = function open(){
+ //TODO: this can be moved to start (I think...?)
+ //!! override bc phantom has it's lang as 'en-US,*' and galaxy doesn't handle the '*' well (server error)
+ this.page.customHeaders = { 'Accept-Language': 'en-US' };
+ return Casper.prototype.open.apply( this, arguments );
+};
+
+/** An override to provide json output and more informative error codes
+ */
+SpaceGhost.prototype.run = function run( onComplete, time ){
+ // wrap the onComplete to:
+ // return code 2 on test failure
+ // 0 on success
+ // (1 on js error - in error handler)
+ var new_onComplete = function(){
+ onComplete.call( this );
+ var returnCode = ( this.test.testResults.failed )?( 2 ):( 0 );
+
+ // if --return-json is used: output json and exit
+ if( this.options.returnJsonOnly ){
+ this.outputStateAsJson();
+ this.exit( returnCode );
+
+ // otherwise, render the nice casper output and exit
+ } else {
+ this.test.renderResults( true, returnCode );
+ }
+ };
+ Casper.prototype.run.call( this, new_onComplete, time );
+};
+
+/** Install a function as an error handler temporarily, run a function with steps, then remove the handler.
+ * A rough stand-in for try catch with steps.
+ * CatchFn will be passed error's msg and trace.
+ * @param {Function} stepsFn a function that puts casper steps on the stack (then, thenOpen, etc.)
+ * @param {Function} catchFn some portion of the correct error msg
+ */
+SpaceGhost.prototype.tryStepsCatch = function tryStepsCatch( stepsFn, catchFn ){
+ //TODO: * @param {Boolean} removeOtherListeners option to remove other listeners while this fires
+ // create three steps: 1) set up new error handler, 2) try the fn, 3) check for errors and rem. handler
+ var originalExitOnError,
+ errorMsg = '', errorTrace = [],
+ recordError = function( msg, trace ){
+ errorMsg = msg; errorTrace = trace;
+ };
+
+ // dont bail on the error (but preserve option), install hndlr to simply record msg, trace
+ //NOTE: haven't had to remove other listeners yet
+ this.then( function(){
+ originalExitOnError = this.options.exitOnError;
+ this.options.exitOnError = false;
+ this.on( 'error', recordError );
+ });
+
+ // try the step...
+ this.then( stepsFn );
+
+ this.then( function(){
+ // ...and if an error was recorded call the catch with the info
+ if( errorMsg ){
+ catchFn.call( this, errorMsg, errorTrace );
+ }
+ // remove that listener either way and restore the bail option
+ this.removeListener( 'error', recordError );
+ this.options.exitOnError = originalExitOnError;
+ });
+};
+
+
+// =================================================================== TESTING
+//TODO: form fill doesn't work as casperjs would want it - often a button -> controller url
+//TODO: saveScreenshot (to GALAXY_TEST_SAVE)
+//TODO: saveHtml (to GALAXY_TEST_SAVE)
+
+/** Casper has an (undocumented?) skip test feature. This is a conv. wrapper for that.
+ */
+SpaceGhost.prototype.skipTest = function(){
+ //TODO: does this work? seems to...
+ throw this.test.SKIP_MESSAGE;
+};
+
+/** test helper - within frame, assert selector, and assert text in selector
+ * @param {CasperJS selector} selector what element in which to search for the text
+ * @param {String} text what text to search for
+ * @param {String} frame frame selector (gen. name) in which to search for selector (defaults to top)
+ */
+SpaceGhost.prototype.assertSelectorAndTextInFrame = function assertSelectorAndTextInFrame( selector, text, frame ){
+ var spaceghost = this;
+ function assertSelectorAndText( selector, text ){
+ spaceghost.test.assertExists( selector,
+ format( "found '%s' in %s", selector, frame ) );
+ spaceghost.test.assertSelectorHasText( selector, text,
+ format( "%s contains '%s'", selector, text ) );
+ }
+ if( frame ){
+ this.withFrame( frame, function(){
+ assertSelectorAndText( selector, text );
+ });
+ } else {
+ assertSelectorAndText( selector, text );
+ }
+}
+
+/** test helper - within frame, assert errormessage, and assert text in errormessage
+ * *message is a common UI feedback motif in Galaxy (often displayed in the main panel)
+ * @param {String} message what the message should contain
+ * @param {String} frame frame selector (gen. name) in which to search for selector (defaults to 'galaxy_main')
+ * @param {CasperJS selector} messageSelector what element in which to search for the text (defaults to '.errormessage')
+ */
+SpaceGhost.prototype.assertErrorMessage = function assertSelectorAndTextInFrame( message, frame, messageSelector ){
+ messageSelector = messageSelector || this.selectors.messages.error;
+ frame = frame || this.selectors.frames.main;
+ this.assertSelectorAndTextInFrame( messageSelector, message, frame );
+};
+
+/** Assert that stepsFn (which contains casper.then or some other casper step function) raises an error with
+ * a msg that contains some text (msgContains).
+ * @param {String} msgContains some portion of the correct error msg
+ * @param {Function} stepsFn a function that puts casper steps on the stack (then, thenOpen, etc.)
+ */
+SpaceGhost.prototype.assertStepsRaise = function assertStepsRaise( msgContains, stepsFn, removeOtherListeners ){
+ // casper provides an assertRaises but this doesn't work well with steps
+ //TODO: * @param {Boolean} removeOtherListeners option to remove other listeners while this fires
+ var spaceghost = this;
+ function testTheError( msg, backtrace ){
+ spaceghost.test.assert( msg.indexOf( msgContains ) != -1, 'Raised correct error: ' + msg );
+ }
+ this.tryStepsCatch( stepsFn, testTheError );
+};
+
+// =================================================================== CONVENIENCE
+/** Wraps casper.getElementInfo in try, returning null if element not found instead of erroring.
+ * @param {String} selector css or xpath selector for the element to find
+ */
+SpaceGhost.prototype.elementInfoOrNull = function elementInfoOrNull( selector ){
+ var found = null;
+ try {
+ found = this.getElementInfo( selector );
+ } catch( err ){}
+ return found;
+};
+
+/** Wraps casper.click in try, returning true if element found and clicked, false if not instead of erroring.
+ * @param {String} selector css or xpath selector for the element to find
+ */
+SpaceGhost.prototype.tryClick = function tryClick( selector ){
+ var done = false;
+ try {
+ found = this.click( selector );
+ done = true;
+ } catch( err ){}
+ return done;
+};
+
+
+// =================================================================== GALAXY CONVENIENCE
+/** Gets a psuedo-random (unique?) email based on the time stamp.
+ * Helpful for testing registration.
+ * @param {String} username email user (defaults to 'test')
+ * @param {String} domain email domain (defaults to 'test.test')
+ */
+SpaceGhost.prototype.getRandomEmail = function getRandomEmail( username, domain ){
+ username = username || 'test';
+ domain = domain || 'test.test';
+ return username + Date.now() + '@' + domain;
+};
+
+
+/** Tests registering a new user on the Galaxy instance by submitting the registration form.
+ * NOTE: this version does NOT throw an error on a bad registration.
+ * It is meant for testing the registration functionality and, therefore, is marked as private.
+ * Other tests should use registerUser
+ * @param {String} email the users email address
+ * @param {String} password the users password
+ * @param {String} username the users ...username! (optional: will use 1st part of email)
+ * @param {String} confirm password confirmation (optional: defaults to password)
+ */
+SpaceGhost.prototype._submitUserRegistration = function _submitUserRegistration( email, password, username, confirm ){
+ var userInfo = {
+ email : email,
+ password: password,
+ // default username to first part of email
+ username:( !username && email.match( /^\w*/ ) )?( email.match( /^\w*/ ) ):( username ),
+ // default confirm duplicate of password
+ confirm : ( confirm !== undefined )?( confirm ):( password )
+ };
+ this.debug( 'registering user:\n' + this.jsonStr( userInfo ) );
+
+ this.thenOpen( this.baseUrl, function(){
+
+ this.clickLabel( this.labels.masthead.menus.user );
+ this.clickLabel( this.labels.masthead.userMenu.register );
+
+ this.withFrame( this.selectors.frames.main, function mainBeforeRegister(){
+ this.debug( 'submitting registration... ' + this.getCurrentUrl() );
+ this.fill( this.selectors.registrationPage.form, userInfo, false );
+ // need manual up
+ this.click( xpath( this.selectors.registrationPage.submit_xpath ) );
+ });
+
+ this.withFrame( this.selectors.frames.main, function mainAfterRegister(){
+ var messageInfo = this.getElementInfo( this.selectors.messages.all );
+ this.debug( 'post registration message:\n' + this.jsonStr( messageInfo ) );
+ });
+ });
+};
+
+/** Register a new user on the Galaxy instance.
+ * @param {String} email the users email address
+ * @param {String} password the users password
+ * @param {String} username the users ...username! (optional: will use 1st part of email)
+ */
+SpaceGhost.prototype.registerUser = function registerUser( email, password, username ){
+ this._submitUserRegistration( email, password, username );
+ this.then( function(){
+ this.withFrame( this.selectors.frames.main, function mainAfterRegister(){
+ var messageInfo = this.getElementInfo( this.selectors.messages.all );
+ this.debug( 'post registration message:\n' + this.jsonStr( messageInfo ) );
+
+ if( messageInfo.attributes[ 'class' ] === 'errormessage' ){
+ throw new GalaxyError( 'RegistrationError: ' + messageInfo.html );
+ }
+ });
+ });
+ return this;
+};
+
+/** Log out the current user
+ */
+SpaceGhost.prototype.logout = function logoutUser(){
+ this.clickLabel( this.labels.masthead.menus.user );
+ this.clickLabel( this.labels.masthead.userMenu.login );
+ this.thenOpen( this.baseUrl, function(){
+ //TODO: handle already logged out
+ this.clickLabel( this.labels.masthead.menus.user );
+ this.clickLabel( this.labels.masthead.userMenu.logout );
+ });
+};
+
+/** Tests logging in a user on the Galaxy instance by submitting the login form.
+ * NOTE: this version does NOT throw an error on a bad login.
+ * It is meant for testing the login functionality and, therefore, is marked as private.
+ * Other tests should use login
+ * @param {String} email the users email address
+ * @param {String} password the users password
+ */
+SpaceGhost.prototype._submitLogin = function logoutUser( email, password ){
+ var loginInfo = {
+ //NOTE: keys are used as name selectors in the fill fn - must match the names of the inputs
+ email: email,
+ password: password
+ };
+
+ this.thenOpen( this.baseUrl, function(){
+
+ this.clickLabel( this.labels.masthead.menus.user );
+ this.clickLabel( this.labels.masthead.userMenu.login );
+
+ this.withFrame( this.selectors.frames.main, function mainBeforeLogin(){
+ this.debug( '(' + this.getCurrentUrl() + ') logging in user:\n' + this.jsonStr( loginInfo ) );
+ this.fill( this.selectors.loginPage.form, loginInfo, false );
+ this.click( xpath( this.selectors.loginPage.submit_xpath ) );
+ });
+ this.withFrame( this.selectors.frames.main, function mainAfterLogin(){
+ //TODO: prob. could use a more generalized form of this for url breakdown/checking
+ if( this.getCurrentUrl().search( this.selectors.loginPage.url_regex ) != -1 ){
+ var messageInfo = this.getElementInfo( this.selectors.messages.all );
+ this.debug( 'post login message:\n' + this.jsonStr( messageInfo ) );
+ }
+ });
+ });
+};
+
+/** Logs in a user. Throws error on bad log in.
+ * @param {String} email the users email address
+ * @param {String} password the users password
+ */
+SpaceGhost.prototype.login = function login( email, password ){
+ this._submitLogin( email, password );
+ this.then( function(){
+ this.withFrame( this.selectors.frames.main, function mainAfterLogin(){
+ if( this.getCurrentUrl().search( this.selectors.loginPage.url_regex ) != -1 ){
+ var messageInfo = this.getElementInfo( this.selectors.messages.all );
+ if( messageInfo && messageInfo.attributes[ 'class' ] === 'errormessage' ){
+ throw new GalaxyError( 'LoginError: ' + messageInfo.html );
+ }
+ }
+ });
+ if( this.loggedInAs() === email ){
+ this.debug( 'logged in as ' + email );
+ }
+ });
+ return this;
+};
+
+/** Fetch the email of the currently logged in user (or '' if not logged in)
+ * @returns {String} email of currently logged in user or '' if no one logged in
+ */
+SpaceGhost.prototype.loggedInAs = function loggedInAs(){
+ var userEmail = '';
+ try {
+ var loggedInInfo = this.getElementInfo( xpath( this.selectors.masthead.userMenu.userEmail_xpath ) );
+ userEmail = loggedInInfo.text;
+ } catch( err ){
+ this.error( err );
+ }
+ //console.debug( 'loggedInInfo:', this.jsonStr( loggedInInfo ) );
+ return userEmail;
+};
+
+/** Attempts to login a user - if that raises an error (LoginError), register the user
+ * @param {String} email the users email address
+ * @param {String} password the users password
+ * @param {String} username the users ...username! (optional: will use 1st part of email)
+ */
+SpaceGhost.prototype.loginOrRegisterUser = function loginOrRegisterUser( email, password, username ){
+ // attempt a login, if that fails - register
+ this.tryStepsCatch( function tryToLogin(){
+ this.open( this.baseUrl ).login( email, password );
+
+ }, function failedLoginRegister(){
+ this.open( this.baseUrl ).registerUser( email, password, username );
+ });
+ return this;
+};
+
+/** Tests uploading a file.
+ * NOTE: this version does NOT throw an error on a bad upload.
+ * It is meant for testing the upload functionality and, therefore, is marked as private.
+ * Other tests should use uploadFile
+ * @param {String} filepath the local filesystem path of the file to upload (absolute (?))
+ */
+SpaceGhost.prototype._uploadFile = function _uploadFile( filepath ){
+ var uploadInfo = {};
+ //TODO: check file exists using phantom.fs
+ //TODO: pull from test data
+ uploadInfo[ this.tools.upload.fileInput ] = filepath;
+ this.debug( 'uploading file: ' + filepath );
+
+ spaceghost.then( function(){
+ spaceghost.withFrame( this.selectors.frames.tools, function(){
+ this.clickLabel( this.tools.upload.panelLabel );
+ });
+ });
+
+ this.then( function beginUpload(){
+ spaceghost.withFrame( this.selectors.frames.main, function(){
+ this.fill( this.tools.general.form, uploadInfo, false );
+
+ // the following throws:
+ // [error] [remote] Failed dispatching clickmouse event on xpath selector: //input[@value="Execute"]:
+ // PageError: TypeError: 'undefined' is not a function (evaluating '$(this).formSerialize()')
+
+ // ...and yet the upload still seems to work
+ this.click( xpath( this.tools.general.executeButton_xpath ) );
+ });
+ });
+ this.withFrame( this.selectors.frames.main, function afterUpload(){
+ var messageInfo = this.elementInfoOrNull( this.selectors.messages.all );
+ this.debug( 'post upload message:\n' + this.jsonStr( messageInfo ) );
+ });
+};
+
+/** Uploads a file.
+ * @param {String} filepath the local filesystem path of the file to upload (absolute (?))
+ */
+SpaceGhost.prototype.uploadFile = function uploadFile( filepath ){
+ this._uploadFile( filepath );
+ this.then( function(){
+ this.withFrame( this.selectors.frames.main, function mainAfterUpload(){
+ var messageInfo = this.elementInfoOrNull( this.selectors.messages.all );
+ if( ( !messageInfo )
+ || ( messageInfo.attributes[ 'class' ] !== 'donemessagelarge' )
+ || ( messageInfo.text.indexOf( this.text.upload.success ) === -1 ) ){
+ throw new GalaxyError( 'UploadError: ' + this.jsonStr( messageInfo ) );
+ }
+ });
+ });
+ return this;
+};
+
+/** Parses the hid and name of a newly uploaded file from the tool execution donemessagelarge
+ * @param {String} doneMsgText the text extracted from the donemessagelarge after a tool execution
+ */
+SpaceGhost.prototype.parseDoneMessageForTool = function parseDoneMessageForTool( doneMsgText ){
+ //TODO: test on non-upload
+ var executionInfo = {};
+ var textMatch = doneMsgText.match( /added to the queue:\n\n(\d+)\: (.*)\n/m );
+ if( textMatch ){
+ if( textMatch.length > 1 ){
+ executionInfo.hid = parseInt( textMatch[1], 10 );
+ }
+ if( textMatch.length > 2 ){
+ executionInfo.name = textMatch[2];
+ }
+ executionInfo.name = textMatch[2];
+ }
+ return executionInfo;
+};
+
+/** Find the casper element info of the hda wrapper given the hda title and hid.
+ * NOTE: if more than one is found, will return the first found.
+ * precondition: you should wrap this with withFrame( 'galaxy_history' ) :(
+ * @param {String} title the title of the hda
+ * @param {Int} hid (optional) the hid of the hda to look for
+ * @returns {Object|null} ElementInfo of the historyItemWrapper found, null if not found
+ */
+SpaceGhost.prototype.hdaElementInfoByTitle = function hdaElementInfoByTitle( title, hid ){
+ var spaceghost = this,
+ titleContains = ( hid !== undefined )?( hid + ': ' + title ):( title ),
+ wrapperInfo = null;
+
+ wrapperInfo = spaceghost.evaluate( function( titleContains ){
+ // find the title, then the wrapper (2 containers up)
+ var $title = $( '.historyItemTitle:contains(' + titleContains + ')' );
+ var $wrapper = $title.parent().parent();
+ return (( $wrapper.attr( 'id' ) )?( __utils__.getElementInfo( '#' + $wrapper.attr( 'id' ) )):( null ));
+ }, titleContains );
+
+ return wrapperInfo;
+};
+
+/** Wait for the hda with given id to move into the given state.
+ * @param {String} hdaSelector selector for hda (should be historyItemWrapper)
+ * @param {String} finalState hda state to wait for (e.g. 'ok', 'error', 'running', 'queued', etc.)
+ * @param {Function} whenInStateFn called when hda goes into finalState
+ * @param {Function} timeoutFn called when maxWaitMs have passed without the desired state
+ * @param {Int} maxWaitMs number of milliseconds to wait before timing out (defaults to options.waitTimeout)
+ */
+SpaceGhost.prototype.waitForHdaState = function waitForHdaState( hdaSelector, finalState,
+ whenInStateFn, timeoutFn, maxWaitMs ){
+ //TODO:?? explicitly a historyWrapper id?
+ maxWaitMs = maxWaitMs || this.options.waitTimeout;
+ var finalStateClass = '.historyItem-' + finalState;
+
+ this.then( function(){
+ this.withFrame( this.selectors.frames.history, function(){
+ // wait for state, preferrably debugging intermediate states
+ var spaceghost = this,
+
+ // we need a larger timeout for these - it can take a bit
+ oldWaitTimeout = this.options.waitTimeout,
+
+ // output some progress indicator within the test (debug)
+ progressIntervalId = setInterval( function progress(){
+ var state = spaceghost.evaluate( function( hdaSelector ){
+ var $wrapperClasses = $( hdaSelector ).attr( 'class' );
+ return $wrapperClasses.match( /historyItem\-(\w+)/ )[1];
+ }, hdaSelector );
+ spaceghost.debug( hdaSelector + ': ' + state );
+ }, 1000 ),
+
+ // when done, close down the progress reporter and reset the wait timeout to what it was
+ finallyFn = function(){
+ spaceghost.options.waitTimeout = oldWaitTimeout;
+ clearInterval( progressIntervalId );
+ };
+
+ this.options.waitTimeout = maxWaitMs;
+ this.waitForSelector( hdaSelector + finalStateClass, function _whenInState(){
+ this.debug( 'HDA now in state ' + finalState + ':\n'
+ + this.jsonStr( this.elementInfoOrNull( hdaSelector ) ) );
+ whenInStateFn.call( this );
+ finallyFn();
+
+ }, function timeout(){
+ this.debug( 'timed out:\n'
+ + this.jsonStr( this.elementInfoOrNull( hdaSelector ) ) );
+ timeoutFn.call( this );
+ finallyFn();
+ }
+ );
+ });
+ });
+};
+
+// =================================================================== MISCELAIN
+/** Send message to stderr
+ */
+SpaceGhost.prototype.stderr = function( msg ){
+ var fs = require( 'fs' );
+ fs.write( '/dev/stderr', msg + '\n', 'w' );
+};
+
+// convenience logging funcs
+/** log using level = 'debug' and default namespace = 'spaceghost'
+ */
+SpaceGhost.prototype.debug = function( msg, namespace ){
+ namespace = namespace || 'spaceghost';
+ this.log( msg, 'debug', namespace );
+};
+
+/** log using level = 'info' and default namespace = 'spaceghost'
+ */
+SpaceGhost.prototype.info = function( msg, namespace ){
+ namespace = namespace || 'spaceghost';
+ this.log( msg, 'info', namespace );
+};
+
+/** log using level = 'info' and default namespace = 'spaceghost'
+ */
+SpaceGhost.prototype.warning = function( msg, namespace ){
+ namespace = namespace || 'spaceghost';
+ this.log( msg, 'warning', namespace );
+};
+
+/** log using level = 'info' and default namespace = 'spaceghost'
+ */
+SpaceGhost.prototype.error = function( msg, namespace ){
+ namespace = namespace || 'spaceghost';
+ this.log( msg, 'error', namespace );
+};
+
+/** log despite logLevel settings, unless returnJsonOnly is set
+ */
+SpaceGhost.prototype.out = function( msg, namespace ){
+ if( !this.options.returnJsonOnly ){
+ console.debug( msg );
+ }
+};
+
+/** JSON formatter
+ */
+SpaceGhost.prototype.jsonStr = function( obj ){
+ return JSON.stringify( obj, null, 2 );
+};
+
+/** Debug SG itself
+ */
+SpaceGhost.prototype.debugMe = function(){
+ console.debug( 'options:\n' + this.jsonStr( this.options ) );
+ console.debug( 'cli:\n' + this.jsonStr( this.cli ) );
+};
+
+/** Get the last error on the stack.
+ */
+SpaceGhost.prototype.lastError = function(){
+ return this.errors[( this.errors.length - 1 )];
+};
+
+/** Get the last error from an assertRaises test (gen. for the message)
+ */
+SpaceGhost.prototype.getLastAssertRaisesError = function(){
+ // assuming the test passed here...
+ var testsThatPassed = this.test.testResults.passes;
+ var test = null;
+ for( var i=( testsThatPassed.length - 1 ); i>=0; i-- ){
+ currTest = testsThatPassed[i];
+ if( currTest.type === 'assertRaises' ){
+ test = currTest; break;
+ }
+ }
+ return ( ( test && test.values )?( test.values.error ):( undefined ) );
+};
+
+/** String representation
+ */
+SpaceGhost.prototype.toString = function(){
+ var currentUrl = '';
+ try {
+ currentUrl = this.getCurrentUrl();
+ } catch( err ){}
+ return 'SpaceGhost(' + currentUrl + ')';
+};
+
+
+// =================================================================== TEST DATA
+// maintain selectors, labels, text here in one central location
+
+//TODO: to separate file?
+SpaceGhost.prototype.selectors = {
+ masthead : {
+ userMenu : {
+ userEmail : 'a #user-email',
+ userEmail_xpath : '//a[contains(text(),"Logged in as")]/span["id=#user-email"]'
+ }
+ },
+ frames : {
+ main : 'galaxy_main',
+ tools : 'galaxy_tools',
+ history : 'galaxy_history'
+ },
+ messages : {
+ all : '[class*="message"]',
+ error : '.errormessage',
+ done : '.donemessage'
+ },
+ loginPage : {
+ form : 'form#login',
+ submit_xpath : "//input[@value='Login']",
+ url_regex : /\/user\/login/
+ },
+ registrationPage : {
+ form : 'form#registration',
+ submit_xpath : "//input[@value='Submit']"
+ }
+};
+
+SpaceGhost.prototype.labels = {
+ masthead : {
+ menus : {
+ user : 'User'
+ },
+ userMenu : {
+ register : 'Register',
+ login : 'Login',
+ logout : 'Logout'
+ }
+ }
+};
+
+SpaceGhost.prototype.tools = {
+ general : {
+ form : 'form#tool_form',
+ executeButton_xpath : '//input[@value="Execute"]'
+ },
+ upload : {
+ panelLabel : 'Upload File',
+ fileInput : 'files_0|file_data' // is this general?
+ }
+};
+
+SpaceGhost.prototype.text = {
+ registrationPage : {
+ badEmailError : 'Enter a real email address'
+ //...
+ },
+ upload : {
+ success : 'The following job has been successfully added to the queue'
+ }
+};
+
+// =================================================================== EXPORTS
+/**
+ */
+exports.SpaceGhost = SpaceGhost;
+exports.PageError = PageError;
+exports.GalaxyError = GalaxyError;
+exports.AlertError = AlertError;
+/**
+ */
+exports.create = function create(options) {
+ "use strict";
+ return new SpaceGhost(options);
+};
+
+// ------------------------------------------------------------------- included libs
+//??: can we require underscore, etc. from the ../../static/scripts/lib?
+// yep!
+//var _ = require( '../../static/scripts/libs/underscore' );
+//var stooges = [{name : 'moe', age : 40}, {name : 'larry', age : 50}, {name : 'curly', age : 60}];
+//console.debug( JSON.stringify( _.pluck(stooges, 'name') ) );
+//exports._ = _;
diff -r ba8c49884f7daab5df8b62bd631157058c7ee910 -r 01e73b11a46f87b03af29581603378b06187051d test/casperjs/upload-tests.js
--- /dev/null
+++ b/test/casperjs/upload-tests.js
@@ -0,0 +1,132 @@
+// have to handle errors here - or phantom/casper won't bail but _HANG_
+try {
+ var utils = require( 'utils' ),
+ xpath = require( 'casper' ).selectXPath,
+ format = utils.format,
+
+ //...if there's a better way - please let me know, universe
+ scriptDir = require( 'system' ).args[3]
+ // remove the script filename
+ .replace( /[\w|\.|\-|_]*$/, '' )
+ // if given rel. path, prepend the curr dir
+ .replace( /^(?!\/)/, './' ),
+ spaceghost = require( scriptDir + 'spaceghost' ).create({
+ // script options here (can be overridden by CLI)
+ //verbose: true,
+ //logLevel: debug,
+ scriptDir: scriptDir
+ });
+
+ spaceghost.start();
+
+} catch( error ){
+ console.debug( error );
+ phantom.exit( 1 );
+}
+
+
+// ===================================================================
+/* TODO:
+
+ find a way to error on bad upload?
+ general tool execution
+*/
+// =================================================================== globals and helpers
+var email = spaceghost.getRandomEmail(),
+ password = '123456';
+if( spaceghost.fixtureData.testUser ){
+ email = spaceghost.fixtureData.testUser.email;
+ password = spaceghost.fixtureData.testUser.password;
+}
+
+
+// =================================================================== TESTS
+// ------------------------------------------------------------------- start a new user
+spaceghost.loginOrRegisterUser( email, password );
+//??: why is a reload needed here? If we don't, loggedInAs === '' ...
+spaceghost.thenOpen( spaceghost.baseUrl, function(){
+ var loggedInAs = spaceghost.loggedInAs();
+ this.test.assert( loggedInAs === email, 'loggedInAs() matches email: "' + loggedInAs + '"' );
+});
+
+// ------------------------------------------------------------------- get avail. tools
+// list available tools
+//spaceghost.then( function(){
+// spaceghost.withFrame( 'galaxy_tools', function(){
+// //var availableTools = this.fetchText( 'a.tool-link' );
+//
+// var availableTools = this.evaluate( function(){
+// //var toolTitles = __utils__.findAll( 'div.toolTitle' );
+// //return Array.prototype.map.call( toolTitles, function( e ){
+// // //return e.innerHtml;
+// // return e.textContent || e.innerText;
+// //}).join( '\n' );
+//
+// var toolLinks = __utils__.findAll( 'a.tool-link' );
+// return Array.prototype.map.call( toolLinks, function( e ){
+// //return e.innerHtml;
+// return e.textContent || e.innerText;
+// }).join( '\n' );
+// });
+// this.debug( 'availableTools: ' + availableTools );
+// });
+//});
+
+// ------------------------------------------------------------------- upload from fs
+// test uploading from the filesystem
+var uploadInfo = {};
+spaceghost.then( function(){
+ // strangely, this works with a non-existant file --> empty txt file
+ var filename = '1.sam';
+ var filepath = this.options.scriptDir + '/../../test-data/' + filename;
+ this._uploadFile( filepath );
+
+ // when an upload begins successfully...
+ // 1. main should reload with a donemessagelarge
+ // 2. which contains the uploaded file's new hid
+ // 3. and the filename of the upload
+ this.withFrame( 'galaxy_main', function(){
+ var doneElementInfo = this.elementInfoOrNull( '.donemessagelarge' );
+ this.test.assert( doneElementInfo !== null,
+ "Found donemessagelarge after uploading file" );
+
+ uploadInfo = this.parseDoneMessageForTool( doneElementInfo.text );
+ this.test.assert( uploadInfo.hid >= 0,
+ 'Found sensible hid from upload donemessagelarge: ' + uploadInfo.hid );
+ this.test.assert( uploadInfo.name === filename,
+ 'Found matching name from upload donemessagelarge: ' + uploadInfo.name );
+ });
+
+});
+
+// wait for upload to finish
+spaceghost.then( function(){
+ var hdaInfo = null;
+
+ this.withFrame( 'galaxy_history', function(){
+ hdaInfo = this.hdaElementInfoByTitle( uploadInfo.name, uploadInfo.hid );
+ this.debug( 'hda:\n' + this.jsonStr( hdaInfo ) );
+ });
+
+ this.then( function(){
+ this.test.comment( 'Waiting for upload to move to ok state in history' );
+ //precondition: needs class
+ var hdaStateClass = hdaInfo.attributes[ 'class' ].match( /historyItem\-(\w+)/ )[0];
+ if( hdaStateClass !== 'historyItem-ok' ){
+ this.waitForHdaState( '#' + hdaInfo.attributes.id, 'ok',
+ function whenInStateFn(){
+ this.test.assert( true, 'Upload completed successfully for: ' + uploadInfo.name );
+
+ }, function timeoutFn(){
+ this.test.fail( 'Test timedout for upload: ' + uploadInfo.name );
+
+ // wait a maximum of 30 secs
+ }, 30 * 1000 );
+ }
+ });
+});
+
+// ===================================================================
+spaceghost.run( function(){
+ this.test.done();
+});
diff -r ba8c49884f7daab5df8b62bd631157058c7ee910 -r 01e73b11a46f87b03af29581603378b06187051d test/casperjs/utils/simple-galaxy.js
--- /dev/null
+++ b/test/casperjs/utils/simple-galaxy.js
@@ -0,0 +1,1 @@
+/Users/carleberhard/explore/phantom-casper/simple-galaxy.js
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: carlfeberhard: Fix to trackster/util.js exports; Fix to docstring in history_contents; Fix alert text in hda-model
by Bitbucket 12 Feb '13
by Bitbucket 12 Feb '13
12 Feb '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/ba8c49884f7d/
changeset: ba8c49884f7d
user: carlfeberhard
date: 2013-02-12 20:26:30
summary: Fix to trackster/util.js exports; Fix to docstring in history_contents; Fix alert text in hda-model
affected #: 5 files
diff -r d2e30720ba78cbee8b6a6a63daa91702778040bc -r ba8c49884f7daab5df8b62bd631157058c7ee910 lib/galaxy/webapps/galaxy/api/history_contents.py
--- a/lib/galaxy/webapps/galaxy/api/history_contents.py
+++ b/lib/galaxy/webapps/galaxy/api/history_contents.py
@@ -113,11 +113,6 @@
"""
Returns a dictionary for an HDA that raised an exception when it's
dictionary was being built.
- {
- 'id' : < the encoded dataset id >,
- 'type' : < name of the dataset >,
- 'url' : < api url to retrieve this datasets full data >,
- }
"""
return {
'id' : hda_id,
diff -r d2e30720ba78cbee8b6a6a63daa91702778040bc -r ba8c49884f7daab5df8b62bd631157058c7ee910 static/scripts/mvc/history/history-model.js
--- a/static/scripts/mvc/history/history-model.js
+++ b/static/scripts/mvc/history/history-model.js
@@ -191,7 +191,7 @@
// if not interruption by iframe reload
//TODO: remove when iframes are removed
if( !( ( xhr.readyState === 0 ) && ( xhr.status === 0 ) ) ){
- alert( _l( 'Error getting history updates from the server.' ) + '\n' + error );
+ alert( _l( 'Error getting history updates from the server:' ) + '\n' + error );
history.log( 'stateUpdater error:', error, 'responseText:', xhr.responseText );
}
});
diff -r d2e30720ba78cbee8b6a6a63daa91702778040bc -r ba8c49884f7daab5df8b62bd631157058c7ee910 static/scripts/packed/mvc/history/history-model.js
--- a/static/scripts/packed/mvc/history/history-model.js
+++ b/static/scripts/packed/mvc/history/history-model.js
@@ -1,1 +1,1 @@
-var History=BaseModel.extend(LoggableMixin).extend({defaults:{id:"",name:"",state:"",diskSize:0,deleted:false,annotation:null,message:null},urlRoot:"api/histories/",url:function(){return"api/histories/"+this.get("id")},initialize:function(a,b){this.log(this+".initialize:",a,b);this.hdas=new HDACollection();if(b){if(_.isArray(b)){this.hdas.reset(b);this.checkForUpdates()}else{if(_.isString(b)&&(b.match(/error/i))){alert(_l("Error loading bootstrapped history")+":\n"+b)}}}},loadFromApi:function(a,c){var b=this;b.attributes.id=a;jQuery.when(jQuery.ajax("api/users/current"),b.fetch()).then(function(e,d){b.attributes.user=e[0];b.trigger("loaded:user",e[0]);b.trigger("loaded",d[0])}).then(function(){jQuery.ajax(b.url()+"/contents?"+jQuery.param({ids:b.hdaIdsFromStateIds().join(",")})).success(function(d){b.hdas.reset(d);b.checkForUpdates();b.trigger("loaded:hdas",d);if(c){callback(b)}})})},hdaIdsFromStateIds:function(){return _.reduce(_.values(this.get("state_ids")),function(b,a){return b.concat(a)})},checkForUpdates:function(a){if(this.hdas.running().length){this.stateUpdater()}else{this.trigger("ready")}return this},stateUpdater:function(){var c=this,a=this.get("state"),b=this.get("state_ids");jQuery.ajax("api/histories/"+this.get("id")).success(function(d){c.set(d);c.log("current history state:",c.get("state"),"(was)",a,"new size:",c.get("nice_size"));var e=[];_.each(_.keys(d.state_ids),function(g){var f=_.difference(d.state_ids[g],b[g]);e=e.concat(f)});if(e.length){c.fetchHdaUpdates(e)}if((c.get("state")===HistoryDatasetAssociation.STATES.RUNNING)||(c.get("state")===HistoryDatasetAssociation.STATES.QUEUED)){setTimeout(function(){c.stateUpdater()},History.UPDATE_DELAY)}else{c.trigger("ready")}}).error(function(f,d,e){if(!((f.readyState===0)&&(f.status===0))){alert(_l("Error getting history updates from the server.")+"\n"+e);c.log("stateUpdater error:",e,"responseText:",f.responseText)}})},fetchHdaUpdates:function(b){var a=this;jQuery.ajax({url:this.url()+"/contents?"+jQuery.param({ids:b.join(",")}),error:function(h,c,d){if((h.readyState===0)&&(h.status===0)){return}var f=JSON.parse(h.responseText);if(_.isArray(f)){var e=_.groupBy(f,function(i){if(_.has(i,"error")){return"errored"}return"ok"});a.log("fetched, errored datasets:",e.errored);a.updateHdas(f)}else{var g=_l("ERROR updating hdas from api history contents")+": ";a.log(g,b,h,c,d,f);alert(g+b.join(","))}},success:function(d,c,e){a.log(a+".fetchHdaUpdates, success:",c,e);a.updateHdas(d)}})},updateHdas:function(a){var c=this,b=[];c.log(c+".updateHdas:",a);_.each(a,function(e,f){var d=c.hdas.get(e.id);if(d){c.log("found existing model in list for id "+e.id+", updating...:");d.set(e)}else{c.log("NO existing model for id "+e.id+", creating...:");b.push(e)}});if(b.length){c.addHdas(b)}},addHdas:function(a){var b=this;_.each(a,function(c,d){var e=b.hdas.hidToCollectionIndex(c.hid);c.history_id=b.get("id");b.hdas.add(new HistoryDatasetAssociation(c),{at:e,silent:true})});b.hdas.trigger("add",a)},toString:function(){var a=(this.get("name"))?(","+this.get("name")):("");return"History("+this.get("id")+a+")"}});History.UPDATE_DELAY=4000;var HistoryCollection=Backbone.Collection.extend(LoggableMixin).extend({model:History,urlRoot:"api/histories"});
\ No newline at end of file
+var History=BaseModel.extend(LoggableMixin).extend({defaults:{id:"",name:"",state:"",diskSize:0,deleted:false,annotation:null,message:null},urlRoot:"api/histories/",url:function(){return"api/histories/"+this.get("id")},initialize:function(a,b){this.log(this+".initialize:",a,b);this.hdas=new HDACollection();if(b){if(_.isArray(b)){this.hdas.reset(b);this.checkForUpdates()}else{if(_.isString(b)&&(b.match(/error/i))){alert(_l("Error loading bootstrapped history")+":\n"+b)}}}},loadFromApi:function(a,c){var b=this;b.attributes.id=a;jQuery.when(jQuery.ajax("api/users/current"),b.fetch()).then(function(e,d){b.attributes.user=e[0];b.trigger("loaded:user",e[0]);b.trigger("loaded",d[0])}).then(function(){jQuery.ajax(b.url()+"/contents?"+jQuery.param({ids:b.hdaIdsFromStateIds().join(",")})).success(function(d){b.hdas.reset(d);b.checkForUpdates();b.trigger("loaded:hdas",d);if(c){callback(b)}})})},hdaIdsFromStateIds:function(){return _.reduce(_.values(this.get("state_ids")),function(b,a){return b.concat(a)})},checkForUpdates:function(a){if(this.hdas.running().length){this.stateUpdater()}else{this.trigger("ready")}return this},stateUpdater:function(){var c=this,a=this.get("state"),b=this.get("state_ids");jQuery.ajax("api/histories/"+this.get("id")).success(function(d){c.set(d);c.log("current history state:",c.get("state"),"(was)",a,"new size:",c.get("nice_size"));var e=[];_.each(_.keys(d.state_ids),function(g){var f=_.difference(d.state_ids[g],b[g]);e=e.concat(f)});if(e.length){c.fetchHdaUpdates(e)}if((c.get("state")===HistoryDatasetAssociation.STATES.RUNNING)||(c.get("state")===HistoryDatasetAssociation.STATES.QUEUED)){setTimeout(function(){c.stateUpdater()},History.UPDATE_DELAY)}else{c.trigger("ready")}}).error(function(f,d,e){if(!((f.readyState===0)&&(f.status===0))){alert(_l("Error getting history updates from the server:")+"\n"+e);c.log("stateUpdater error:",e,"responseText:",f.responseText)}})},fetchHdaUpdates:function(b){var a=this;jQuery.ajax({url:this.url()+"/contents?"+jQuery.param({ids:b.join(",")}),error:function(h,c,d){if((h.readyState===0)&&(h.status===0)){return}var f=JSON.parse(h.responseText);if(_.isArray(f)){var e=_.groupBy(f,function(i){if(_.has(i,"error")){return"errored"}return"ok"});a.log("fetched, errored datasets:",e.errored);a.updateHdas(f)}else{var g=_l("ERROR updating hdas from api history contents")+": ";a.log(g,b,h,c,d,f);alert(g+b.join(","))}},success:function(d,c,e){a.log(a+".fetchHdaUpdates, success:",c,e);a.updateHdas(d)}})},updateHdas:function(a){var c=this,b=[];c.log(c+".updateHdas:",a);_.each(a,function(e,f){var d=c.hdas.get(e.id);if(d){c.log("found existing model in list for id "+e.id+", updating...:");d.set(e)}else{c.log("NO existing model for id "+e.id+", creating...:");b.push(e)}});if(b.length){c.addHdas(b)}},addHdas:function(a){var b=this;_.each(a,function(c,d){var e=b.hdas.hidToCollectionIndex(c.hid);c.history_id=b.get("id");b.hdas.add(new HistoryDatasetAssociation(c),{at:e,silent:true})});b.hdas.trigger("add",a)},toString:function(){var a=(this.get("name"))?(","+this.get("name")):("");return"History("+this.get("id")+a+")"}});History.UPDATE_DELAY=4000;var HistoryCollection=Backbone.Collection.extend(LoggableMixin).extend({model:History,urlRoot:"api/histories"});
\ No newline at end of file
diff -r d2e30720ba78cbee8b6a6a63daa91702778040bc -r ba8c49884f7daab5df8b62bd631157058c7ee910 static/scripts/packed/viz/trackster/util.js
--- a/static/scripts/packed/viz/trackster/util.js
+++ b/static/scripts/packed/viz/trackster/util.js
@@ -1,1 +1,1 @@
-define(function(){exports={};exports.ServerStateDeferred=Backbone.Model.extend({defaults:{ajax_settings:{},interval:1000,success_fn:function(a){return true}},go:function(){var d=$.Deferred(),c=this,f=c.get("ajax_settings"),e=c.get("success_fn"),b=c.get("interval"),a=function(){$.ajax(f).success(function(g){if(e(g)){d.resolve(g)}else{setTimeout(a,b)}})};a();return d}});exports.get_random_color=function(a){if(!a){a="#ffffff"}if(typeof(a)==="string"){a=[a]}for(var j=0;j<a.length;j++){a[j]=parseInt(a[j].slice(1),16)}var n=function(t,s,i){return((t*299)+(s*587)+(i*114))/1000};var e=function(v,u,w,s,i,t){return(Math.max(v,s)-Math.min(v,s))+(Math.max(u,i)-Math.min(u,i))+(Math.max(w,t)-Math.min(w,t))};var g,o,f,k,q,h,r,c,d,b,p,m=false,l=0;do{g=Math.round(Math.random()*16777215);o=(g&16711680)>>16;f=(g&65280)>>8;k=g&255;d=n(o,f,k);m=true;for(j=0;j<a.length;j++){q=a[j];h=(q&16711680)>>16;r=(q&65280)>>8;c=q&255;b=n(h,r,c);p=e(o,f,k,h,r,c);if((Math.abs(d-b)<40)||(p<200)){m=false;break}}l++}while(!m&&l<=10);return"#"+(16777216+g).toString(16).substr(1,6)};return exports});
\ No newline at end of file
+define(function(){var b=Backbone.Model.extend({defaults:{ajax_settings:{},interval:1000,success_fn:function(c){return true}},go:function(){var f=$.Deferred(),e=this,h=e.get("ajax_settings"),g=e.get("success_fn"),d=e.get("interval"),c=function(){$.ajax(h).success(function(i){if(g(i)){f.resolve(i)}else{setTimeout(c,d)}})};c();return f}});var a=function(c){if(!c){c="#ffffff"}if(typeof(c)==="string"){c=[c]}for(var l=0;l<c.length;l++){c[l]=parseInt(c[l].slice(1),16)}var p=function(v,u,i){return((v*299)+(u*587)+(i*114))/1000};var g=function(x,w,y,u,i,v){return(Math.max(x,u)-Math.min(x,u))+(Math.max(w,i)-Math.min(w,i))+(Math.max(y,v)-Math.min(y,v))};var j,q,h,m,s,k,t,e,f,d,r,o=false,n=0;do{j=Math.round(Math.random()*16777215);q=(j&16711680)>>16;h=(j&65280)>>8;m=j&255;f=p(q,h,m);o=true;for(l=0;l<c.length;l++){s=c[l];k=(s&16711680)>>16;t=(s&65280)>>8;e=s&255;d=p(k,t,e);r=g(q,h,m,k,t,e);if((Math.abs(f-d)<40)||(r<200)){o=false;break}}n++}while(!o&&n<=10);return"#"+(16777216+j).toString(16).substr(1,6)};return{ServerStateDeferred:b,get_random_color:a}});
\ No newline at end of file
diff -r d2e30720ba78cbee8b6a6a63daa91702778040bc -r ba8c49884f7daab5df8b62bd631157058c7ee910 static/scripts/viz/trackster/util.js
--- a/static/scripts/viz/trackster/util.js
+++ b/static/scripts/viz/trackster/util.js
@@ -1,12 +1,10 @@
define(function(){
-exports = {};
-
/**
* Implementation of a server-state based deferred. Server is repeatedly polled, and when
* condition is met, deferred is resolved.
*/
-exports.ServerStateDeferred = Backbone.Model.extend({
+var ServerStateDeferred = Backbone.Model.extend({
defaults: {
ajax_settings: {},
interval: 1000,
@@ -44,7 +42,7 @@
* or set of colors.
* @param colors a color or list of colors in the format '#RRGGBB'
*/
-exports.get_random_color = function(colors) {
+var get_random_color = function(colors) {
// Default for colors is white.
if (!colors) { colors = "#ffffff"; }
@@ -110,6 +108,9 @@
return '#' + ( 0x1000000 + new_color ).toString(16).substr(1,6);
};
-return exports;
+return {
+ ServerStateDeferred : ServerStateDeferred,
+ get_random_color : get_random_color
+};
-})
\ No newline at end of file
+});
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/d2e30720ba78/
changeset: d2e30720ba78
user: jgoecks
date: 2013-02-12 18:01:37
summary: Pack scripts.
affected #: 2 files
diff -r a6fe104c109feea61995567336a1aaf515acf0d5 -r d2e30720ba78cbee8b6a6a63daa91702778040bc static/scripts/packed/mvc/data.js
--- a/static/scripts/packed/mvc/data.js
+++ b/static/scripts/packed/mvc/data.js
@@ -1,1 +1,1 @@
-define(["libs/backbone/backbone-relational"],function(){var b=Backbone.RelationalModel.extend({});var c=Backbone.RelationalModel.extend({defaults:{id:"",type:"",name:"",hda_ldda:"hda",metadata:null},initialize:function(){var f=new b();_.each(_.keys(this.attributes),function(g){if(g.indexOf("metadata_")===0){var h=g.split("metadata_")[1];f.set(h,this.attributes[g]);delete this.attributes[g]}},this);this.set("metadata",f)},get_metadata:function(f){return this.attributes.metadata.get(f)},urlRoot:galaxy_paths.get("datasets_url")});var a=c.extend({defaults:_.extend({},c.prototype.defaults,{chunk_url:null,first_data_chunk:null,chunk_index:-1,at_eof:false}),initialize:function(f){c.prototype.initialize.call(this);chunk_index=(this.attributes.first_data_chunk?1:0)},set_first_chunk:function(f){this.attributes.first_data_chunk=f;this.attributes.chunk_index=1},get_next_chunk:function(){if(this.attributes.at_eof){return null}var f=this,g=$.Deferred();$.getJSON(this.attributes.chunk_url,{chunk:f.attributes.chunk_index++}).success(function(h){var i;if(h.ck_data!==""){i=h}else{f.attributes.at_eof=true;i=null}g.resolve(i)});return g}});var e=Backbone.Collection.extend({model:c});var d=Backbone.View.extend({initialize:function(f){},render:function(){this.$el.append($("<div/>").attr("id","loading_indicator"));var i=$("<table/>").attr({id:"content_table",cellpadding:0});this.$el.append(i);var f=this.model.get_metadata("column_names");if(f){i.append("<tr><th>"+f.join("</th><th>")+"</th></tr>")}var h=this.model.get("first_data_chunk");if(h){this._renderChunk(h)}var g=this;$(window).scroll(function(){if($(window).scrollTop()===$(document).height()-$(window).height()){$.when(g.model.get_next_chunk()).then(function(j){if(j){g._renderChunk(j)}})}});$("#loading_indicator").ajaxStart(function(){$(this).show()}).ajaxStop(function(){$(this).hide()})},_renderCell:function(h,f,i){var g=this.model.get_metadata("column_types");if(i!==undefined){return $("<td>").attr("colspan",i).addClass("stringalign").text(h)}else{if(g[f]==="str"||g==="list"){return $("<td>").addClass("stringalign").text(h)}else{return $("<td>").text(h)}}},_renderRow:function(f){var g=f.split("\t"),i=$("<tr>"),h=this.model.get_metadata("columns");if(g.length===h){_.each(g,function(k,j){i.append(this._renderCell(k,j))},this)}else{if(g.length>h){_.each(g.slice(0,h-1),function(k,j){i.append(this._renderCell(k,j))},this);i.append(this._renderCell(g.slice(h-1).join("\t"),h-1))}else{if(h>5&&g.length===h-1){_.each(g,function(k,j){i.append(this._renderCell(k,j))},this);i.append($("<td>"))}else{i.append(this._renderCell(f,0,h))}}}return i},_renderChunk:function(f){var g=this.$el.find("table");_.each(f.ck_data.split("\n"),function(h,i){g.append(this._renderRow(h))},this)}});return{Dataset:c,TabularDataset:a,DatasetCollection:e,TabularDatasetChunkedView:d}});
\ No newline at end of file
+define(["libs/backbone/backbone-relational"],function(){var c=Backbone.RelationalModel.extend({});var d=Backbone.RelationalModel.extend({defaults:{id:"",type:"",name:"",hda_ldda:"hda",metadata:null},initialize:function(){var h=new c();_.each(_.keys(this.attributes),function(i){if(i.indexOf("metadata_")===0){var j=i.split("metadata_")[1];h.set(j,this.attributes[i]);delete this.attributes[i]}},this);this.set("metadata",h)},get_metadata:function(h){return this.attributes.metadata.get(h)},urlRoot:galaxy_paths.get("datasets_url")});var b=d.extend({defaults:_.extend({},d.prototype.defaults,{chunk_url:null,first_data_chunk:null,chunk_index:-1,at_eof:false}),initialize:function(h){d.prototype.initialize.call(this);this.attributes.chunk_index=(this.attributes.first_data_chunk?1:0)},get_next_chunk:function(){if(this.attributes.at_eof){return null}var h=this,i=$.Deferred();$.getJSON(this.attributes.chunk_url,{chunk:h.attributes.chunk_index++}).success(function(j){var k;if(j.ck_data!==""){k=j}else{h.attributes.at_eof=true;k=null}i.resolve(k)});return i}});var f=Backbone.Collection.extend({model:d});var e=Backbone.View.extend({initialize:function(h){},render:function(){this.$el.append($("<div/>").attr("id","loading_indicator"));var l=$("<table/>").attr({id:"content_table",cellpadding:0});this.$el.append(l);var h=this.model.get_metadata("column_names");if(h){l.append("<tr><th>"+h.join("</th><th>")+"</th></tr>")}var j=this.model.get("first_data_chunk");if(j){this._renderChunk(j)}var i=this,m=_.find(this.$el.parents(),function(n){return $(n).css("overflow")==="auto"}),k=false;if(!m){m=window}m=$(m);m.scroll(function(){if(!k&&(i.$el.height()-m.scrollTop()-m.height()<=0)){k=true;$.when(i.model.get_next_chunk()).then(function(n){if(n){i._renderChunk(n);k=false}})}});$("#loading_indicator").ajaxStart(function(){$(this).show()}).ajaxStop(function(){$(this).hide()})},_renderCell:function(j,h,k){var i=this.model.get_metadata("column_types");if(k!==undefined){return $("<td>").attr("colspan",k).addClass("stringalign").text(j)}else{if(i[h]==="str"||i==="list"){return $("<td>").addClass("stringalign").text(j)}else{return $("<td>").text(j)}}},_renderRow:function(h){var i=h.split("\t"),k=$("<tr>"),j=this.model.get_metadata("columns");if(i.length===j){_.each(i,function(m,l){k.append(this._renderCell(m,l))},this)}else{if(i.length>j){_.each(i.slice(0,j-1),function(m,l){k.append(this._renderCell(m,l))},this);k.append(this._renderCell(i.slice(j-1).join("\t"),j-1))}else{if(j>5&&i.length===j-1){_.each(i,function(m,l){k.append(this._renderCell(m,l))},this);k.append($("<td>"))}else{k.append(this._renderCell(h,0,j))}}}return k},_renderChunk:function(h){var i=this.$el.find("table");_.each(h.ck_data.split("\n"),function(j,k){i.append(this._renderRow(j))},this)}});var a=function(k,i,l,h){var j=new i({model:new k(l)});j.render();if(h){h.append(j.$el)}return j};var g=function(j,h){var i=$("<div/>").appendTo(h);return new e({el:i,model:new b(j)}).render()};return{Dataset:d,TabularDataset:b,DatasetCollection:f,TabularDatasetChunkedView:e,createTabularDatasetChunkedView:g}});
\ No newline at end of file
diff -r a6fe104c109feea61995567336a1aaf515acf0d5 -r d2e30720ba78cbee8b6a6a63daa91702778040bc static/scripts/packed/mvc/history/history-model.js
--- a/static/scripts/packed/mvc/history/history-model.js
+++ b/static/scripts/packed/mvc/history/history-model.js
@@ -1,1 +1,1 @@
-var History=BaseModel.extend(LoggableMixin).extend({defaults:{id:"",name:"",state:"",diskSize:0,deleted:false,annotation:null,message:null},urlRoot:"api/histories/",url:function(){return"api/histories/"+this.get("id")},initialize:function(a,b){this.log(this+".initialize:",a,b);this.hdas=new HDACollection();if(b){if(_.isArray(b)){this.hdas.reset(b);this.checkForUpdates()}else{if(_.isString(b)&&(b.match(/error/i))){alert(_l("Error loading bootstrapped history")+":\n"+b)}}}},loadFromApi:function(a,c){var b=this;b.attributes.id=a;jQuery.when(jQuery.ajax("api/users/current"),b.fetch()).then(function(e,d){b.attributes.user=e[0];b.trigger("loaded:user",e[0]);b.trigger("loaded",d[0])}).then(function(){jQuery.ajax(b.url()+"/contents?"+jQuery.param({ids:b.hdaIdsFromStateIds().join(",")})).success(function(d){b.hdas.reset(d);b.checkForUpdates();b.trigger("loaded:hdas",d);if(c){callback(b)}})})},hdaIdsFromStateIds:function(){return _.reduce(_.values(this.get("state_ids")),function(b,a){return b.concat(a)})},checkForUpdates:function(a){if(this.hdas.running().length){this.stateUpdater()}else{this.trigger("ready")}return this},stateUpdater:function(){var c=this,a=this.get("state"),b=this.get("state_ids");jQuery.ajax("api/histories/"+this.get("id")).success(function(d){c.set(d);c.log("current history state:",c.get("state"),"(was)",a,"new size:",c.get("nice_size"));var e=[];_.each(_.keys(d.state_ids),function(g){var f=_.difference(d.state_ids[g],b[g]);e=e.concat(f)});if(e.length){c.fetchHdaUpdates(e)}if((c.get("state")===HistoryDatasetAssociation.STATES.RUNNING)||(c.get("state")===HistoryDatasetAssociation.STATES.QUEUED)){setTimeout(function(){c.stateUpdater()},History.UPDATE_DELAY)}else{c.trigger("ready")}}).error(function(f,d,e){if(!((f.readyState===0)&&(f.status===0))){alert(_l("Error getting history updates from the server.")+"\n"+e);c.log("stateUpdater error:",e,"responseText:",f.responseText)}})},fetchHdaUpdates:function(b){var a=this;jQuery.ajax({url:this.url()+"/contents?"+jQuery.param({ids:b.join(",")}),error:function(h,c,d){if((h.readyState===0)&&(h.status===0)){return}var f=JSON.parse(h.responseText);if(_.isArray(f)){var e=_.groupBy(f,function(i){if(_.has(i,"error")){return"errored"}return"ok"});a.log("fetched, errored datasets:",e.errored);a.updateHdas(f)}else{var g=_l("ERROR updating hdas from api history contents")+": ";a.log(g,b,h,c,d,errorJSON);alert(g+b.join(","))}},success:function(d,c,e){a.log(a+".fetchHdaUpdates, success:",c,e);a.updateHdas(d)}})},updateHdas:function(a){var c=this,b=[];c.log(c+".updateHdas:",a);_.each(a,function(e,f){var d=c.hdas.get(e.id);if(d){c.log("found existing model in list for id "+e.id+", updating...:");d.set(e)}else{c.log("NO existing model for id "+e.id+", creating...:");b.push(e)}});if(b.length){c.addHdas(b)}},addHdas:function(a){var b=this;_.each(a,function(c,d){var e=b.hdas.hidToCollectionIndex(c.hid);c.history_id=b.get("id");b.hdas.add(new HistoryDatasetAssociation(c),{at:e,silent:true})});b.hdas.trigger("add",a)},toString:function(){var a=(this.get("name"))?(","+this.get("name")):("");return"History("+this.get("id")+a+")"}});History.UPDATE_DELAY=4000;var HistoryCollection=Backbone.Collection.extend(LoggableMixin).extend({model:History,urlRoot:"api/histories"});
\ No newline at end of file
+var History=BaseModel.extend(LoggableMixin).extend({defaults:{id:"",name:"",state:"",diskSize:0,deleted:false,annotation:null,message:null},urlRoot:"api/histories/",url:function(){return"api/histories/"+this.get("id")},initialize:function(a,b){this.log(this+".initialize:",a,b);this.hdas=new HDACollection();if(b){if(_.isArray(b)){this.hdas.reset(b);this.checkForUpdates()}else{if(_.isString(b)&&(b.match(/error/i))){alert(_l("Error loading bootstrapped history")+":\n"+b)}}}},loadFromApi:function(a,c){var b=this;b.attributes.id=a;jQuery.when(jQuery.ajax("api/users/current"),b.fetch()).then(function(e,d){b.attributes.user=e[0];b.trigger("loaded:user",e[0]);b.trigger("loaded",d[0])}).then(function(){jQuery.ajax(b.url()+"/contents?"+jQuery.param({ids:b.hdaIdsFromStateIds().join(",")})).success(function(d){b.hdas.reset(d);b.checkForUpdates();b.trigger("loaded:hdas",d);if(c){callback(b)}})})},hdaIdsFromStateIds:function(){return _.reduce(_.values(this.get("state_ids")),function(b,a){return b.concat(a)})},checkForUpdates:function(a){if(this.hdas.running().length){this.stateUpdater()}else{this.trigger("ready")}return this},stateUpdater:function(){var c=this,a=this.get("state"),b=this.get("state_ids");jQuery.ajax("api/histories/"+this.get("id")).success(function(d){c.set(d);c.log("current history state:",c.get("state"),"(was)",a,"new size:",c.get("nice_size"));var e=[];_.each(_.keys(d.state_ids),function(g){var f=_.difference(d.state_ids[g],b[g]);e=e.concat(f)});if(e.length){c.fetchHdaUpdates(e)}if((c.get("state")===HistoryDatasetAssociation.STATES.RUNNING)||(c.get("state")===HistoryDatasetAssociation.STATES.QUEUED)){setTimeout(function(){c.stateUpdater()},History.UPDATE_DELAY)}else{c.trigger("ready")}}).error(function(f,d,e){if(!((f.readyState===0)&&(f.status===0))){alert(_l("Error getting history updates from the server.")+"\n"+e);c.log("stateUpdater error:",e,"responseText:",f.responseText)}})},fetchHdaUpdates:function(b){var a=this;jQuery.ajax({url:this.url()+"/contents?"+jQuery.param({ids:b.join(",")}),error:function(h,c,d){if((h.readyState===0)&&(h.status===0)){return}var f=JSON.parse(h.responseText);if(_.isArray(f)){var e=_.groupBy(f,function(i){if(_.has(i,"error")){return"errored"}return"ok"});a.log("fetched, errored datasets:",e.errored);a.updateHdas(f)}else{var g=_l("ERROR updating hdas from api history contents")+": ";a.log(g,b,h,c,d,f);alert(g+b.join(","))}},success:function(d,c,e){a.log(a+".fetchHdaUpdates, success:",c,e);a.updateHdas(d)}})},updateHdas:function(a){var c=this,b=[];c.log(c+".updateHdas:",a);_.each(a,function(e,f){var d=c.hdas.get(e.id);if(d){c.log("found existing model in list for id "+e.id+", updating...:");d.set(e)}else{c.log("NO existing model for id "+e.id+", creating...:");b.push(e)}});if(b.length){c.addHdas(b)}},addHdas:function(a){var b=this;_.each(a,function(c,d){var e=b.hdas.hidToCollectionIndex(c.hid);c.history_id=b.get("id");b.hdas.add(new HistoryDatasetAssociation(c),{at:e,silent:true})});b.hdas.trigger("add",a)},toString:function(){var a=(this.get("name"))?(","+this.get("name")):("");return"History("+this.get("id")+a+")"}});History.UPDATE_DELAY=4000;var HistoryCollection=Backbone.Collection.extend(LoggableMixin).extend({model:History,urlRoot:"api/histories"});
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
3 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/1f1072317efd/
changeset: 1f1072317efd
branch: stable
user: natefoo
date: 2013-02-12 14:46:28
summary: Allow the CLI runner to handle command stdout >65K.
affected #: 2 files
diff -r 961ae35ba61230ac1f5991b7629e5da0559cd0b5 -r 1f1072317efd5cf82cb791d75ba968c4bacffaf4 lib/galaxy/jobs/runners/cli.py
--- a/lib/galaxy/jobs/runners/cli.py
+++ b/lib/galaxy/jobs/runners/cli.py
@@ -316,6 +316,7 @@
if which_try == self.app.config.retry_job_output_collection:
stdout = ''
stderr = 'Job output not returned from cluster'
+ exit_code = 0
log.debug( stderr )
else:
time.sleep(1)
diff -r 961ae35ba61230ac1f5991b7629e5da0559cd0b5 -r 1f1072317efd5cf82cb791d75ba968c4bacffaf4 lib/galaxy/jobs/runners/cli_shell/rsh.py
--- a/lib/galaxy/jobs/runners/cli_shell/rsh.py
+++ b/lib/galaxy/jobs/runners/cli_shell/rsh.py
@@ -4,6 +4,7 @@
import time
import logging
+import tempfile
import subprocess
from galaxy.util.bunch import Bunch
@@ -28,7 +29,9 @@
fullcmd = '%s %s %s' % (self.rsh, self.hostname, cmd)
else:
fullcmd = '%s -l %s %s %s' % (self.rsh, self.username, self.hostname, cmd)
- p = subprocess.Popen(fullcmd, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ # Read stdout to a tempfile in case it's large (>65K)
+ outf = tempfile.TemporaryFile()
+ p = subprocess.Popen(fullcmd, shell=True, stdin=None, stdout=outf, stderr=subprocess.PIPE)
# poll until timeout
for i in range(timeout/3):
r = p.poll()
@@ -44,7 +47,8 @@
except:
log.warning('Killing pid %s (cmd: "%s") with signal %s failed' % (p.pid, fullcmd, sig))
return Bunch(stdout='', stderr='Execution timed out', returncode=-1)
- return Bunch(stdout=p.stdout.read(), stderr=p.stderr.read(), returncode=p.returncode)
+ outf.seek(0)
+ return Bunch(stdout=outf.read(), stderr=p.stderr.read(), returncode=p.returncode)
class SecureShell(RemoteShell):
https://bitbucket.org/galaxy/galaxy-central/commits/056ff69b05c4/
changeset: 056ff69b05c4
user: natefoo
date: 2013-02-12 14:46:28
summary: Allow the CLI runner to handle command stdout >65K.
affected #: 2 files
diff -r e5dcefc328bb4fadcd0097787d167c7f43db5627 -r 056ff69b05c435f26650c5e7f65cffd764a40a08 lib/galaxy/jobs/runners/cli.py
--- a/lib/galaxy/jobs/runners/cli.py
+++ b/lib/galaxy/jobs/runners/cli.py
@@ -316,6 +316,7 @@
if which_try == self.app.config.retry_job_output_collection:
stdout = ''
stderr = 'Job output not returned from cluster'
+ exit_code = 0
log.debug( stderr )
else:
time.sleep(1)
diff -r e5dcefc328bb4fadcd0097787d167c7f43db5627 -r 056ff69b05c435f26650c5e7f65cffd764a40a08 lib/galaxy/jobs/runners/cli_shell/rsh.py
--- a/lib/galaxy/jobs/runners/cli_shell/rsh.py
+++ b/lib/galaxy/jobs/runners/cli_shell/rsh.py
@@ -4,6 +4,7 @@
import time
import logging
+import tempfile
import subprocess
from galaxy.util.bunch import Bunch
@@ -28,7 +29,9 @@
fullcmd = '%s %s %s' % (self.rsh, self.hostname, cmd)
else:
fullcmd = '%s -l %s %s %s' % (self.rsh, self.username, self.hostname, cmd)
- p = subprocess.Popen(fullcmd, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ # Read stdout to a tempfile in case it's large (>65K)
+ outf = tempfile.TemporaryFile()
+ p = subprocess.Popen(fullcmd, shell=True, stdin=None, stdout=outf, stderr=subprocess.PIPE)
# poll until timeout
for i in range(timeout/3):
r = p.poll()
@@ -44,7 +47,8 @@
except:
log.warning('Killing pid %s (cmd: "%s") with signal %s failed' % (p.pid, fullcmd, sig))
return Bunch(stdout='', stderr='Execution timed out', returncode=-1)
- return Bunch(stdout=p.stdout.read(), stderr=p.stderr.read(), returncode=p.returncode)
+ outf.seek(0)
+ return Bunch(stdout=outf.read(), stderr=p.stderr.read(), returncode=p.returncode)
class SecureShell(RemoteShell):
https://bitbucket.org/galaxy/galaxy-central/commits/a6fe104c109f/
changeset: a6fe104c109f
user: natefoo
date: 2013-02-12 15:04:17
summary: Merged heads.
affected #: 2 files
diff -r 056ff69b05c435f26650c5e7f65cffd764a40a08 -r a6fe104c109feea61995567336a1aaf515acf0d5 tools/ngs_rna/tophat2_wrapper.py
--- a/tools/ngs_rna/tophat2_wrapper.py
+++ b/tools/ngs_rna/tophat2_wrapper.py
@@ -22,7 +22,7 @@
parser.add_option( '', '--mate-std-dev', dest='mate_std_dev', help='Standard deviation of distribution on inner distances between male pairs.' )
parser.add_option( '', '--read-mismatches', dest='read_mismatches' )
parser.add_option( '', '--bowtie-n', action="store_true", dest='bowtie_n' )
- parser.add_option( '', '--report-discordant-pair-alignments', action="store_true", dest='report_discordant_pairs' )
+ parser.add_option( '', '--no-discordant', action="store_true", dest='report_concordant_pairs_only' )
parser.add_option( '-a', '--min-anchor-length', dest='min_anchor_length',
help='The "anchor length". TopHat will report junctions spanned by reads with at least this many bases on each side of the junction.' )
parser.add_option( '-m', '--splice-mismatches', dest='splice_mismatches', help='The maximum number of mismatches that can appear in the anchor region of a spliced alignment.' )
@@ -141,8 +141,8 @@
opts = '-p %s %s' % ( options.num_threads, space )
if options.single_paired == 'paired':
opts += ' -r %s' % options.mate_inner_dist
- if options.report_discordant_pairs:
- opts += ' --report-discordant-pair-alignments'
+ if options.report_concordant_pairs_only:
+ opts += ' --no-discordant'
# Read group options.
if options.rgid:
if not options.rglb or not options.rgpl or not options.rgsm:
diff -r 056ff69b05c435f26650c5e7f65cffd764a40a08 -r a6fe104c109feea61995567336a1aaf515acf0d5 tools/ngs_rna/tophat2_wrapper.xml
--- a/tools/ngs_rna/tophat2_wrapper.xml
+++ b/tools/ngs_rna/tophat2_wrapper.xml
@@ -37,8 +37,8 @@
-r $singlePaired.mate_inner_distance
--mate-std-dev=$singlePaired.mate_std_dev
- #if str($singlePaired.report_discordant_pairs) == "Yes":
- --report-discordant-pair-alignments
+ #if str($singlePaired.report_discordant_pairs) == "No":
+ --no-discordant
#end if
#end if
@@ -138,8 +138,8 @@
<param name="mate_std_dev" type="integer" value="20" label="Std. Dev for Distance between Mate Pairs" help="The standard deviation for the distribution on inner distances between mate pairs."/><!-- Discordant pairs. --><param name="report_discordant_pairs" type="select" label="Report discordant pair alignments?">
- <option selected="true" value="No">No</option>
- <option value="Yes">Yes</option>
+ <option value="No">No</option>
+ <option selected="True" value="Yes">Yes</option></param></when></conditional>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: joachimjacob: Fixed --no-discordant parameter in tophat2_wrapper.xml and .py.
by Bitbucket 12 Feb '13
by Bitbucket 12 Feb '13
12 Feb '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b1d3a6a907d1/
changeset: b1d3a6a907d1
user: joachimjacob
date: 2013-02-12 09:55:44
summary: Fixed --no-discordant parameter in tophat2_wrapper.xml and .py.
affected #: 2 files
diff -r e5dcefc328bb4fadcd0097787d167c7f43db5627 -r b1d3a6a907d1ee4847fbcea61a162067b3be0f49 tools/ngs_rna/tophat2_wrapper.py
--- a/tools/ngs_rna/tophat2_wrapper.py
+++ b/tools/ngs_rna/tophat2_wrapper.py
@@ -22,7 +22,7 @@
parser.add_option( '', '--mate-std-dev', dest='mate_std_dev', help='Standard deviation of distribution on inner distances between male pairs.' )
parser.add_option( '', '--read-mismatches', dest='read_mismatches' )
parser.add_option( '', '--bowtie-n', action="store_true", dest='bowtie_n' )
- parser.add_option( '', '--report-discordant-pair-alignments', action="store_true", dest='report_discordant_pairs' )
+ parser.add_option( '', '--no-discordant', action="store_true", dest='report_concordant_pairs_only' )
parser.add_option( '-a', '--min-anchor-length', dest='min_anchor_length',
help='The "anchor length". TopHat will report junctions spanned by reads with at least this many bases on each side of the junction.' )
parser.add_option( '-m', '--splice-mismatches', dest='splice_mismatches', help='The maximum number of mismatches that can appear in the anchor region of a spliced alignment.' )
@@ -141,8 +141,8 @@
opts = '-p %s %s' % ( options.num_threads, space )
if options.single_paired == 'paired':
opts += ' -r %s' % options.mate_inner_dist
- if options.report_discordant_pairs:
- opts += ' --report-discordant-pair-alignments'
+ if options.report_concordant_pairs_only:
+ opts += ' --no-discordant'
# Read group options.
if options.rgid:
if not options.rglb or not options.rgpl or not options.rgsm:
diff -r e5dcefc328bb4fadcd0097787d167c7f43db5627 -r b1d3a6a907d1ee4847fbcea61a162067b3be0f49 tools/ngs_rna/tophat2_wrapper.xml
--- a/tools/ngs_rna/tophat2_wrapper.xml
+++ b/tools/ngs_rna/tophat2_wrapper.xml
@@ -37,8 +37,8 @@
-r $singlePaired.mate_inner_distance
--mate-std-dev=$singlePaired.mate_std_dev
- #if str($singlePaired.report_discordant_pairs) == "Yes":
- --report-discordant-pair-alignments
+ #if str($singlePaired.report_discordant_pairs) == "No":
+ --no-discordant
#end if
#end if
@@ -138,8 +138,8 @@
<param name="mate_std_dev" type="integer" value="20" label="Std. Dev for Distance between Mate Pairs" help="The standard deviation for the distribution on inner distances between mate pairs."/><!-- Discordant pairs. --><param name="report_discordant_pairs" type="select" label="Report discordant pair alignments?">
- <option selected="true" value="No">No</option>
- <option value="Yes">Yes</option>
+ <option value="No">No</option>
+ <option selected="True" value="Yes">Yes</option></param></when></conditional>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: inithello: Uncomment the previously added sentry_dsn.
by Bitbucket 12 Feb '13
by Bitbucket 12 Feb '13
12 Feb '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/e5dcefc328bb/
changeset: e5dcefc328bb
user: inithello
date: 2013-02-12 05:17:13
summary: Uncomment the previously added sentry_dsn.
affected #: 1 file
diff -r 6be149267ed6016351819a0605213fb3d34b25ef -r e5dcefc328bb4fadcd0097787d167c7f43db5627 lib/galaxy/webapps/reports/config.py
--- a/lib/galaxy/webapps/reports/config.py
+++ b/lib/galaxy/webapps/reports/config.py
@@ -41,7 +41,7 @@
self.log_events = False
self.cookie_path = kwargs.get( "cookie_path", "/" )
# Error logging with sentry
- # self.sentry_dsn = kwargs.get( 'sentry_dsn', None )
+ self.sentry_dsn = kwargs.get( 'sentry_dsn', None )
#Parse global_conf
global_conf = kwargs.get( 'global_conf', None )
global_conf_parser = ConfigParser.ConfigParser()
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: inithello: Add sentry_dsn to reports webapp configuration.
by Bitbucket 12 Feb '13
by Bitbucket 12 Feb '13
12 Feb '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/6be149267ed6/
changeset: 6be149267ed6
user: inithello
date: 2013-02-12 05:15:34
summary: Add sentry_dsn to reports webapp configuration.
affected #: 1 file
diff -r 42e0e5d9b7a479d884f9556a59aadea7886c131e -r 6be149267ed6016351819a0605213fb3d34b25ef lib/galaxy/webapps/reports/config.py
--- a/lib/galaxy/webapps/reports/config.py
+++ b/lib/galaxy/webapps/reports/config.py
@@ -40,6 +40,8 @@
self.screencasts_url = kwargs.get( 'screencasts_url', None )
self.log_events = False
self.cookie_path = kwargs.get( "cookie_path", "/" )
+ # Error logging with sentry
+ # self.sentry_dsn = kwargs.get( 'sentry_dsn', None )
#Parse global_conf
global_conf = kwargs.get( 'global_conf', None )
global_conf_parser = ConfigParser.ConfigParser()
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: natefoo: Return a dict instead of a list if a [galaxy:tool_*] section is missing from the config.
by Bitbucket 11 Feb '13
by Bitbucket 11 Feb '13
11 Feb '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/42e0e5d9b7a4/
changeset: 42e0e5d9b7a4
user: natefoo
date: 2013-02-11 22:50:16
summary: Return a dict instead of a list if a [galaxy:tool_*] section is missing from the config.
affected #: 1 file
diff -r 41f4c9c9095919b080dc0e32a5d540865fdf0fa7 -r 42e0e5d9b7a479d884f9556a59aadea7886c131e lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -304,7 +304,7 @@
return rval
except ConfigParser.NoSectionError:
- return []
+ return {}
def get( self, key, default ):
return self.config_dict.get( key, default )
def get_bool( self, key, default ):
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: jgoecks: Use tabular chunked data diplay for shared/published datasets.
by Bitbucket 11 Feb '13
by Bitbucket 11 Feb '13
11 Feb '13
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/41f4c9c90959/
changeset: 41f4c9c90959
user: jgoecks
date: 2013-02-11 21:56:50
summary: Use tabular chunked data diplay for shared/published datasets.
affected #: 5 files
diff -r 422f368eb0978b7d8ed5a320f1700603aea22ca1 -r 41f4c9c9095919b080dc0e32a5d540865fdf0fa7 lib/galaxy/datatypes/data.py
--- a/lib/galaxy/datatypes/data.py
+++ b/lib/galaxy/datatypes/data.py
@@ -69,6 +69,9 @@
<class 'galaxy.datatypes.metadata.MetadataParameter'>
"""
+ # Data is not chunkable by default.
+ CHUNKABLE = False
+
#: dictionary of metadata fields for this datatype::
metadata_spec = None
diff -r 422f368eb0978b7d8ed5a320f1700603aea22ca1 -r 41f4c9c9095919b080dc0e32a5d540865fdf0fa7 lib/galaxy/datatypes/tabular.py
--- a/lib/galaxy/datatypes/tabular.py
+++ b/lib/galaxy/datatypes/tabular.py
@@ -20,6 +20,9 @@
class Tabular( data.Text ):
"""Tab delimited data"""
+
+ # All tabular data is chunkable.
+ CHUNKABLE = True
CHUNK_SIZE = 50000
"""Add metadata elements"""
diff -r 422f368eb0978b7d8ed5a320f1700603aea22ca1 -r 41f4c9c9095919b080dc0e32a5d540865fdf0fa7 lib/galaxy/webapps/galaxy/controllers/dataset.py
--- a/lib/galaxy/webapps/galaxy/controllers/dataset.py
+++ b/lib/galaxy/webapps/galaxy/controllers/dataset.py
@@ -642,6 +642,11 @@
truncated, dataset_data = self.get_data( dataset, preview )
dataset.annotation = self.get_item_annotation_str( trans.sa_session, dataset.history.user, dataset )
+ # If dataset is chunkable, get first chunk.
+ first_chunk = None
+ if dataset.datatype.CHUNKABLE:
+ first_chunk = dataset.datatype.get_chunk(trans, dataset, 0)
+
# If data is binary or an image, stream without template; otherwise, use display template.
# TODO: figure out a way to display images in display template.
if isinstance(dataset.datatype, datatypes.binary.Binary) or isinstance(dataset.datatype, datatypes.images.Image) or isinstance(dataset.datatype, datatypes.images.Html):
@@ -658,8 +663,10 @@
user_item_rating = 0
ave_item_rating, num_ratings = self.get_ave_item_rating_data( trans.sa_session, dataset )
- return trans.fill_template_mako( "/dataset/display.mako", item=dataset, item_data=dataset_data, truncated=truncated,
- user_item_rating = user_item_rating, ave_item_rating=ave_item_rating, num_ratings=num_ratings )
+ return trans.fill_template_mako( "/dataset/display.mako", item=dataset, item_data=dataset_data,
+ truncated=truncated, user_item_rating = user_item_rating,
+ ave_item_rating=ave_item_rating, num_ratings=num_ratings,
+ first_chunk=first_chunk )
else:
raise web.httpexceptions.HTTPNotFound()
diff -r 422f368eb0978b7d8ed5a320f1700603aea22ca1 -r 41f4c9c9095919b080dc0e32a5d540865fdf0fa7 static/scripts/mvc/data.js
--- a/static/scripts/mvc/data.js
+++ b/static/scripts/mvc/data.js
@@ -102,7 +102,10 @@
});
/**
- * Provides table-based, dynamic view of a tabular dataset.
+ * Provides table-based, dynamic view of a tabular dataset.
+ * NOTE: view's el must be in DOM already and provided when
+ * createing the view so that scrolling event can be attached
+ * to the correct container.
*/
var TabularDatasetChunkedView = Backbone.View.extend({
@@ -129,13 +132,31 @@
this._renderChunk(first_chunk);
}
- // Show new chunks during scrolling.
- var self = this;
- $(window).scroll(function() {
- if ($(window).scrollTop() === $(document).height() - $(window).height()) {
+ // -- Show new chunks during scrolling. --
+
+ var self = this,
+ // Element that does the scrolling.
+ scroll_elt = _.find(this.$el.parents(), function(p) {
+ return $(p).css('overflow') === 'auto';
+ }),
+ // Flag to ensure that only one chunk is loaded at a time.
+ loading_chunk = false;
+
+ // If no scrolling element found, use window.
+ if (!scroll_elt) { scroll_elt = window; }
+
+ // Wrap scrolling element for easy access.
+ scroll_elt = $(scroll_elt);
+
+ // Set up chunk loading when scrolling using the scrolling element.
+ scroll_elt.scroll(function() {
+ // If not already loading a chunk and have scrolled to the bottom of this element, get next chunk.
+ if ( !loading_chunk && (self.$el.height() - scroll_elt.scrollTop() - scroll_elt.height() <= 0) ) {
+ loading_chunk = true;
$.when(self.model.get_next_chunk()).then(function(result) {
if (result) {
self._renderChunk(result);
+ loading_chunk = false;
}
});
}
@@ -218,7 +239,7 @@
if (parent_elt) {
parent_elt.append(a_view.$el);
}
-
+
return a_view;
};
@@ -227,7 +248,14 @@
* and appends to parent_elt.
*/
var createTabularDatasetChunkedView = function(dataset_config, parent_elt) {
- return createModelAndView(TabularDataset, TabularDatasetChunkedView, dataset_config, parent_elt);
+ // Create view element and add to parent.
+ var view_div = $('<div/>').appendTo(parent_elt);
+
+ // Create view with model, render, and return.
+ return new TabularDatasetChunkedView({
+ el: view_div,
+ model: new TabularDataset(dataset_config)
+ }).render();
};
return {
diff -r 422f368eb0978b7d8ed5a320f1700603aea22ca1 -r 41f4c9c9095919b080dc0e32a5d540865fdf0fa7 templates/webapps/galaxy/dataset/display.mako
--- a/templates/webapps/galaxy/dataset/display.mako
+++ b/templates/webapps/galaxy/dataset/display.mako
@@ -5,6 +5,35 @@
<%def name="javascripts()">
${parent.javascripts()}
+ ## If data is chunkable, use JavaScript for display.
+ %if item.datatype.CHUNKABLE:
+
+ <script type="text/javascript">
+ require.config({
+ baseUrl: "${h.url_for('/static/scripts')}",
+ shim: {
+ "libs/backbone/backbone": { exports: "Backbone" },
+ "libs/backbone/backbone-relational": ["libs/backbone/backbone"]
+ }
+ });
+
+ require(['mvc/data'], function(data) {
+ data.createTabularDatasetChunkedView(
+ // Dataset config. TODO: encode id.
+ _.extend( ${h.to_json_string( item.get_api_value() )},
+ {
+ chunk_url: "${h.url_for( controller='/dataset', action='display',
+ dataset_id=trans.security.encode_id( item.id ))}",
+ first_data_chunk: ${first_chunk}
+ }
+ ),
+ // Append view to body.
+ $('.page-body')
+ );
+ });
+ </script>
+
+ %endif
</%def><%def name="init()">
@@ -31,14 +60,17 @@
</%def><%def name="render_item( data, data_to_render )">
- %if truncated:
- <div class="warningmessagelarge">
- This dataset is large and only the first megabyte is shown below. |
- <a href="${h.url_for( controller='dataset', action='display_by_username_and_slug', username=data.history.user.username, slug=trans.security.encode_id( data.id ), preview=False )}">Show all</a>
- </div>
+ ## Chunkable data is rendered in JavaScript above; render unchunkable data below.
+ %if not data.datatype.CHUNKABLE:
+ %if truncated:
+ <div class="warningmessagelarge">
+ This dataset is large and only the first megabyte is shown below. |
+ <a href="${h.url_for( controller='dataset', action='display_by_username_and_slug', username=data.history.user.username, slug=trans.security.encode_id( data.id ), preview=False )}">Show all</a>
+ </div>
+ %endif
+ ## TODO: why is the default font size so small?
+ <pre style="font-size: 135%">${ data_to_render | h }</pre>
%endif
- ## TODO: why is the default font size so small?
- <pre style="font-size: 135%">${ data_to_render | h }</pre></%def>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0