def test_deferred_action_times_out(sql_alchemy_fixture, deferred_action_fixture): """If all its Requirements are not fulfilled before its deadline has been reached, a DeferredAction executes its deadline action; then, it and its Requirements are deleted""" fixture = deferred_action_fixture with sql_alchemy_fixture.persistent_test_classes(fixture.MyDeferredAction, fixture.SomeObject): requirements = [Requirement(), Requirement(), Requirement()] deferred_action = fixture.MyDeferredAction(fixture.one_object, requirements=requirements, deadline=fixture.future_time) Session.add(deferred_action) Session.flush() assert deferred_action.deadline == fixture.future_time ReahlEgg.do_daily_maintenance_for_egg('reahl-domain') assert not fixture.one_object.deadline_flag assert not fixture.another_object.deadline_flag assert Session.query(Requirement).count() == 3 assert Session.query(DeferredAction).count() == 1 deferred_action.deadline = fixture.past_time ReahlEgg.do_daily_maintenance_for_egg('reahl-domain') assert fixture.one_object.deadline_flag assert not fixture.another_object.deadline_flag assert Session.query(Requirement).count() == 0 assert Session.query(DeferredAction).count() == 0
def test_expire_stale_requests(reahl_system_fixture, party_account_fixture): fixture = party_account_fixture old_email = '*****@*****.**' recent_email = '*****@*****.**' password = '******' mailer_stub = fixture.mailer EmailAndPasswordSystemAccount.mailer = mailer_stub longago = datetime.now() - timedelta( reahl_system_fixture.config.accounts.request_verification_timeout) old_account_management_interface = AccountManagementInterface() old_account_management_interface.email = old_email old_account_management_interface.password = password old_account_management_interface.register() old_system_account = EmailAndPasswordSystemAccount.by_email(old_email) old_activation_request = Session.query(VerifyEmailRequest).one() old_activation_request.deferred_actions[0].deadline = longago new_account_management_interface = AccountManagementInterface() new_account_management_interface.email = recent_email new_account_management_interface.password = password new_account_management_interface.register() recent_system_account = EmailAndPasswordSystemAccount.by_email( recent_email) ReahlEgg.do_daily_maintenance_for_egg('reahl-domain') assert Session.query(EmailAndPasswordSystemAccount).filter_by( id=old_system_account.id).count() == 0 assert Session.query(EmailAndPasswordSystemAccount).filter_by( id=recent_system_account.id).count() == 1
def create_db_tables(self): """Creates the underlying database schema.""" eggs_in_order = ReahlEgg.get_all_relevant_interfaces( self.config.reahlsystem.root_egg) with self.orm_control.managed_transaction() as transaction: return self.orm_control.create_db_tables(transaction, eggs_in_order)
def test_flattened_tree_of_eggs(): """A Reahl application consists of a root egg and all its egg dependencies - with all such components often regarded in flattened order of dependence.""" easter_egg.clear() easter_egg.add_dependency('reahl-component') # All eggs for a root egg can be found in dependency order components_in_order = ReahlEgg.compute_ordered_dependent_distributions( easter_egg.as_requirement_string()) component_names_in_order = [i.project_name for i in components_in_order] # (many valid topological sorts are possible and the algorithm is nondeterministic in some aspects that # do not matter, hence many possible valid orderings are possible for this dependency tree) # We assert here only what matters, else this test becomes a flipper: def is_ordered_before(higher, lower): return component_names_in_order.index( higher) < component_names_in_order.index(lower) assert component_names_in_order[:2] == [ easter_egg.project_name, 'reahl-component' ] for package_name in component_names_in_order: dependencies = [ i.project_name for i in pkg_resources.require(package_name) if i.project_name != package_name ] assert all([is_ordered_before(package_name, i) for i in dependencies])
def list_all(self): all_items = [] all_items.extend(self.list_required(ReahlSystemConfig)) eggs = ReahlEgg.get_all_relevant_interfaces(self.reahlsystem.root_egg) for egg in reversed(eggs): all_items.extend(egg.list_config(self)) return all_items
def test_interface_with_meta_info(): """A Reahl component can publish a ReahlEgg instance to supply extra meta information about itself. Such interfaces with extra information are also often used from a flattened list in dependency order.""" easter_egg.clear() easter_egg.add_dependency('reahl-component') # The interface for a component is published via the reahl.eggs entry point line = 'Egg = reahl.component.eggs:ReahlEgg' easter_egg.add_entry_point_from_line('reahl.eggs', line) # Interfaces can be queried in dependency order too interfaces_in_order = ReahlEgg.compute_all_relevant_interfaces(easter_egg.as_requirement_string()) assert len(interfaces_in_order) == 2 # That of reahl-component itself, and of the easteregg [interface] = [i for i in interfaces_in_order if i.distribution is easter_egg] # The meta-info that can be obtained via such an interface assert interface.configuration_spec is None assert interface.get_persisted_classes_in_order() == [] assert interface.migrations_in_order == [] # Hooks for allowing a component to do its own housekeeping with expected(NoException): interface.do_daily_maintenance()
def instrument_classes_for(self, root_egg): all_classes = [] for i in ReahlEgg.get_all_relevant_interfaces(root_egg): all_classes.extend(i.get_persisted_classes_in_order() ) # So that they get imported declarative_classes = [i for i in all_classes if issubclass(i, Base)] self.instrument_declarative_classes(declarative_classes)
def execute(self, args): egg = ReahlEgg(get_distribution(args.component_name)) print('Name: %s' % egg.name) print('Version: %s' % egg.version) configuration_class = egg.configuration_spec if configuration_class: self.print_configuration_info(configuration_class) if egg.translation_package: self.print_locale_info(egg)
def test_deferred_action_times_out_with_shared_requirements( sql_alchemy_fixture, deferred_action_fixture): """If a DeferredAction times out, it will not nuke Requirements shared with another DeferredAction.""" fixture = deferred_action_fixture with sql_alchemy_fixture.persistent_test_classes(fixture.MyDeferredAction, fixture.SomeObject): requirements1 = [Requirement()] requirements2 = [Requirement(), Requirement()] deferred_action1 = fixture.MyDeferredAction( fixture.one_object, requirements=requirements2, deadline=fixture.future_time) Session.add(deferred_action1) deferred_action2 = fixture.MyDeferredAction( fixture.another_object, requirements=requirements1 + requirements2, deadline=fixture.future_time) Session.add(deferred_action2) Session.flush() # If one DeferredAction times out, the remaining one and its Requirements are left intact deferred_action1.deadline = fixture.past_time ReahlEgg.do_daily_maintenance_for_egg('reahl-domain') assert fixture.one_object.deadline_flag assert not fixture.another_object.deadline_flag assert Session.query(Requirement).count() == 3 assert Session.query(DeferredAction).count() == 1 for requirement in requirements1 + requirements2: assert set(requirement.deferred_actions) == {deferred_action2} # When no more DeferredActions are held onto by Requirements, those Requirements are deleted deferred_action2.deadline = fixture.past_time ReahlEgg.do_daily_maintenance_for_egg('reahl-domain') assert fixture.one_object.deadline_flag assert fixture.another_object.deadline_flag assert Session.query(Requirement).count() == 0 assert Session.query(DeferredAction).count() == 0
def execute(self, args): super().execute(args) self.context.install() distributions = ReahlEgg.compute_ordered_dependent_distributions(self.config.reahlsystem.root_egg) for distribution in distributions: deps = '' if args.verbose: deps = '[%s]' % (' | '.join([str(i) for i in distribution.requires()])) print('%s %s' % (distribution, deps)) return 0
def execute(self, options, args): super(ListDependencies, self).execute(options, args) with self.context: distributions = ReahlEgg.compute_ordered_dependent_distributions( self.config.reahlsystem.root_egg) for distribution in distributions: deps = '' if options.verbose: deps = '[%s]' % (' | '.join( [six.text_type(i) for i in distribution.requires()])) print('%s %s' % (distribution, deps)) return 0
def get_interface_locale(self): context = ExecutionContext.get_context() if not hasattr(context, 'request'): return 'en_gb' url = Url.get_current_url() possible_locale, path = url.get_locale_split_path() supported_locales = ReahlEgg.get_languages_supported_by_all(context.config.reahlsystem.root_egg) if possible_locale: if possible_locale in supported_locales: return possible_locale return context.config.web.default_url_locale
def with_languages(self): """Populates this Menu with a MenuItem for each available language. Answers the same Menu. .. versionadded:: 3.2 """ context = ExecutionContext.get_context() supported_locales = ReahlEgg.get_languages_supported_by_all( context.config.reahlsystem.root_egg) for locale in supported_locales: try: language_name = Locale.parse(locale).display_name except UnknownLocaleError: language_name = locale bookmark = self.view.as_bookmark(description=language_name, locale=locale) bookmark.exact = True self.add_bookmark(bookmark) return self
def flattened_tree_of_eggs(self, fixture): """A Reahl application consists of a root egg and all its egg dependencies - with all such components often regarded in flattened order of dependence.""" easter_egg.clear() easter_egg.add_dependency('reahl-component') # All eggs for a root egg can be found in dependency order components_in_order = ReahlEgg.compute_ordered_dependent_distributions( easter_egg.as_requirement_string()) component_names_in_order = [ i.project_name for i in components_in_order ] # (many valid topological sorts are possible and the algorithm is nondeterministic in some aspects that # do not matter, hence many possible valid orderings are possible for this dependency tree) # We assert here only what matters, else this test becomes a flipper: def is_ordered_before(higher, lower): return component_names_in_order.index( higher) < component_names_in_order.index(lower) vassert(component_names_in_order[:2] == [easter_egg.project_name, 'reahl-component']) vassert(is_ordered_before('Babel', 'pytz')) vassert(is_ordered_before('python-dateutil', 'six'))
def migrate_db(self): eggs_in_order = ReahlEgg.get_all_relevant_interfaces(self.config.reahlsystem.root_egg) self.orm_control.migrate_db(eggs_in_order) return 0
def validate_components(self): eggs = ReahlEgg.get_all_relevant_interfaces(self.reahlsystem.root_egg) for egg in reversed(eggs): logging.getLogger(__name__).debug('going to validate config for %s' % egg) egg.validate_config(self)
def do_daily_maintenance(self): with self.orm_control.managed_transaction() as transaction: ReahlEgg.do_daily_maintenance_for_egg(self.config.reahlsystem.root_egg)
def create_db_tables(self): eggs_in_order = ReahlEgg.get_all_relevant_interfaces(self.config.reahlsystem.root_egg) with self.orm_control.managed_transaction() as transaction: return self.orm_control.create_db_tables(transaction, eggs_in_order)
def do_daily_maintenance(self): """Runs the all the scheduled jobs relevant to the current system.""" with self.orm_control.managed_transaction() as transaction: ReahlEgg.do_daily_maintenance_for_egg( self.config.reahlsystem.root_egg)
def migrate_db(self): """Runs the database migrations relevant to the current system.""" eggs_in_order = ReahlEgg.get_all_relevant_interfaces( self.config.reahlsystem.root_egg) self.orm_control.migrate_db(eggs_in_order) return 0
def set_up_easter_egg(self): self.config_bootstrap_file easter_egg.clear() ReahlEgg.clear_cache()
def migrate_db(self, explain=False): """Runs the database migrations relevant to the current system.""" self.orm_control.migrate_db(ReahlEgg.interface_for( get_distribution(self.config.reahlsystem.root_egg)), explain=explain) return 0