#!/usr/bin/env python """Test driver for tool shed functional tests.""" import os import string import tempfile # This is for the tool shed application. from galaxy.webapps.galaxy.buildapp import app_factory as galaxy_app_factory from galaxy_test.driver import driver_util from tool_shed.test.base.api_util import get_admin_api_key from tool_shed.webapp import buildapp as toolshedbuildapp from tool_shed.webapp.app import UniverseApplication as ToolshedUniverseApplication from tool_shed.webapp.fast_app import initialize_fast_app as init_tool_shed_fast_app log = driver_util.build_logger() tool_sheds_conf_xml_template = """ """ shed_tool_conf_xml_template = """ """ tool_data_table_conf_xml_template = """ """ shed_data_manager_conf_xml_template = """ """ # Global variable to pass database contexts around - only needed for older # Tool Shed twill tests that didn't utilize the API for such interactions. tool_shed_context = None def build_shed_app(simple_kwargs): """Build a Galaxy app object from a simple keyword arguments. Construct paste style complex dictionary. Also setup "global" reference to sqlalchemy database context for tool shed database. """ log.info("Tool shed database connection: %s", simple_kwargs["database_connection"]) # TODO: Simplify global_conf to match Galaxy above... simple_kwargs["__file__"] = "tool_shed_wsgi.yml.sample" simple_kwargs["global_conf"] = driver_util.get_webapp_global_conf() app = ToolshedUniverseApplication(**simple_kwargs) log.info("Embedded Toolshed application started") global tool_shed_context tool_shed_context = app.model.context return app class ToolShedTestDriver(driver_util.TestDriver): """Instantiate a Galaxy-style TestDriver for testing the tool shed.""" def setup(self) -> None: """Entry point for test driver script.""" self.external_shed = bool(os.environ.get("TOOL_SHED_TEST_EXTERNAL", None)) if not self.external_shed: self._setup_local() else: # Going to also need to set TOOL_SHED_TEST_HOST. assert os.environ["TOOL_SHED_TEST_HOST"] def _setup_local(self): # ---- Configuration ------------------------------------------------------ # disable sensitive request limiting for the test suite os.environ["TOOL_SHED_SENSITIVE_API_REQUEST_LIMIT"] = "10000/second" tool_shed_test_tmp_dir = driver_util.setup_tool_shed_tmp_dir() if not os.path.isdir(tool_shed_test_tmp_dir): os.mkdir(tool_shed_test_tmp_dir) self.temp_directories.append(tool_shed_test_tmp_dir) shed_db_path = driver_util.database_files_path(tool_shed_test_tmp_dir, prefix="TOOL_SHED") shed_tool_data_table_conf_file = os.environ.get( "TOOL_SHED_TEST_TOOL_DATA_TABLE_CONF", os.path.join(tool_shed_test_tmp_dir, "shed_tool_data_table_conf.xml") ) galaxy_shed_data_manager_conf_file = os.environ.get( "GALAXY_SHED_DATA_MANAGER_CONF", os.path.join(tool_shed_test_tmp_dir, "test_shed_data_manager_conf.xml") ) default_tool_data_table_config_path = os.path.join(tool_shed_test_tmp_dir, "tool_data_table_conf.xml") galaxy_shed_tool_conf_file = os.environ.get( "GALAXY_TEST_SHED_TOOL_CONF", os.path.join(tool_shed_test_tmp_dir, "test_shed_tool_conf.xml") ) galaxy_migrated_tool_conf_file = os.environ.get( "GALAXY_TEST_MIGRATED_TOOL_CONF", os.path.join(tool_shed_test_tmp_dir, "test_migrated_tool_conf.xml") ) galaxy_tool_sheds_conf_file = os.environ.get( "GALAXY_TEST_TOOL_SHEDS_CONF", os.path.join(tool_shed_test_tmp_dir, "test_sheds_conf.xml") ) if "GALAXY_TEST_TOOL_DATA_PATH" in os.environ: tool_data_path = os.environ["GALAXY_TEST_TOOL_DATA_PATH"] else: tool_data_path = tempfile.mkdtemp(dir=tool_shed_test_tmp_dir) os.environ["GALAXY_TEST_TOOL_DATA_PATH"] = tool_data_path galaxy_db_path = driver_util.database_files_path(tool_shed_test_tmp_dir) shed_file_path = os.path.join(shed_db_path, "files") whoosh_index_dir = os.path.join(shed_db_path, "toolshed_whoosh_indexes") hgweb_config_dir = tempfile.mkdtemp(dir=tool_shed_test_tmp_dir) new_repos_path = tempfile.mkdtemp(dir=tool_shed_test_tmp_dir) galaxy_shed_tool_path = tempfile.mkdtemp(dir=tool_shed_test_tmp_dir) galaxy_migrated_tool_path = tempfile.mkdtemp(dir=tool_shed_test_tmp_dir) os.environ["TEST_HG_WEB_CONFIG_DIR"] = hgweb_config_dir print("Directory location for hgweb.config:", hgweb_config_dir) toolshed_database_conf = driver_util.database_conf(shed_db_path, prefix="TOOL_SHED") kwargs = dict( admin_users="test@bx.psu.edu", bootstrap_admin_api_key=get_admin_api_key(), allow_local_account_creation=True, allow_user_deletion=True, config_hg_for_dev=True, # Allow hg push without authentication for tests datatype_converters_config_file="datatype_converters_conf.xml.sample", file_path=shed_file_path, hgweb_config_dir=hgweb_config_dir, id_secret="changethisinproductiontoo", log_destination="stdout", new_file_path=new_repos_path, running_functional_tests=True, shed_tool_data_table_config=shed_tool_data_table_conf_file, smtp_server="smtp.dummy.string.tld", email_from="functional@localhost", use_heartbeat=False, whoosh_index_dir=whoosh_index_dir, ) kwargs.update(toolshed_database_conf) # Generate the tool_data_table_conf.xml file. with open(default_tool_data_table_config_path, "w") as fh: fh.write(tool_data_table_conf_xml_template) # Generate the shed_tool_data_table_conf.xml file. with open(shed_tool_data_table_conf_file, "w") as fh: fh.write(tool_data_table_conf_xml_template) os.environ["TOOL_SHED_TEST_TOOL_DATA_TABLE_CONF"] = shed_tool_data_table_conf_file # ---- Run tool shed webserver ------------------------------------------------------ # TODO: Needed for hg middleware ('lib/galaxy/webapps/tool_shed/framework/middleware/hg.py') tool_shed_server_wrapper = driver_util.launch_server( app_factory=lambda: build_shed_app(kwargs), webapp_factory=toolshedbuildapp.app_factory, galaxy_config=kwargs, prefix="TOOL_SHED", init_fast_app=init_tool_shed_fast_app, ) self.server_wrappers.append(tool_shed_server_wrapper) tool_shed_test_host = tool_shed_server_wrapper.host tool_shed_test_port = tool_shed_server_wrapper.port log.info(f"Functional tests will be run against {tool_shed_test_host}:{tool_shed_test_port}") # Used by get_filename in tool shed's testcase if "TOOL_SHED_TEST_FILE_DIR" not in os.environ: os.environ["TOOL_SHED_TEST_FILE_DIR"] = driver_util.TOOL_SHED_TEST_DATA # ---- Optionally start up a Galaxy instance ------------------------------------------------------ if "TOOL_SHED_TEST_OMIT_GALAXY" not in os.environ: # Generate the shed_tool_conf.xml file. tool_sheds_conf_template_parser = string.Template(tool_sheds_conf_xml_template) tool_sheds_conf_xml = tool_sheds_conf_template_parser.safe_substitute( shed_url=tool_shed_test_host, shed_port=tool_shed_test_port ) with open(galaxy_tool_sheds_conf_file, "w") as fh: fh.write(tool_sheds_conf_xml) # Generate the tool_sheds_conf.xml file. shed_tool_conf_template_parser = string.Template(shed_tool_conf_xml_template) shed_tool_conf_xml = shed_tool_conf_template_parser.safe_substitute(shed_tool_path=galaxy_shed_tool_path) with open(galaxy_shed_tool_conf_file, "w") as fh: fh.write(shed_tool_conf_xml) # Generate the migrated_tool_conf.xml file. migrated_tool_conf_xml = shed_tool_conf_template_parser.safe_substitute( shed_tool_path=galaxy_migrated_tool_path ) with open(galaxy_migrated_tool_conf_file, "w") as fh: fh.write(migrated_tool_conf_xml) os.environ["GALAXY_TEST_SHED_TOOL_CONF"] = galaxy_shed_tool_conf_file # Generate shed_data_manager_conf.xml if not os.environ.get("GALAXY_SHED_DATA_MANAGER_CONF"): with open(galaxy_shed_data_manager_conf_file, "w") as fh: fh.write(shed_data_manager_conf_xml_template) kwargs = dict( migrated_tools_config=galaxy_migrated_tool_conf_file, shed_data_manager_config_file=galaxy_shed_data_manager_conf_file, shed_tool_path=galaxy_shed_tool_path, tool_data_path=tool_data_path, tool_sheds_config_file=galaxy_tool_sheds_conf_file, ) kwargs.update( driver_util.setup_galaxy_config( galaxy_db_path, use_test_file_dir=False, default_install_db_merged=False, default_tool_data_table_config_path=default_tool_data_table_config_path, default_shed_tool_data_table_config=shed_tool_data_table_conf_file, enable_tool_shed_check=True, shed_tool_conf=galaxy_shed_tool_conf_file, update_integrated_tool_panel=True, ) ) print("Galaxy database connection:", kwargs["database_connection"]) # ---- Run galaxy webserver ------------------------------------------------------ galaxy_server_wrapper = driver_util.launch_server( app_factory=lambda: driver_util.build_galaxy_app(kwargs), webapp_factory=galaxy_app_factory, galaxy_config=kwargs, ) log.info(f"Galaxy tests will be run against {galaxy_server_wrapper.host}:{galaxy_server_wrapper.port}") self.server_wrappers.append(galaxy_server_wrapper)