mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Add baseline support for reviewing functional test results for installing repositories and executing functional tests on the contained tool inside a Galaxy instance for tools included in repositories in the tool shed.
This commit is contained in:
@@ -672,20 +672,32 @@ class RepositoryController( BaseUIController, common_util.ItemRatings ):
|
||||
status='error' ) )
|
||||
|
||||
@web.expose
|
||||
def display_tool_functional_test_errors( self, trans, repository_id, repository_metadata_id, **kwd ):
|
||||
def display_tool_functional_test_results( self, trans, repository_id, repository_metadata_id, **kwd ):
|
||||
"""
|
||||
The test framework in ~/test/install_and_test_tool_shed_repositories can be executed on a regularly defined schedule (e.g., via cron) to install appropriate
|
||||
repositories from a tool shed into a Galaxy instance and run defined functional tests for the tools included in the repository. This process affects the values
|
||||
if these columns in the repository_metadata table: tools_functionally_correct, do_not_test, time_last_tested and tool_test_errors. The tool_test_errors is
|
||||
slightly mis-named (it should have been named tool_test_results) it will contain a dictionary that includes information about the test environment even if all
|
||||
tests passed and the tools_functionally_correct column is set to True.
|
||||
The value of the tool_test_errors column will be a dictionary with the key / value pairs:
|
||||
"test_environment", {"architecture": "i386", "python_version": "2.5.4", "system": "Darwin 10.8.0"}
|
||||
"test_errors" [ { "test_id":<some test id>, "stdout":<stdout of running the test>, "stderr":<stderr of running the test>, "traceback":<traceback of running the test>]
|
||||
"""
|
||||
params = util.Params( kwd )
|
||||
message = util.restore_text( params.get( 'message', '' ) )
|
||||
status = params.get( 'status', 'done' )
|
||||
repository = suc.get_repository_by_id( trans.app, repository_id )
|
||||
repository = suc.get_repository_by_id( trans, repository_id )
|
||||
if repository:
|
||||
repository_metadata = suc.get_repository_metadata_by_id( trans, repository_metadata_id )
|
||||
changeset_revision = repository_metadata.changeset_revision
|
||||
if repository_metadata:
|
||||
metadata = repository_metadata.metadata
|
||||
if metadata:
|
||||
return trans.fill_template( '/webapps/tool_shed/repository/display_tool_functional_test_errors.mako',
|
||||
revision_label = suc.get_revision_label( trans, repository, repository_metadata.changeset_revision )
|
||||
return trans.fill_template( '/webapps/tool_shed/repository/display_tool_functional_test_results.mako',
|
||||
repository=repository,
|
||||
repository_metadata=repository_metadata,
|
||||
revision_label=revision_label,
|
||||
message=message,
|
||||
status=status )
|
||||
else:
|
||||
@@ -1636,7 +1648,6 @@ class RepositoryController( BaseUIController, common_util.ItemRatings ):
|
||||
downloadable=False )
|
||||
revision_label = suc.get_revision_label( trans, repository, repository.tip( trans.app ) )
|
||||
repository_metadata = None
|
||||
repository_metadata_id = None
|
||||
metadata = None
|
||||
is_malicious = False
|
||||
repository_dependencies = None
|
||||
@@ -1644,7 +1655,6 @@ class RepositoryController( BaseUIController, common_util.ItemRatings ):
|
||||
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, id, changeset_revision )
|
||||
if repository_metadata:
|
||||
revision_label = suc.get_revision_label( trans, repository, changeset_revision )
|
||||
repository_metadata_id = trans.security.encode_id( repository_metadata.id )
|
||||
metadata = repository_metadata.metadata
|
||||
is_malicious = repository_metadata.malicious
|
||||
else:
|
||||
@@ -1654,7 +1664,6 @@ class RepositoryController( BaseUIController, common_util.ItemRatings ):
|
||||
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, id, previous_changeset_revision )
|
||||
if repository_metadata:
|
||||
revision_label = suc.get_revision_label( trans, repository, previous_changeset_revision )
|
||||
repository_metadata_id = trans.security.encode_id( repository_metadata.id )
|
||||
metadata = repository_metadata.metadata
|
||||
is_malicious = repository_metadata.malicious
|
||||
if repository_metadata:
|
||||
@@ -1702,7 +1711,7 @@ class RepositoryController( BaseUIController, common_util.ItemRatings ):
|
||||
repo=repo,
|
||||
repository=repository,
|
||||
containers_dict=containers_dict,
|
||||
repository_metadata_id=repository_metadata_id,
|
||||
repository_metadata=repository_metadata,
|
||||
changeset_revision=changeset_revision,
|
||||
reviewed_by_user=reviewed_by_user,
|
||||
review_id=review_id,
|
||||
|
||||
@@ -2134,13 +2134,12 @@ def get_repo_info_tuple_contents( repo_info_tuple ):
|
||||
elif len( repo_info_tuple ) == 7:
|
||||
description, repository_clone_url, changeset_revision, ctx_rev, repository_owner, repository_dependencies, tool_dependencies = repo_info_tuple
|
||||
return description, repository_clone_url, changeset_revision, ctx_rev, repository_owner, repository_dependencies, tool_dependencies
|
||||
def get_repository_by_id( app, id ):
|
||||
def get_repository_by_id( trans, id ):
|
||||
"""Get a repository from the database via id."""
|
||||
sa_session = app.model.context.current
|
||||
if app.name == 'galaxy':
|
||||
return sa_session.query( app.model.ToolShedRepository ).get( id )
|
||||
if trans.webapp.name == 'galaxy':
|
||||
return trans.sa_session.query( trans.model.ToolShedRepository ).get( trans.security.decode_id( id ) )
|
||||
else:
|
||||
return sa_session.query( app.model.Repository ).get( id )
|
||||
return trans.sa_session.query( trans.model.Repository ).get( trans.security.decode_id( id ) )
|
||||
def get_repository_by_name( app, name ):
|
||||
"""Get a repository from the database via name."""
|
||||
sa_session = app.model.context.current
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
<%namespace file="/webapps/tool_shed/common/common.mako" import="*" />
|
||||
<%namespace file="/webapps/tool_shed/repository/common.mako" import="*" />
|
||||
|
||||
<%
|
||||
from galaxy.web.framework.helpers import time_ago
|
||||
|
||||
changeset_revision = repository_metadata.changeset_revision
|
||||
has_metadata = repository.metadata_revisions
|
||||
has_readme = metadata and 'readme' in metadata
|
||||
is_admin = trans.user_is_admin()
|
||||
is_new = repository.is_new( trans.app )
|
||||
is_deprecated = repository.deprecated
|
||||
|
||||
can_browse_contents = trans.webapp.name == 'tool_shed' and not is_new
|
||||
can_contact_owner = trans.user and trans.user != repository.user
|
||||
can_download = not is_new and ( not is_malicious or can_push )
|
||||
can_manage = is_admin or repository.user == trans.user
|
||||
can_push = trans.app.security_agent.can_push( trans.app, trans.user, repository )
|
||||
can_rate = repository.user != trans.user
|
||||
can_review_repository = has_metadata and not is_deprecated and trans.app.security_agent.user_can_review_repositories( trans.user )
|
||||
can_upload = can_push
|
||||
can_view_change_log = trans.webapp.name == 'tool_shed' and not is_new
|
||||
if repository_metadata.tool_test_errors:
|
||||
# The tool_test_errors is mis-named (it should have been named tool_test_results) it will contain a dictionary that includes information
|
||||
# about the test environment even if all tests passed and the repository_metadata.tools_functionally_correct column is set to True.
|
||||
tool_test_errors = repository_metadata.tool_test_errors
|
||||
test_environment_dict = tool_test_errors.get( 'test_environment', None )
|
||||
test_errors = tool_test_errors.get( 'test_errors', [] )
|
||||
else:
|
||||
tool_test_errors = None
|
||||
test_environment_dict = {}
|
||||
test_errors = []
|
||||
|
||||
if can_push:
|
||||
browse_label = 'Browse or delete repository tip files'
|
||||
else:
|
||||
browse_label = 'Browse repository tip files'
|
||||
%>
|
||||
|
||||
<%!
|
||||
def inherit(context):
|
||||
if context.get('use_panels'):
|
||||
return '/webapps/tool_shed/base_panels.mako'
|
||||
else:
|
||||
return '/base.mako'
|
||||
%>
|
||||
<%inherit file="${inherit(context)}"/>
|
||||
|
||||
<br/><br/>
|
||||
<ul class="manage-table-actions">
|
||||
%if is_new:
|
||||
<a class="action-button" href="${h.url_for( controller='upload', action='upload', repository_id=trans.security.encode_id( repository.id ) )}">Upload files to repository</a>
|
||||
%else:
|
||||
<li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Repository Actions</a></li>
|
||||
<div popupmenu="repository-${repository.id}-popup">
|
||||
%if can_review_repository:
|
||||
%if reviewed_by_user:
|
||||
<a class="action-button" href="${h.url_for( controller='repository_review', action='edit_review', id=review_id )}">Manage my review of this revision</a>
|
||||
%else:
|
||||
<a class="action-button" href="${h.url_for( controller='repository_review', action='create_review', id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">Add a review to this revision</a>
|
||||
%endif
|
||||
%endif
|
||||
%if can_manage:
|
||||
<a class="action-button" href="${h.url_for( controller='repository', action='manage_repository', id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">Manage repository</a>
|
||||
%else:
|
||||
<a class="action-button" href="${h.url_for( controller='repository', action='view_repository', id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">View repository</a>
|
||||
%endif
|
||||
%if can_upload:
|
||||
<a class="action-button" href="${h.url_for( controller='upload', action='upload', repository_id=trans.security.encode_id( repository.id ) )}">Upload files to repository</a>
|
||||
%endif
|
||||
%if can_view_change_log:
|
||||
<a class="action-button" href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">View change log</a>
|
||||
%endif
|
||||
%if can_browse_contents:
|
||||
<a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label}</a>
|
||||
%endif
|
||||
%if can_contact_owner:
|
||||
<a class="action-button" href="${h.url_for( controller='repository', action='contact_owner', id=trans.security.encode_id( repository.id ) )}">Contact repository owner</a>
|
||||
%endif
|
||||
%if can_download:
|
||||
<a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision, file_type='gz' )}">Download as a .tar.gz file</a>
|
||||
<a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision, file_type='bz2' )}">Download as a .tar.bz2 file</a>
|
||||
<a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision, file_type='zip' )}">Download as a zip file</a>
|
||||
%endif
|
||||
</div>
|
||||
%endif
|
||||
</ul>
|
||||
|
||||
%if message:
|
||||
${render_msg( message, status )}
|
||||
%endif
|
||||
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">Repository revision</div>
|
||||
<div class="toolFormBody">
|
||||
<div class="form-row">
|
||||
<label>Revision:</label>
|
||||
%if can_view_change_log:
|
||||
<a href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">${revision_label}</a>
|
||||
%else:
|
||||
${revision_label}
|
||||
%endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p/>
|
||||
%if can_download:
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">Repository '${repository.name}'</div>
|
||||
<div class="toolFormBody">
|
||||
<div class="form-row">
|
||||
<label>Clone this repository:</label>
|
||||
${render_clone_str( repository )}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
%else:
|
||||
<b>Repository name:</b><br/>
|
||||
${repository.name}
|
||||
%endif
|
||||
%if tool_test_errors:
|
||||
<p/>
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">Tool functional test results</div>
|
||||
<div class="toolFormBody">
|
||||
<div class="form-row">
|
||||
<label>Time tested:</label>
|
||||
${time_ago( repository_metadata.time_last_tested ) | h}
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<table width="100%">
|
||||
<tr bgcolor="#D8D8D8" width="100%"><td><b>Test environment</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Architecture:</label>
|
||||
${test_environment_dict.get( 'architecture', 'unknown' ) | h}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Python version:</label>
|
||||
${test_environment_dict.get( 'python_version', 'unknown' ) | h}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Operating system:</label>
|
||||
${test_environment_dict.get( 'system', 'unknown' ) | h}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<table width="100%">
|
||||
<tr bgcolor="#D8D8D8" width="100%"><td><b>Test results</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<table class="grid">
|
||||
%for test_results_dict in test_errors:
|
||||
<tr>
|
||||
<td bgcolor="#FFFFCC"><b>Test id</b></td>
|
||||
<td bgcolor="#FFFFCC">${test_results_dict.get( 'test_id', 'unknown' )}</td>
|
||||
</tr>
|
||||
%if repository_metadata.tools_functionally_correct:
|
||||
<tr>
|
||||
<td><b>Stdout</b></td>
|
||||
<td>${test_results_dict.get( 'stdout', '' )}</td>
|
||||
</tr>
|
||||
%else:
|
||||
<tr>
|
||||
<td><b>Stderr</b></td>
|
||||
<td>${test_results_dict.get( 'stderr', '' )}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Traceback</b></td>
|
||||
<td>${test_results_dict.get( 'traceback', '' )}</td>
|
||||
</tr>
|
||||
%endif
|
||||
%endfor
|
||||
</table>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
%endif
|
||||
@@ -26,6 +26,13 @@
|
||||
can_undeprecate = trans.user and ( is_admin or repository.user == trans.user ) and is_deprecated
|
||||
can_upload = can_push
|
||||
can_view_change_log = not is_new
|
||||
if repository_metadata:
|
||||
if repository_metadata.includes_tools and repository_metadata.tool_test_errors is not None:
|
||||
can_display_tool_functional_test_results = True
|
||||
else:
|
||||
can_display_tool_functional_test_results = False
|
||||
else:
|
||||
can_display_tool_functional_test_results = False
|
||||
|
||||
if can_push:
|
||||
browse_label = 'Browse or delete repository tip files'
|
||||
@@ -105,6 +112,9 @@
|
||||
%if can_undeprecate:
|
||||
<a class="action-button" href="${h.url_for( controller='repository', action='deprecate', id=trans.security.encode_id( repository.id ), mark_deprecated=False )}">Mark repository as not deprecated</a>
|
||||
%endif
|
||||
%if can_display_tool_functional_test_results:
|
||||
<a class="action-button" href="${h.url_for( controller='repository', action='display_tool_functional_test_results', repository_id=trans.security.encode_id( repository.id ), repository_metadata_id=trans.security.encode_id( repository_metadata.id ) )}">View tool functional test results</a>
|
||||
%endif
|
||||
%if can_download:
|
||||
<a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision, file_type='gz' )}">Download as a .tar.gz file</a>
|
||||
<a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision, file_type='bz2' )}">Download as a .tar.bz2 file</a>
|
||||
|
||||
Reference in New Issue
Block a user