def get_test_labels(cls, tests): """Get a list of app labels and possibly tests for the db app optimizer This should be called after `loadTestsFromNames` has been called. """ test_apps = set(app.name for app in apps.get_app_configs() if app.name not in settings.APPS_TO_EXCLUDE_FROM_TESTS and not app.name.startswith('django.')) if not cls.user_specified_test_names: return [AppConfig.create(app).label for app in test_apps] def iter_names(test): # a.b.c -> a.b.c, a.b, a if isinstance(test.context, type): name = test.context.__module__ elif isinstance(test.context, types.ModuleType): name = test.context.__name__ else: raise RuntimeError("unknown test type: {!r}".format(test)) parts = name.split(".") num_parts = len(parts) for i in range(num_parts): yield ".".join(parts[:num_parts - i]) labels = set() for test in tests: for name in iter_names(test): if name in test_apps: labels.add((AppConfig.create(name).label, test.context)) break return list(labels)
def load_helpers(): """Try to import ``helpers.py`` from each app in INSTALLED_APPS.""" # We want to wait as long as possible to load helpers so there aren't any # weird circular imports with jingo. global _helpers_loaded if _helpers_loaded: return _helpers_loaded = True from jingo import helpers # noqa for app in settings.INSTALLED_APPS: try: app_path = import_module(app).__path__ except ImportError: # Django 1.7 allows for speciying a path to an AppConfig class if django.VERSION[:2] >= (1, 7): from django.apps import AppConfig app_config = AppConfig.create(app) app_path = app_config.name except AttributeError: continue try: imp.find_module('helpers', app_path) except ImportError: continue import_module('%s.helpers' % app)
def test_get_tests(self): "Check that the get_tests helper function can find tests in a directory" from django.apps import AppConfig from django.test.simple import get_tests app_config = AppConfig.create('test_runner.valid_app') app_config.import_models({}) tests = get_tests(app_config) self.assertIsInstance(tests, types.ModuleType)
def test_import_error(self): "Test for #12658 - Tests with ImportError's shouldn't fail silently" from django.apps import AppConfig from django.test.simple import get_tests app_config = AppConfig.create('test_runner_invalid_app') app_config.import_models({}) with self.assertRaises(ImportError): get_tests(app_config)
def test_overriding_view_is_possible_without_overriding_app(self): # If test fails, it's helpful to know if it's caused by order of # execution customer_app_config = AppConfig.create('oscar.apps.customer') customer_app_config.ready() self.assertEqual(customer_app_config.summary_view.__module__, 'tests._site.apps.customer.views') self.assertEqual(apps.get_app_config('customer').summary_view.__module__, 'tests._site.apps.customer.views')
def app_labels(apps_list): """ Returns a list of app labels of the given apps_list, now properly handles new Django 1.7+ application registry. https://docs.djangoproject.com/en/1.8/ref/applications/#django.apps.AppConfig.label """ if AppConfig is None: return [app.split('.')[-1] for app in apps_list] return [AppConfig.create(app).label for app in apps_list]
def test_overriding_view_is_possible_without_overriding_app(self): # If test fails, it's helpful to know if it's caused by order of # execution customer_app_config = AppConfig.create('oscar.apps.customer') customer_app_config.ready() self.assertEqual(customer_app_config.summary_view.__module__, 'tests._site.apps.customer.views') self.assertEqual( apps.get_app_config('customer').summary_view.__module__, 'tests._site.apps.customer.views')
def setup_test_app(package, label=None): """ Setup a Django test app for the provided package to allow test-only models to be used. This function should be called from myapp.tests.__init__ like so: setup_test_app(__package__) Or, if a specific app label is required, like so: setup_test_app(__package__, 'mytests') Models defined within the package also require their app labels manually set to match, e.g.: class MyTestModel(models.Model): # ... class Meta: app_label = 'mytests' """ # # if label is None: containing_app_config = apps.get_containing_app_config(package) label = containing_app_config.label # Only suffix the app label if it has not been already. This allows # duplicate entries to be detected and prevented. It may prevent the # use of an implicit label if the tests reside in an app that # legitimately ends with "_tests", but an explicit label can always be # used. Without this check, earlier entries are returned by # get_containing_app_config() and suffixed repeatedly. if not containing_app_config.label.endswith('_tests'): label = '{}_tests'.format(containing_app_config.label) if label in apps.app_configs: # An app with this label already exists, skip adding it. This is # necessary (vs raising an exception) as there are certain conditions # that can cause this function to be run multiple times (e.g. errors # during Django's initialisation can cause this). return app_config = AppConfig.create(package) app_config.apps = apps app_config.label = label apps.app_configs[label] = app_config app_config.import_models() apps.clear_cache()
def test_credentials_config_settings_failure(self): """Verify an exception is raised when required settings are missing.""" app_config = AppConfig.create("credentials.apps.credentials") setting_attribute = "CREDENTIALS_SERVICE_USER" expected_error_msg = f"The settings {setting_attribute} must be set in order to start the application!" delattr(settings, setting_attribute) with LogCapture(LOGGER_NAME) as log: with self.assertRaises(AttributeError): app_config.ready() log.check((LOGGER_NAME, "CRITICAL", expected_error_msg))
def get_env(): """Configure and return a jinja2 Environment.""" # Mimic Django's setup by loading templates from directories in # TEMPLATE_DIRS and packages in INSTALLED_APPS. x = ((jinja2.FileSystemLoader, settings.TEMPLATE_DIRS), (jinja2.PackageLoader, settings.INSTALLED_APPS)) loaders = [] for loader, places in x: for p in places: try: loader(p) except ImportError: # Django 1.7 allows for speciying a path to an AppConfig class if django.VERSION[:2] >= (1, 7): from django.apps import AppConfig app_config = AppConfig.create(p) p = app_config.name finally: loaders.append(loader(p)) opts = { 'trim_blocks': True, 'extensions': ['jinja2.ext.i18n'], 'autoescape': True, 'auto_reload': settings.DEBUG, 'loader': jinja2.ChoiceLoader(loaders), } if hasattr(settings, 'JINJA_CONFIG'): if hasattr(settings.JINJA_CONFIG, '__call__'): config = settings.JINJA_CONFIG() else: config = settings.JINJA_CONFIG opts.update(config) e = Environment(**opts) # Install null translations since gettext isn't always loaded up during # testing. if ('jinja2.ext.i18n' in e.extensions or 'jinja2.ext.InternationalizationExtension' in e.extensions): e.install_null_translations() return e
def _apply_base_settings(plugin_instance, settings_module): # Instead of just adding the module path to the settings # we instantiate an app config object for the plugin # and explicitly set its label to its module path. # This way, there is no way for a plugin to collide in its # label in the Django App Registry with kolibri core apps # or Kolibri core plugins. app_config = AppConfig.create(plugin_instance.module_path) app_config.label = plugin_instance.module_path # Register the plugin as an installed app _set_setting_value("INSTALLED_APPS", (app_config, ), settings_module) # Add in the external plugins' locale paths. Our frontend messages depends # specifically on the value of LOCALE_PATHS to find its catalog files. if i18n.is_external_plugin(plugin_instance.module_path): _set_setting_value( "LOCALE_PATHS", (i18n.get_installed_app_locale_path( plugin_instance.module_path), ), settings_module, )
def setup(verbosity, test_labels): state = { 'INSTALLED_APPS': settings.INSTALLED_APPS, 'ROOT_URLCONF': getattr(settings, "ROOT_URLCONF", ""), 'TEMPLATE_DIRS': settings.TEMPLATE_DIRS, 'LANGUAGE_CODE': settings.LANGUAGE_CODE, 'STATIC_URL': settings.STATIC_URL, 'STATIC_ROOT': settings.STATIC_ROOT, 'MIDDLEWARE_CLASSES': settings.MIDDLEWARE_CLASSES, } settings.INSTALLED_APPS = ALWAYS_INSTALLED_APPS settings.ROOT_URLCONF = 'denyzen.tests.urls' settings.STATIC_URL = '/static/' settings.STATIC_ROOT = os.path.join(TEMP_DIR, 'static') settings.TEMPLATE_DIRS = (os.path.join(RUNTESTS_DIR, TEST_TEMPLATE_DIR),) settings.LANGUAGE_CODE = 'en' settings.SITE_ID = 1 settings.MIDDLEWARE_CLASSES = ALWAYS_MIDDLEWARE_CLASSES # Ensure the middleware classes are seen as overridden otherwise we get a compatibility warning. #settings._explicit_settings.add('MIDDLEWARE_CLASSES') settings.MIGRATION_MODULES = { # these 'tests.migrations' modules don't actually exist, but this lets # us skip creating migrations for the test models. 'auth': 'django.contrib.auth.tests.migrations', 'contenttypes': 'django.contrib.contenttypes.tests.migrations', } # Load all the ALWAYS_INSTALLED_APPS. django.setup() if verbosity > 0: # Ensure any warnings captured to logging are piped through a verbose # logging handler. If any -W options were passed explicitly on command # line, warnings are not captured, and this has no effect. logger = logging.getLogger('py.warnings') handler = logging.StreamHandler() logger.addHandler(handler) # Load all the test model apps. test_modules = get_test_modules() print(test_modules) test_labels_set = set() for label in test_labels: test_labels_set.add(label) installed_app_names = set(get_installed()) for modpath, module_name in test_modules: if modpath: module_label = '.'.join([modpath, module_name]) else: module_label = module_name # if the module (or an ancestor) was named on the command line, or # no modules were named (i.e., run all), import # this module and add it to INSTALLED_APPS. if not test_labels: module_found_in_labels = True else: module_found_in_labels = any( # exact match or ancestor match module_label == label or module_label.startswith(label + '.') for label in test_labels_set) if module_found_in_labels and module_label not in installed_app_names: if verbosity >= 2: print("Importing application %s" % module_name) settings.INSTALLED_APPS.append(module_label) app_config = AppConfig.create(module_name) apps.app_configs[app_config.label] = app_config app_config.import_models(apps.all_models[app_config.label]) apps.clear_cache() apps.set_installed_apps(settings.INSTALLED_APPS) return state
url(r'^$', never_cache( RedirectView.as_view(url=reverse_lazy('webindex_custom'), permanent=True)), name="index"), ] # url patterns urlpatterns = [] for app in settings.ADDITIONAL_APPS: if isinstance(app, AppConfig): app_config = app else: app_config = AppConfig.create(app) label = app_config.label # Depending on how we added the app to INSTALLED_APPS in settings.py, # include the urls the same way if 'omeroweb.%s' % app in settings.INSTALLED_APPS: urlmodule = 'omeroweb.%s.urls' % app else: urlmodule = '%s.urls' % app # Try to import module.urls.py if it exists (not for corsheaders etc) urls_found = pkgutil.find_loader(urlmodule) if urls_found is not None: try: __import__(urlmodule) # https://stackoverflow.com/questions/7580220/django-urls-how-to-map-root-to-app
def setup(verbosity, test_labels): import django from django.apps import apps, AppConfig from django.conf import settings from django.test import TransactionTestCase, TestCase print("Testing against Django installed in '%s'" % os.path.dirname(django.__file__)) # Force declaring available_apps in TransactionTestCase for faster tests. def no_available_apps(self): raise Exception("Please define available_apps in TransactionTestCase " "and its subclasses.") TransactionTestCase.available_apps = property(no_available_apps) TestCase.available_apps = None state = { 'INSTALLED_APPS': settings.INSTALLED_APPS, 'ROOT_URLCONF': getattr(settings, "ROOT_URLCONF", ""), 'TEMPLATE_DIRS': settings.TEMPLATE_DIRS, 'LANGUAGE_CODE': settings.LANGUAGE_CODE, 'STATIC_URL': settings.STATIC_URL, 'STATIC_ROOT': settings.STATIC_ROOT, } # Redirect some settings for the duration of these tests. settings.INSTALLED_APPS = ALWAYS_INSTALLED_APPS settings.ROOT_URLCONF = 'urls' settings.STATIC_URL = '/static/' settings.STATIC_ROOT = os.path.join(TEMP_DIR, 'static') settings.TEMPLATE_DIRS = (os.path.join(RUNTESTS_DIR, TEST_TEMPLATE_DIR),) settings.LANGUAGE_CODE = 'en' settings.SITE_ID = 1 if verbosity > 0: # Ensure any warnings captured to logging are piped through a verbose # logging handler. If any -W options were passed explicitly on command # line, warnings are not captured, and this has no effect. logger = logging.getLogger('py.warnings') handler = logging.StreamHandler() logger.addHandler(handler) # Load all the ALWAYS_INSTALLED_APPS. with warnings.catch_warnings(): warnings.filterwarnings('ignore', 'django.contrib.comments is deprecated and will be removed before Django 1.8.', DeprecationWarning) apps.populate_models() # Load all the test model apps. test_modules = get_test_modules() # Reduce given test labels to just the app module path test_labels_set = set() for label in test_labels: bits = label.split('.') if bits[:2] == ['django', 'contrib']: bits = bits[:3] else: bits = bits[:1] test_labels_set.add('.'.join(bits)) for modpath, module_name in test_modules: if modpath: module_label = '.'.join([modpath, module_name]) else: module_label = module_name # if the module (or an ancestor) was named on the command line, or # no modules were named (i.e., run all), import # this module and add it to INSTALLED_APPS. if not test_labels: module_found_in_labels = True else: match = lambda label: ( module_label == label or # exact match module_label.startswith(label + '.') # ancestor match ) module_found_in_labels = any(match(l) for l in test_labels_set) if module_found_in_labels: if verbosity >= 2: print("Importing application %s" % module_name) # HACK. if module_label not in settings.INSTALLED_APPS: settings.INSTALLED_APPS.append(module_label) app_config = AppConfig.create(module_label) app_config.import_models(apps.all_models[app_config.label]) apps.app_configs[app_config.label] = app_config apps.get_models.cache_clear() return state
def _strip(self, entry): app_config = AppConfig.create(entry) return app_config.label
def setup(verbosity, test_labels): from django.apps import apps, AppConfig from django.conf import settings from django.test import TransactionTestCase, TestCase print("Testing against Django installed in '%s'" % os.path.dirname(django.__file__)) # Force declaring available_apps in TransactionTestCase for faster tests. def no_available_apps(self): raise Exception("Please define available_apps in TransactionTestCase " "and its subclasses.") TransactionTestCase.available_apps = property(no_available_apps) TestCase.available_apps = None state = { 'INSTALLED_APPS': settings.INSTALLED_APPS, 'ROOT_URLCONF': getattr(settings, "ROOT_URLCONF", ""), 'TEMPLATE_DIRS': settings.TEMPLATE_DIRS, 'LANGUAGE_CODE': settings.LANGUAGE_CODE, 'STATIC_URL': settings.STATIC_URL, 'STATIC_ROOT': settings.STATIC_ROOT, } # Redirect some settings for the duration of these tests. settings.INSTALLED_APPS = ALWAYS_INSTALLED_APPS settings.ROOT_URLCONF = 'urls' settings.STATIC_URL = '/static/' settings.STATIC_ROOT = os.path.join(TEMP_DIR, 'static') settings.TEMPLATE_DIRS = (os.path.join(RUNTESTS_DIR, TEST_TEMPLATE_DIR),) settings.LANGUAGE_CODE = 'en' settings.SITE_ID = 1 if verbosity > 0: # Ensure any warnings captured to logging are piped through a verbose # logging handler. If any -W options were passed explicitly on command # line, warnings are not captured, and this has no effect. logger = logging.getLogger('py.warnings') handler = logging.StreamHandler() logger.addHandler(handler) # Load all the ALWAYS_INSTALLED_APPS. django.setup() # Load all the test model apps. test_modules = get_test_modules() # Reduce given test labels to just the app module path test_labels_set = set() for label in test_labels: bits = label.split('.') if bits[:2] == ['django', 'contrib']: bits = bits[:3] else: bits = bits[:1] test_labels_set.add('.'.join(bits)) for modpath, module_name in test_modules: if modpath: module_label = '.'.join([modpath, module_name]) else: module_label = module_name # if the module (or an ancestor) was named on the command line, or # no modules were named (i.e., run all), import # this module and add it to INSTALLED_APPS. if not test_labels: module_found_in_labels = True else: module_found_in_labels = any( # exact match or ancestor match module_label == label or module_label.startswith(label + '.') for label in test_labels_set) installed_app_names = set(get_installed()) if module_found_in_labels and module_label not in installed_app_names: if verbosity >= 2: print("Importing application %s" % module_name) # HACK. settings.INSTALLED_APPS.append(module_label) app_config = AppConfig.create(module_label) apps.app_configs[app_config.label] = app_config app_config.import_models(apps.all_models[app_config.label]) apps.clear_cache() return state
def get_first_party_app_labels(): if not settings.is_overridden("FIRST_PARTY_APPS"): return None return {AppConfig.create(name).label for name in settings.FIRST_PARTY_APPS}
def test_default_config_exists(): """ A really trivial "test case": just checking that the app can be instantiated. """ app = AppConfig.create("morphodict.apps.MorphodictConfig") assert "morphodict" in app.name
def setUp(self): super(CredentialsConfigTests, self).setUp() self.app_config = AppConfig.create('credentials.apps.credentials')
urlpatterns += redirect_urlpatterns() def remove_prefix(appname, prefix="omero_"): if appname.startswith(prefix): return appname[len(prefix):] return appname for app in settings.ADDITIONAL_APPS: if django.VERSION > (1, 7): from django.apps import AppConfig if isinstance(app, AppConfig): app_config = app else: app_config = AppConfig.create(app) label = app_config.label else: logger.warn( ("Django %s does not support AppConfig. Some OMERO.web plugins " "may not work correctly.") % django.get_version()) label = remove_prefix(app) # Depending on how we added the app to INSTALLED_APPS in settings.py, # include the urls the same way if 'omeroweb.%s' % app in settings.INSTALLED_APPS: urlmodule = 'omeroweb.%s.urls' % app else: urlmodule = '%s.urls' % app try: __import__(urlmodule) except ImportError:
def populate(self, installed_apps=None): """ Load application configurations and models. Import each application module and then each model module. It is thread-safe and idempotent, but not reentrant. """ if self.ready: return # populate() might be called by two threads in parallel on servers # that create threads before initializing the WSGI callable. with self._lock: if self.ready: return # An RLock prevents other threads from entering this section. The # compare and set operation below is atomic. if self.loading: # Prevent reentrant calls to avoid running AppConfig.ready() # methods twice. raise RuntimeError("populate() isn't reentrant") self.loading = True # Phase 1: initialize app configs and import app modules. for entry in installed_apps: if isinstance(entry, AppConfig): app_config = entry else: app_config = AppConfig.create(entry) if app_config.label in self.app_configs: raise ImproperlyConfigured( "Application labels aren't unique, " "duplicates: %s" % app_config.label) self.app_configs[app_config.label] = app_config app_config.apps = self # Check for duplicate app names. counts = Counter( app_config.name for app_config in self.app_configs.values()) duplicates = [ name for name, count in counts.most_common() if count > 1] if duplicates: raise ImproperlyConfigured( "Application names aren't unique, " "duplicates: %s" % ", ".join(duplicates)) self.apps_ready = True # Phase 2: import models modules. for app_config in self.app_configs.values(): app_config.import_models() self.clear_cache() self.models_ready = True # Phase 3: run ready() methods of app configs. for app_config in self.get_app_configs(): app_config.ready() self.ready = True self.ready_event.set()