def testLoadPluginsMissing(registry): # This case should not typically happen outside of the testing environment with pytest.raises(GirderException, match='Plugin missing is not installed'): plugin._loadPlugins(info={}, names=['missing']) assert plugin.loadedPlugins() == []
def testLoadMultiplePluginsWithFailure(registry, logprint): plugin._loadPlugins(['plugin1', 'plugin2'], {}) logprint.exception.assert_has_calls( [mock.call('Failed to load plugin plugin1')]) assert 'plugin1' in plugin.getPluginFailureInfo() assert plugin.loadedPlugins() == ['plugin2']
def testLoadMultiplePluginsWithFailure(registry, logprint): plugin._loadPlugins(['plugin1', 'plugin2'], {}) logprint.exception.assert_has_calls([ mock.call('Failed to load plugin plugin1') ]) assert 'plugin1' in plugin.getPluginFailureInfo() assert plugin.loadedPlugins() == ['plugin2']
def testLoadPluginsSingle(registry, logprint): plugin._loadPlugins(info={}, names=['plugin1']) assert set(plugin.loadedPlugins()) == {'plugin1'} plugin1Definition = plugin.getPlugin('plugin1') assert plugin1Definition is not None assert plugin1Definition.loaded is True plugin1Definition._testLoadMock.assert_called_once() logprint.success.assert_any_call('Loaded plugin "plugin1"')
def testLoadPluginsWithError(registry): with pytest.raises(Exception) as exception1: plugin._loadPlugins(info={}, names=['throws']) assert plugin.loadedPlugins() == [] # Try again, as this shouldn't corrupt the loading system with pytest.raises(Exception) as exception2: plugin._loadPlugins(info={}, names=['throws']) # Ensure the exception is new each time assert exception1.value is not exception2.value
def testLoadPluginsExclusion(registry): # Ignoring installed but not-requested plugins only happens in the testing environment, but # is critical functionality plugin._loadPlugins(info={}, names=['plugin1']) assert set(plugin.loadedPlugins()) == {'plugin1'} for pluginName in ['plugin2', 'plugin3']: pluginDefinition = plugin.getPlugin(pluginName) assert pluginDefinition is not None assert pluginDefinition.loaded is False pluginDefinition._testLoadMock.assert_not_called()
def testLoadPluginsWithDeps(registry, logprint): plugin._loadPlugins(info={}, names=['plugin2']) assert set(plugin.loadedPlugins()) == {'plugin1', 'plugin2'} for pluginName in ['plugin1', 'plugin2']: pluginDefinition = plugin.getPlugin(pluginName) assert pluginDefinition is not None assert pluginDefinition.loaded is True pluginDefinition._testLoadMock.assert_called_once() # Since plugin1 is the dependant, it must be loaded first logprint.success.assert_has_calls([ mock.call('Loaded plugin "plugin1"'), mock.call('Loaded plugin "plugin2"') ], any_order=False)
def configureServer(test=False, plugins=None, curConfig=None): """ Function to setup the cherrypy server. It configures it, but does not actually start it. :param test: Set to True when running in the tests. :type test: bool :param plugins: If you wish to start the server with a custom set of plugins, pass this as a list of plugins to load. Otherwise, will use the PLUGINS_ENABLED setting value from the db. :param curConfig: The configuration dictionary to update. """ if curConfig is None: curConfig = config.getConfig() appconf = { '/': { 'request.dispatch': cherrypy.dispatch.MethodDispatcher(), 'request.show_tracebacks': test, 'request.methods_with_bodies': ('POST', 'PUT', 'PATCH'), 'response.headers.server': 'Girder %s' % __version__, 'error_page.default': _errorDefault } } # Add MIME types for serving Fontello files from staticdir; # these may be missing or incorrect in the OS mimetypes.add_type('application/vnd.ms-fontobject', '.eot') mimetypes.add_type('application/x-font-ttf', '.ttf') mimetypes.add_type('application/font-woff', '.woff') curConfig.update(appconf) if test: # Force some config params in testing mode curConfig.update({'server': { 'mode': 'testing', 'api_root': 'api/v1', 'static_root': 'static', 'api_static_root': '../static', 'cherrypy_server': True }}) mode = curConfig['server']['mode'].lower() logprint.info('Running in mode: ' + mode) cherrypy.config['engine.autoreload.on'] = mode == 'development' _setupCache() # Don't import this until after the configs have been read; some module # initialization code requires the configuration to be set up. from girder.api import api_main root = webroot.Webroot() api_main.addApiToNode(root) girder.events.setupDaemon() cherrypy.engine.subscribe('start', girder.events.daemon.start) cherrypy.engine.subscribe('stop', girder.events.daemon.stop) if plugins is None: plugins = getPlugins() routeTable = loadRouteTable() info = { 'config': appconf, 'serverRoot': root, 'serverRootPath': routeTable[constants.GIRDER_ROUTE_ID], 'apiRoot': root.api.v1, 'staticRoot': routeTable[constants.GIRDER_STATIC_ROUTE_ID] } plugin._loadPlugins(plugins, info) root, appconf = info['serverRoot'], info['config'] return root, appconf
def testLoadMissingDependency(logprint): plugin._loadPlugins(['missing'], {}) logprint.error.assert_called_once_with('Plugin missing is not installed')
def configureServer(mode=None, plugins=None, curConfig=None): """ Function to setup the cherrypy server. It configures it, but does not actually start it. :param mode: The server mode to start in. :type mode: string :param plugins: If you wish to start the server with a custom set of plugins, pass this as a list of plugins to load. Otherwise, all installed plugins will be loaded. :param curConfig: The configuration dictionary to update. """ if curConfig is None: curConfig = config.getConfig() appconf = { '/': { 'request.dispatch': cherrypy.dispatch.MethodDispatcher(), 'request.show_tracebacks': mode == ServerMode.TESTING, 'request.methods_with_bodies': ('POST', 'PUT', 'PATCH'), 'response.headers.server': 'Girder %s' % __version__, 'error_page.default': _errorDefault } } # Add MIME types for serving Fontello files from staticdir; # these may be missing or incorrect in the OS mimetypes.add_type('application/vnd.ms-fontobject', '.eot') mimetypes.add_type('application/x-font-ttf', '.ttf') mimetypes.add_type('application/font-woff', '.woff') curConfig.update(appconf) if mode: curConfig['server']['mode'] = mode logprint.info('Running in mode: ' + curConfig['server']['mode']) cherrypy.config['engine.autoreload.on'] = mode == ServerMode.DEVELOPMENT _setupCache() # Don't import this until after the configs have been read; some module # initialization code requires the configuration to be set up. from girder.api import api_main root = webroot.Webroot() api_main.addApiToNode(root) girder.events.setupDaemon() cherrypy.engine.subscribe('start', girder.events.daemon.start) cherrypy.engine.subscribe('stop', girder.events.daemon.stop) routeTable = loadRouteTable() info = { 'config': appconf, 'serverRoot': root, 'serverRootPath': routeTable[constants.GIRDER_ROUTE_ID], 'apiRoot': root.api.v1, } plugin._loadPlugins(info, plugins) root, appconf = info['serverRoot'], info['config'] return root, appconf