diff --git a/bt5/erp5_upgrader/PathTemplateItem/portal_alarms/promise_check_upgrade.xml b/bt5/erp5_upgrader/PathTemplateItem/portal_alarms/promise_check_upgrade.xml index 5ae99f570858c8f3a15326ea6669108f383bcfaf..665ad12b03907fc9e616198832dd09264716dde6 100644 --- a/bt5/erp5_upgrader/PathTemplateItem/portal_alarms/promise_check_upgrade.xml +++ b/bt5/erp5_upgrader/PathTemplateItem/portal_alarms/promise_check_upgrade.xml @@ -24,16 +24,13 @@ </item> <item> <key> <string>description</string> </key> - <value> <string>This alarm checks that the upgrader is required. If yes, the upgrader have three steps:\n + <value> <string>This alarms controls the upgrade process by calling others upgrader alarms.\n \n -1. Pre-upgrade\n -This step will run all constraints that have contraint_type equal pre_upgrade.\n +It delegates sense to calling fix on "Run Pre Upgrade" then "Run Upgrade" alarms an aggregating the results.\n \n -2. Upgrader\n -This step will run all constraints that have contraint_type equal upgrade. In this step is supposed to install/upgrade all Business Template required.\n +It delegate fix to calling fix on "Run Pre Upgrade" then "Run Upgrade" then "Run Post Upgrade" alarms then aggregating the results.\n \n -3. Post-Upgrade\n -This step will run all constraints that have contraint_type equal post_upgrade.</string> </value> +Note that post upgrade steps are not executed in the sense, because they require the upgrade step to be actually executed.</string> </value> </item> <item> <key> <string>enabled</string> </key> diff --git a/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Alarm_runFullUpgrader.py b/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Alarm_runFullUpgrader.py index 4da1ee22ddb5f3e0a8912ca70b60be3a419246cd..b94705f4340c92429d8b7adacf1cc0d80b21cec1 100644 --- a/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Alarm_runFullUpgrader.py +++ b/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Alarm_runFullUpgrader.py @@ -12,27 +12,42 @@ pre_upgrade_tag = '%s-preupgrade' % tag upgrade_tag = '%s-upgrade' % tag post_upgrade_tag = '%s-postupgrade' % tag -portal_alarms.upgrader_check_pre_upgrade.activate( - activity='SQLQueue', - tag=pre_upgrade_tag, -).activeSense(fixit=fixit, params={'tag': pre_upgrade_tag}) +active_process = context.newActiveProcess() -portal_alarms.upgrader_check_upgrader.activate( - activity='SQLQueue', - tag=upgrade_tag, - after_tag=pre_upgrade_tag, - ).activeSense(fixit=fixit, params={'tag': upgrade_tag}) -portal_alarms.upgrader_check_post_upgrade.activate( - activity='SQLQueue', - tag=post_upgrade_tag, - after_tag=upgrade_tag, -).activeSense(fixit=fixit, params={'tag': post_upgrade_tag}) +portal_alarms.upgrader_check_pre_upgrade.activeSense( + fixit=fixit, + activate_kw={ + 'activity': 'SQLQueue', + 'tag': pre_upgrade_tag, + }, + params={'tag': pre_upgrade_tag}, +) + +portal_alarms.upgrader_check_upgrader.activeSense( + fixit=fixit, + activate_kw={ + 'activity': 'SQLQueue', + 'tag': upgrade_tag, + 'after_tag': pre_upgrade_tag, + }, + params={'tag': upgrade_tag}, +) + +if fixit: + portal_alarms.upgrader_check_post_upgrade.activeSense( + fixit=fixit, + activate_kw={ + 'activity': 'SQLQueue', + 'tag': post_upgrade_tag, + 'after_tag': upgrade_tag, + }, + params={'tag': post_upgrade_tag}, + ) # start another activity to collect the results from each upgrader step -active_process = context.newActiveProcess() -context.activate(after_tag=post_upgrade_tag).Alarm_postFullUpgradeNeed( +context.activate(after_tag=(upgrade_tag, post_upgrade_tag)).Alarm_postFullUpgradeNeed( active_process=active_process.getRelativeUrl()) # Nothing else to do, so we can disable. diff --git a/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Alarm_runPostUpgrade.py b/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Alarm_runPostUpgrade.py index c8635497985a90ec75941990f0d48c960376ca4b..7f1f1ef9ef169871cb234cdf1b16c1d7c34609f0 100644 --- a/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Alarm_runPostUpgrade.py +++ b/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Alarm_runPostUpgrade.py @@ -4,7 +4,7 @@ activate_kw = params or {} with context.defaultActivateParameterDict(activate_kw, placeless=True): - active_process = context.newActiveProcess() + active_process = context.newActiveProcess(activate_kw=activate_kw) context.ERP5Site_checkUpgraderConsistency(fixit=fixit, activate_kw=activate_kw, diff --git a/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Alarm_runPreUpgrade.py b/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Alarm_runPreUpgrade.py index 60568a92969faad752abd7033bc520fc2722f9dd..0d0e6181d058c106864c0b73eef928b2b7b58969 100644 --- a/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Alarm_runPreUpgrade.py +++ b/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Alarm_runPreUpgrade.py @@ -4,7 +4,7 @@ activate_kw = params or {} with context.defaultActivateParameterDict(activate_kw, placeless=True): - active_process = context.newActiveProcess() + active_process = context.newActiveProcess(activate_kw=activate_kw) context.ERP5Site_checkUpgraderConsistency(fixit=fixit, activate_kw=activate_kw, diff --git a/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Alarm_runUpgrader.py b/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Alarm_runUpgrader.py index 36d3d9ed0b15ec4beceaff8914eb16ea63f09102..8f5ca67b0fcaa356cf8f6c6efc84358188376749 100644 --- a/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Alarm_runUpgrader.py +++ b/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Alarm_runUpgrader.py @@ -17,7 +17,7 @@ if tool_portal_type in portal_type_list: activate_kw = params or {} with context.defaultActivateParameterDict(activate_kw, placeless=True): - active_process = context.newActiveProcess() + active_process = context.newActiveProcess(activate_kw=activate_kw) method_kw = {'fixit': fixit, 'filter': {"constraint_type": 'upgrader'}, diff --git a/bt5/erp5_upgrader/TestTemplateItem/portal_components/test.erp5.testUpgrader.py b/bt5/erp5_upgrader/TestTemplateItem/portal_components/test.erp5.testUpgrader.py index 099cf71af035e66a3cf49e3dc68af1abb81eca2b..b8b291495dd117f29e1106927578ac53d5369483 100644 --- a/bt5/erp5_upgrader/TestTemplateItem/portal_components/test.erp5.testUpgrader.py +++ b/bt5/erp5_upgrader/TestTemplateItem/portal_components/test.erp5.testUpgrader.py @@ -135,12 +135,19 @@ class TestUpgrader(ERP5TypeTestCase): id=script_constraint_id) script_constraint.edit(script_id=self.script_id, constraint_type="pre_upgrade") - def stepCreatePersonPropertySheet(self, sequence=None): + def _createPersonEmptyPropertySheet(self): portal = self.portal property_sheet = getattr(portal.portal_property_sheets, self.property_sheet_id, None) if property_sheet is None: property_sheet = portal.portal_property_sheets.newContent( portal_type="Property Sheet", id=self.property_sheet_id) + return property_sheet + + def stepCreatePersonEmptyPropertySheet(self, sequence=None): + self._createPersonEmptyPropertySheet() + + def stepCreatePersonPropertySheet(self, sequence=None): + property_sheet = self._createPersonEmptyPropertySheet() script_constraint_id = "person_old_reference_constraint" script_constraint = getattr(property_sheet, script_constraint_id, None) if script_constraint is None: @@ -306,6 +313,11 @@ class TestUpgrader(ERP5TypeTestCase): alarm_id="promise_check_upgrade") self.assertTrue(sense, detail_list) + def stepCheckFullUpgradeNotRequired(self, sequence=None): + sense, detail_list = self._checkAlarmSense( + alarm_id="promise_check_upgrade") + self.assertFalse(sense, detail_list) + def stepCheckPostUpgradeNotRequired(self, sequence=None): sense, detail_list = self._checkAlarmSense( alarm_id="upgrader_check_post_upgrade") @@ -743,3 +755,97 @@ class TestUpgrader(ERP5TypeTestCase): """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self) + + def test_sense_full_upgrade_do_not_sense_post_upgrade(self): + """ + Check that the post-upgrade consistency check is not run + when running the activeSense method of the full-upgrade alarm, + as post-upgrade will give inconsistent result + """ + sequence_list = SequenceList() + sequence_string = """ + stepRunUpgrader + stepTic + stepCreatePerson + stepValidatePerson + stepSetConstraintInPersonModulePortalType + stepTic + stepCheckFullUpgradeNotRequired + stepCheckPostUpgradeRequired + """ + sequence_list.addSequenceString(sequence_string) + sequence_list.play(self) + + def _setPersonTitleConstraintForUpgraderStep(self, step): + portal = self.portal + skin_folder = portal.portal_skins.custom + script_id = "Person_%s_setTitleConstraint" % step + custom_script = getattr(skin_folder, script_id, None) + if custom_script is None: + skin_folder.manage_addProduct['PythonScripts'].manage_addPythonScript(script_id) + custom_script = getattr(skin_folder, script_id) + custom_script.ZPythonScript_edit('fixit=False, **kw', + "{step_string}='M. {step_string}'\n" + "if context.getTitle() != {step_string}:\n" + " if fixit:\n" + " context.setTitle({step_string})\n" + " else:\n" + " return [\"Person's title is wrong\",]\n" + "return []".format(step_string=step) + ) + + property_sheet_id = self.property_sheet_id + property_sheet = getattr(portal.portal_property_sheets, property_sheet_id, None) + script_constraint_id = "person_title_%s_constraint" % step + script_constraint = getattr(property_sheet, script_constraint_id, None) + if script_constraint is None: + script_constraint = property_sheet.newContent( + portal_type="Script Constraint", + id=script_constraint_id + ) + script_constraint.edit( + script_id=script_id, + constraint_type="%s" % step) + + def stepSetPersonTitlePreUpgradeConstraint(self, sequence=None): + self._setPersonTitleConstraintForUpgraderStep('pre_upgrade') + + def stepSetPersonTitleUpgradeConstraint(self, sequence=None): + self._setPersonTitleConstraintForUpgraderStep('upgrader') + + def stepSetPersonTitlePostUpgradeConstraint(self, sequence=None): + self._setPersonTitleConstraintForUpgraderStep('post_upgrade') + + def stepCheckPersonTitleHasBeenSetByPersonTitlePostUpgradeConstraint(self, sequence=None): + person = sequence['person'] + title = person.getTitle() + self.assertEqual(title, 'M. post_upgrade') + + def stepCheckPersonTitleHistory(self, sequence=None): + person = sequence['person'] + self.assertEqual( + [x.changes for x in self.portal.person_module['1'].Base_getZODBHistoryList()[-3:]], + [('title:M. pre_upgrade',), ('title:M. upgrader',), ('title:M. post_upgrade',)]) + + def test_upgrade_activities_are_run_sequentially(self): + """ + Check that activities spawned by the upgrader are always run in the same + order : pre-upgrade, upgrade, post-upgrade + """ + sequence_list = SequenceList() + sequence_string = """ + stepCreatePerson + stepValidatePerson + stepCreatePersonEmptyPropertySheet + stepSetConstraintInPersonPortalType + stepSetPersonTitlePreUpgradeConstraint + stepSetPersonTitleUpgradeConstraint + stepSetPersonTitlePostUpgradeConstraint + stepTic + stepRunFullUpgrader + stepTic + stepCheckPersonTitleHasBeenSetByPersonTitlePostUpgradeConstraint + stepCheckPersonTitleHistory + """ + sequence_list.addSequenceString(sequence_string) + sequence_list.play(self) \ No newline at end of file diff --git a/product/ERP5/Document/Alarm.py b/product/ERP5/Document/Alarm.py index fc7bea9e8fe2a0d445b98dfb72c8002efe53ded5..045b8abe6c2e592ec964fabe6c261db1ec62abdd 100644 --- a/product/ERP5/Document/Alarm.py +++ b/product/ERP5/Document/Alarm.py @@ -103,7 +103,7 @@ class Alarm(XMLObject, PeriodicityMixin): return '%s_%s' % (self.getRelativeUrl(), id) security.declareProtected(Permissions.AccessContentsInformation, 'activeSense') - def activeSense(self, fixit=0, params=None): + def activeSense(self, fixit=0, activate_kw=(), params=None): """ This method launches the sensing process as activities. It is intended to launch a very long process made @@ -113,6 +113,8 @@ class Alarm(XMLObject, PeriodicityMixin): The result of the sensing process can be obtained by invoking the sense method or by requesting a report. """ + activate_kw = dict(activate_kw) + portal_membership = self.getPortalObject().portal_membership if fixit or not self.getEnabled(): checkPermission = portal_membership.checkPermission @@ -135,7 +137,9 @@ class Alarm(XMLObject, PeriodicityMixin): # able to notify the user after all processes are ended # We do some inspection to keep compatibility # (because fixit and tag were not set previously) - tag = self.__getTag(True) + if 'tag' not in activate_kw: + activate_kw['tag'] = self.__getTag(True) + tag = activate_kw['tag'] method = getattr(self, method_id) func_code = method.func_code try: @@ -149,13 +153,13 @@ class Alarm(XMLObject, PeriodicityMixin): name_list = func_code.co_varnames[:func_code.co_argcount] if 'params' in name_list or has_kw: # New New API - getattr(self.activate(tag=tag), method_id)(fixit=fixit, tag=tag, params=params) + getattr(self.activate(**activate_kw), method_id)(fixit=fixit, tag=tag, params=params) elif 'fixit' in name_list: # New API - also if variable number of named parameters - getattr(self.activate(tag=tag), method_id)(fixit=fixit, tag=tag) + getattr(self.activate(**activate_kw), method_id)(fixit=fixit, tag=tag) else: # Old API - getattr(self.activate(tag=tag), method_id)() + getattr(self.activate(**activate_kw), method_id)() if self.isAlarmNotificationMode(): self.activate(after_tag=tag).notify(include_active=True, params=params) @@ -163,6 +167,7 @@ class Alarm(XMLObject, PeriodicityMixin): # is always invoked by system user. sm = getSecurityManager() newSecurityManager(None, nobody) + try: _activeSense() finally: