Commit df2f22d0 authored by Rafael Monnerat's avatar Rafael Monnerat

extend *slap-interface-workflow API to CRM/PDM

See merge request !360
parents 1d1bcf8b 4eeac9b7
Pipeline #20170 failed with stage
in 0 seconds
...@@ -1253,3 +1253,208 @@ class TestSlapOSCorePersonRequestToken(SlapOSTestCaseMixin): ...@@ -1253,3 +1253,208 @@ class TestSlapOSCorePersonRequestToken(SlapOSTestCaseMixin):
self.assertEqual( self.assertEqual(
token.getPortalType(), "One Time Restricted Access Token") token.getPortalType(), "One Time Restricted Access Token")
self.assertEqual(token.getUrlMethod(), "POST") self.assertEqual(token.getUrlMethod(), "POST")
class TestSlapOSCorePersonNotify(SlapOSTestCaseMixin):
def afterSetUp(self):
SlapOSTestCaseMixin.afterSetUp(self)
self.person = self.makePerson()
self.tic()
def beforeTearDown(self):
pass
def test_Person_notify_mandatory_argument(self):
self.assertRaises(TypeError, self.person.notify)
self.assertRaises(TypeError, self.person.notify, support_request_title="a")
self.assertRaises(TypeError, self.person.notify, support_request_title="a", support_request_description="b")
def test_Person_notify_unknown_aggregate(self):
self.assertRaises(KeyError, self.person.notify,
support_request_title="a", support_request_description="b", aggregate="c")
def test_Person_notify_computer_node(self):
compute_node, _ = self._makeComputeNode()
self._test_Person_notify(compute_node)
def test_Person_notify_instance_tree(self):
person = self.portal.person_module.template_member\
.Base_createCloneDocument(batch_mode=1)
instance_tree = self.portal\
.instance_tree_module.template_instance_tree\
.Base_createCloneDocument(batch_mode=1)
instance_tree.validate()
new_id = self.generateNewId()
instance_tree.edit(
title= "Test hosting sub ticket %s" % new_id,
reference="TESTHST-%s" % new_id,
destination_section_value=person
)
self._test_Person_notify(instance_tree)
def test_Person_notify_software_installation(self):
self._makeComputeNode()
software_installation = self.portal\
.software_installation_module.template_software_installation\
.Base_createCloneDocument(batch_mode=1)
software_installation.edit(
url_string=self.generateNewSoftwareReleaseUrl(),
aggregate=self.compute_node.getRelativeUrl(),
reference='TESTSOFTINSTS-%s' % self.generateNewId(),
title='Start requested for %s' % self.compute_node.getUid()
)
software_installation.validate()
software_installation.requestStart()
self._test_Person_notify(software_installation)
def _test_Person_notify(self, aggregate_value):
# Step 1: Notify
self.person.notify(
support_request_title="A",
support_request_description="B",
aggregate=aggregate_value.getRelativeUrl()
)
# Step 2: Check return
support_request_relative_url = self.person.REQUEST.get(
"support_request_relative_url", None)
self.assertNotEqual(None, support_request_relative_url)
support_request_in_progress = self.person.REQUEST.get(
"support_request_in_progress", None)
self.assertEqual(support_request_in_progress, support_request_relative_url)
support_request = self.portal.restrictedTraverse(support_request_in_progress)
self.assertEqual(support_request.getSimulationState(),
"validated")
self.assertEqual(support_request.getTitle(), "A")
self.assertEqual(support_request.getDescription(), "B")
self.assertNotEqual(support_request.getStartDate(), None)
self.assertEqual(support_request.getDestinationDecision(),
self.person.getRelativeUrl())
self.assertEqual(support_request.getAggregateValue(),
aggregate_value)
self.assertEqual(support_request.getResource(),
"service_module/slapos_crm_monitoring")
# Step 3: Reset REQUEST and check in progress before catalog
self.person.REQUEST.set(
"support_request_relative_url", None)
support_request_relative_url = self.person.REQUEST.get(
"support_request_relative_url", None)
self.assertEqual(None, support_request_relative_url)
self.person.notify(
support_request_title="A",
support_request_description="B",
aggregate=aggregate_value.getRelativeUrl()
)
support_request_relative_url = self.person.REQUEST.get(
"support_request_relative_url", None)
self.assertNotEqual(None, support_request_relative_url)
self.assertEqual(support_request_in_progress, support_request_relative_url)
self.tic()
# Step 4: Reset parameters and check if the support request is got again.
self.person.REQUEST.set(
"support_request_relative_url", None)
support_request_relative_url = self.person.REQUEST.get(
"support_request_relative_url", None)
self.assertEqual(None, support_request_relative_url)
support_request_in_progress = self.person.REQUEST.set(
"support_request_in_progress", None)
support_request_in_progress = self.person.REQUEST.set(
"support_request_in_progress", None)
self.assertEqual(support_request_in_progress, None)
self.commit()
self.person.notify(
support_request_title="A",
support_request_description="B",
aggregate=aggregate_value.getRelativeUrl()
)
support_request_relative_url = self.person.REQUEST.get(
"support_request_relative_url", None)
self.assertNotEqual(None, support_request_relative_url)
support_request_in_progress = self.person.REQUEST.get(
"support_request_in_progress", None)
self.assertEqual(support_request_in_progress, support_request_relative_url)
# Check if it is the same Support Request as before
self.assertEqual(support_request.getRelativeUrl(),
support_request_relative_url)
# Step 5: Retry the same thing, but now on suspended state
support_request.suspend()
self.tic()
self.person.REQUEST.set(
"support_request_relative_url", None)
support_request_relative_url = self.person.REQUEST.get(
"support_request_relative_url", None)
self.assertEqual(None, support_request_relative_url)
support_request_in_progress = self.person.REQUEST.set(
"support_request_in_progress", None)
support_request_in_progress = self.person.REQUEST.set(
"support_request_in_progress", None)
self.assertEqual(support_request_in_progress, None)
self.commit()
self.person.notify(
support_request_title="A",
support_request_description="B",
aggregate=aggregate_value.getRelativeUrl()
)
support_request_relative_url = self.person.REQUEST.get(
"support_request_relative_url", None)
self.assertNotEqual(None, support_request_relative_url)
support_request_in_progress = self.person.REQUEST.get(
"support_request_in_progress", None)
self.assertEqual(support_request_in_progress, support_request_relative_url)
# Check if it is the same Support Request as before and still suspended
self.assertEqual(support_request.getRelativeUrl(),
support_request_relative_url)
self.assertEqual(support_request.getSimulationState(), "suspended")
# Step 6: If the support request is closed, create indeed a new one.
support_request.invalidate()
self.tic()
self.person.REQUEST.set("support_request_relative_url", None)
support_request_relative_url = self.person.REQUEST.get(
"support_request_relative_url", None)
self.assertEqual(None, support_request_relative_url)
support_request_in_progress = self.person.REQUEST.set(
"support_request_in_progress", None)
support_request_in_progress = self.person.REQUEST.set(
"support_request_in_progress", None)
self.assertEqual(support_request_in_progress, None)
self.commit()
self.person.notify(
support_request_title="A",
support_request_description="B",
aggregate=aggregate_value.getRelativeUrl()
)
support_request_relative_url = self.person.REQUEST.get(
"support_request_relative_url", None)
self.assertNotEqual(None, support_request_relative_url)
support_request_in_progress = self.person.REQUEST.get(
"support_request_in_progress", None)
self.assertEqual(support_request_in_progress, support_request_relative_url)
# Check if it is the another Support Request
self.assertEqual(support_request.getSimulationState(), "invalidated")
self.assertNotEqual(support_request.getRelativeUrl(),
support_request_relative_url)
from DateTime import DateTime person = state_change['object']
portal = person.getPortalObject()
portal = context.getPortalObject() # Get required arguments
aggregate_value = portal.restrictedTraverse(source_relative_url) kwargs = state_change.kwargs
if aggregate_value.getPortalType() == "Compute Node": # Required args
destination_decision = aggregate_value.getSourceAdministration() # Raise TypeError if all parameters are not provided
elif aggregate_value.getPortalType() == "Software Instance": try:
destination_decision = aggregate_value.getSpecialiseValue().getDestinationSection() support_request_title = kwargs['support_request_title']
elif aggregate_value.getPortalType() == "Instance Tree": description = kwargs['support_request_description']
destination_decision = aggregate_value.getDestinationSection() # Aggregate can be None, so it isn't included on the kwargs
elif aggregate_value.getPortalType() == "Software Installation": aggregate = kwargs["aggregate"]
destination_decision = aggregate_value.getDestinationSection() except KeyError:
else: raise TypeError, "Person_requestSupportRequest takes exactly 3 arguments"
destination_decision = None
aggregate_value = portal.restrictedTraverse(aggregate)
if portal.ERP5Site_isSupportRequestCreationClosed(destination_decision):
# Stop ticket creation
return
support_request_in_progress = portal.portal_catalog.getResultValue( support_request_in_progress = portal.portal_catalog.getResultValue(
portal_type = 'Support Request', portal_type = 'Support Request',
title = title, title = support_request_title,
simulation_state = ["validated", "submitted", "suspended"], simulation_state = ["validated", "submitted", "suspended"],
default_aggregate_uid = aggregate_value.getUid(), default_aggregate_uid = aggregate_value.getUid(),
) )
if support_request_in_progress is not None: if support_request_in_progress is not None:
return support_request_in_progress context.REQUEST.set("support_request_relative_url",
support_request_in_progress.getRelativeUrl())
context.REQUEST.set("support_request_in_progress",
support_request_in_progress.getRelativeUrl())
return
support_request_in_progress = context.REQUEST.get("support_request_in_progress", None) support_request_in_progress = context.REQUEST.get("support_request_in_progress", None)
if support_request_in_progress is not None: if support_request_in_progress is not None:
support_request = portal.restrictedTraverse(support_request_in_progress, None) support_request = portal.restrictedTraverse(support_request_in_progress, None)
if support_request and support_request.getTitle() == title and \ if support_request and support_request.getTitle() == support_request_title and \
support_request.getAggregateUid() == aggregate_value.getUid(): support_request.getAggregateUid() == aggregate_value.getUid():
return portal.restrictedTraverse(support_request_in_progress) context.REQUEST.set("support_request_relative_url", support_request_in_progress)
return
# Ensure resoure is Monitoring # Ensure resoure is Monitoring
resource = portal.service_module.\ resource = portal.service_module.\
...@@ -45,15 +47,14 @@ support_request = portal.restrictedTraverse( ...@@ -45,15 +47,14 @@ support_request = portal.restrictedTraverse(
.Base_createCloneDocument(batch_mode=1) .Base_createCloneDocument(batch_mode=1)
support_request.edit( support_request.edit(
title = title, title = support_request_title,
description = description, description = description,
start_date = DateTime(), start_date = DateTime(),
destination_decision=destination_decision, destination_decision=person.getRelativeUrl(),
aggregate_value = aggregate_value, aggregate_value=aggregate_value,
resource=resource resource=resource
) )
support_request.validate() support_request.validate()
context.REQUEST.set("support_request_relative_url", support_request.getRelativeUrl())
context.REQUEST.set("support_request_in_progress", support_request.getRelativeUrl()) context.REQUEST.set("support_request_in_progress", support_request.getRelativeUrl())
return support_request
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/> <global name="Workflow Script" module="erp5.portal_type"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
...@@ -50,11 +50,25 @@ ...@@ -50,11 +50,25 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>message_title, message, destination_relative_url</string> </value> <value> <string>state_change</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>SupportRequest_trySendNotificationMessage</string> </value> <value> <string>script_Person_notify</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Person_notify</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
person = state_change['object']
portal = person.getPortalObject()
# Get required arguments
kwargs = state_change.kwargs
# Required args
# Raise TypeError if all parameters are not provided
try:
support_request_title = kwargs['support_request_title']
resource = kwargs['support_request_resource']
description = kwargs['support_request_description']
# Aggregate can be None, so it isn't included on the kwargs
aggregate = kwargs.get("support_request_aggregate", None)
except KeyError:
raise TypeError, "Person_requestSupportRequest takes exactly 4 arguments"
tag = "%s_%s_SupportRequestInProgress" % (person.getUid(),
support_request_title)
if (portal.portal_activities.countMessageWithTag(tag) > 0):
# The software instance is already under creation but can not be fetched from catalog
# As it is not possible to fetch informations, it is better to raise an error
raise NotImplementedError(tag)
support_request_portal_type = "Support Request"
module = portal.getDefaultModule(portal_type=support_request_portal_type)
support_request = module.newContent(
portal_type=support_request_portal_type,
title=support_request_title,
description=description,
resource=resource,
destination_decision_value=person,
aggregate=aggregate,
specialise="sale_trade_condition_module/slapos_ticket_trade_condition",
activate_kw={'tag': tag}
)
context.REQUEST.set("support_request_relative_url", support_request.getRelativeUrl())
support_request.approveRegistration()
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/> <global name="Workflow Script" module="erp5.portal_type"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
...@@ -50,11 +50,25 @@ ...@@ -50,11 +50,25 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string></string> </value> <value> <string>state_change</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>UpgradeDecision_upgradeInstanceTree</string> </value> <value> <string>script_Person_requestSupportRequest</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Person_requestSupportRequest</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -16,12 +16,14 @@ ...@@ -16,12 +16,14 @@
<key> <string>categories</string> </key> <key> <string>categories</string> </key>
<value> <value>
<tuple> <tuple>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_network</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_notify</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_compute_node</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_compute_node</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_network</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_organisation</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_organisation</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_project</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_project</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_site</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_site</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_software_instance</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_software_instance</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_support</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_token</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_token</string>
</tuple> </tuple>
</value> </value>
......
...@@ -17,10 +17,14 @@ ...@@ -17,10 +17,14 @@
<value> <value>
<tuple> <tuple>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_draft</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_draft</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_notify</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_compute_node</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_compute_node</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_network</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_organisation</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_organisation</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_project</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_project</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_site</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_software_instance</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_software_instance</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_support</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_token</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_token</string>
</tuple> </tuple>
</value> </value>
......
...@@ -2,61 +2,61 @@ ...@@ -2,61 +2,61 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="Interaction Workflow Interaction" module="erp5.portal_type"/> <global name="Workflow Transition" module="erp5.portal_type"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item> <item>
<key> <string>categories</string> </key> <key> <string>action</string> </key>
<value> <value>
<tuple> <none/>
<string>before_commit_script/portal_workflow/slapos_erp5_interaction_workflow/script_WebMessage_stopAndReopenTicket</string>
</tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>description</string> </key> <key> <string>action_name</string> </key>
<value> <value>
<none/> <none/>
</value> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>categories</string> </key>
<value> <string>interaction_WebMessage_setFollowUp</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Interaction Workflow Interaction</string> </value>
</item>
<item>
<key> <string>portal_type_filter</string> </key>
<value> <value>
<tuple> <tuple>
<string>Web Message</string> <string>action_type/workflow</string>
<string>before_script/portal_workflow/person_slap_interface_workflow/script_Person_checkConsistency</string>
<string>after_script/portal_workflow/person_slap_interface_workflow/script_Person_notify</string>
</tuple> </tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>portal_type_group_filter</string> </key> <key> <string>description</string> </key>
<value> <value>
<tuple/> <none/>
</value> </value>
</item> </item>
<item> <item>
<key> <string>temporary_document_disallowed</string> </key> <key> <string>guard_permission</string> </key>
<value> <int>0</int> </value> <value>
<tuple/>
</value>
</item> </item>
<item> <item>
<key> <string>trigger_method_id</string> </key> <key> <string>icon</string> </key>
<value> <value>
<tuple> <none/>
<string>_setFollowUp*</string>
</tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>trigger_once_per_transaction</string> </key> <key> <string>id</string> </key>
<value> <int>1</int> </value> <value> <string>transition_notify</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Notify</string> </value>
</item> </item>
<item> <item>
<key> <string>trigger_type</string> </key> <key> <string>trigger_type</string> </key>
......
...@@ -2,61 +2,61 @@ ...@@ -2,61 +2,61 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="Interaction Workflow Interaction" module="erp5.portal_type"/> <global name="Workflow Transition" module="erp5.portal_type"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item> <item>
<key> <string>categories</string> </key> <key> <string>action</string> </key>
<value> <value>
<tuple> <none/>
<string>before_commit_script/portal_workflow/slapos_erp5_interaction_workflow/script_SupportRequest_createInitialWebMessage</string>
</tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>description</string> </key> <key> <string>action_name</string> </key>
<value> <value>
<none/> <none/>
</value> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>categories</string> </key>
<value> <string>interaction_SupportRequest_setSpecialise</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Interaction Workflow Interaction</string> </value>
</item>
<item>
<key> <string>portal_type_filter</string> </key>
<value> <value>
<tuple> <tuple>
<string>Support Request</string> <string>action_type/workflow</string>
<string>before_script/portal_workflow/person_slap_interface_workflow/script_Person_checkConsistency</string>
<string>after_script/portal_workflow/person_slap_interface_workflow/script_Person_requestSupportRequest</string>
</tuple> </tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>portal_type_group_filter</string> </key> <key> <string>description</string> </key>
<value> <value>
<tuple/> <none/>
</value> </value>
</item> </item>
<item> <item>
<key> <string>temporary_document_disallowed</string> </key> <key> <string>guard_permission</string> </key>
<value> <int>0</int> </value> <value>
<tuple/>
</value>
</item> </item>
<item> <item>
<key> <string>trigger_method_id</string> </key> <key> <string>icon</string> </key>
<value> <value>
<tuple> <none/>
<string>_setSpecialise*</string>
</tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>trigger_once_per_transaction</string> </key> <key> <string>id</string> </key>
<value> <int>1</int> </value> <value> <string>transition_request_support</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Request Support</string> </value>
</item> </item>
<item> <item>
<key> <string>trigger_type</string> </key> <key> <string>trigger_type</string> </key>
......
...@@ -7,4 +7,8 @@ ...@@ -7,4 +7,8 @@
<type>Regularisation Request</type> <type>Regularisation Request</type>
<workflow>edit_workflow, pricing_interaction_workflow, ticket_interaction_workflow, ticket_workflow</workflow> <workflow>edit_workflow, pricing_interaction_workflow, ticket_interaction_workflow, ticket_workflow</workflow>
</chain> </chain>
<chain>
<type>Support Request</type>
<workflow>ticket_slap_interface_workflow</workflow>
</chain>
</workflow_chain> </workflow_chain>
\ No newline at end of file
...@@ -29,11 +29,12 @@ request_title = 'Allocation scope of %s changed to %s' % (compute_node_reference ...@@ -29,11 +29,12 @@ request_title = 'Allocation scope of %s changed to %s' % (compute_node_reference
request_description = 'Allocation scope has been changed to ' \ request_description = 'Allocation scope has been changed to ' \
'%s for %s' % (target_allocation_scope, compute_node_reference) '%s for %s' % (target_allocation_scope, compute_node_reference)
support_request = context.Base_generateSupportRequestForSlapOS( person.notify(support_request_title=request_title,
request_title, support_request_description=request_description,
request_description, aggregate=context.getRelativeUrl())
compute_node.getRelativeUrl()
) support_request_relative_url = context.REQUEST.get("support_request_relative_url")
support_request = portal.restrictedTraverse(support_request_relative_url)
if support_request is not None: if support_request is not None:
if support_request.getSimulationState() != "validated": if support_request.getSimulationState() != "validated":
...@@ -53,8 +54,8 @@ if support_request is not None: ...@@ -53,8 +54,8 @@ if support_request is not None:
message = notification_message.asText( message = notification_message.asText(
substitution_method_parameter_dict={'mapping_dict': mapping_dict}) substitution_method_parameter_dict={'mapping_dict': mapping_dict})
event = support_request.SupportRequest_trySendNotificationMessage( support_request.notify(message_title=request_title, message=message)
request_title, message, person.getRelativeUrl()) event = support_request.REQUEST.get("ticket_notified_item")
if event is not None: if event is not None:
# event added, suspend ticket # event added, suspend ticket
......
from DateTime import DateTime from DateTime import DateTime
portal = context.getPortalObject() portal = context.getPortalObject()
if portal.ERP5Site_isSupportRequestCreationClosed(): person = context.getSourceAdministrationValue(portal_type="Person")
# Stop ticket creation if not person or \
return context.getMonitorScope() == "disabled" or \
portal.ERP5Site_isSupportRequestCreationClosed():
if context.getMonitorScope() == "disabled": return
return
software_installation_list = portal.portal_catalog( software_installation_list = portal.portal_catalog(
portal_type='Software Installation', portal_type='Software Installation',
...@@ -50,15 +49,13 @@ for software_installation in software_installation_list: ...@@ -50,15 +49,13 @@ for software_installation in software_installation_list:
(software_installation.getUrlString(), compute_node_title, software_installation.getCreationDate()) (software_installation.getUrlString(), compute_node_title, software_installation.getCreationDate())
if should_notify: if should_notify:
support_request = context.Base_generateSupportRequestForSlapOS( person.notify(support_request_title=ticket_title,
ticket_title, support_request_description=description,
description, aggregate=software_installation.getRelativeUrl())
software_installation.getRelativeUrl()
)
person = context.getSourceAdministrationValue(portal_type="Person") support_request = context.REQUEST.get("support_request_relative_url")
if not person: if support_request is None:
return support_request return
# Send Notification message # Send Notification message
notification_reference = 'slapos-crm-compute_node_software_installation_state.notification' notification_reference = 'slapos-crm-compute_node_software_installation_state.notification'
...@@ -75,10 +72,7 @@ for software_installation in software_installation_list: ...@@ -75,10 +72,7 @@ for software_installation in software_installation_list:
message = notification_message.asText( message = notification_message.asText(
substitution_method_parameter_dict={'mapping_dict':mapping_dict}) substitution_method_parameter_dict={'mapping_dict':mapping_dict})
support_request.SupportRequest_trySendNotificationMessage( support_request.notify(message_title=ticket_title, message=message)
ticket_title,
message, person.getRelativeUrl())
support_request_list.append(support_request) support_request_list.append(support_request)
return support_request_list return support_request_list
from DateTime import DateTime from DateTime import DateTime
portal = context.getPortalObject() portal = context.getPortalObject()
if portal.ERP5Site_isSupportRequestCreationClosed(): person = context.getSourceAdministrationValue(portal_type="Person")
# Stop ticket creation if not person or \
return context.getMonitorScope() == "disabled" or \
portal.ERP5Site_isSupportRequestCreationClosed():
if context.getMonitorScope() == "disabled": return
return
if context.getAllocationScope("open").startswith("close"): if context.getAllocationScope("open").startswith("close"):
context.setMonitorScope("disabled") context.setMonitorScope("disabled")
...@@ -18,7 +17,6 @@ ticket_title = "[MONITORING] Lost contact with compute_node %s" % reference ...@@ -18,7 +17,6 @@ ticket_title = "[MONITORING] Lost contact with compute_node %s" % reference
description = "" description = ""
last_contact = "No Contact Information" last_contact = "No Contact Information"
d = context.getAccessStatus() d = context.getAccessStatus()
# Ignore if data isn't present. # Ignore if data isn't present.
if d.get("no_data") == 1: if d.get("no_data") == 1:
...@@ -33,20 +31,19 @@ else: ...@@ -33,20 +31,19 @@ else:
# Nothing to notify. # Nothing to notify.
return return
support_request = context.Base_generateSupportRequestForSlapOS( person.notify(support_request_title=ticket_title,
ticket_title, support_request_description=description,
description, aggregate=context.getRelativeUrl())
context.getRelativeUrl()
)
person = context.getSourceAdministrationValue(portal_type="Person") support_request_relative_url = context.REQUEST.get("support_request_relative_url")
if not person: if support_request_relative_url is None:
return support_request return
support_request = portal.restrictedTraverse(support_request_relative_url)
# Send Notification message # Send Notification message
notification_reference = 'slapos-crm-compute_node_check_state.notification'
notification_message = portal.portal_notifications.getDocumentValue( notification_message = portal.portal_notifications.getDocumentValue(
reference=notification_reference) reference='slapos-crm-compute_node_check_state.notification')
if notification_message is None: if notification_message is None:
message = """%s""" % description message = """%s""" % description
...@@ -55,10 +52,8 @@ else: ...@@ -55,10 +52,8 @@ else:
'compute_node_id':reference, 'compute_node_id':reference,
'last_contact':last_contact} 'last_contact':last_contact}
message = notification_message.asText( message = notification_message.asText(
substitution_method_parameter_dict={'mapping_dict':mapping_dict}) substitution_method_parameter_dict={'mapping_dict': mapping_dict})
support_request.notify(message_title=ticket_title, message=message)
support_request.SupportRequest_trySendNotificationMessage(
ticket_title,
message, person.getRelativeUrl())
return support_request return support_request
portal = context.getPortalObject() portal = context.getPortalObject()
person = context.getDestinationSectionValue()
if person is None or portal.ERP5Site_isSupportRequestCreationClosed(person.getRelativeUrl()):
# Stop ticket creation
return
ticket_title = "Instance Tree %s is failing." % context.getTitle() ticket_title = "Instance Tree %s is failing." % context.getTitle()
error_message = instance.SoftwareInstance_hasReportedError(include_message=True) error_message = instance.SoftwareInstance_hasReportedError(include_message=True)
...@@ -10,27 +16,23 @@ if error_message: ...@@ -10,27 +16,23 @@ if error_message:
else: else:
error_message = "No message!" error_message = "No message!"
support_request = context.Base_generateSupportRequestForSlapOS( person.notify(support_request_title=ticket_title,
ticket_title, support_request_description=description,
description, aggregate=context.getRelativeUrl())
context.getRelativeUrl())
if support_request is None: support_request_relative_url = context.REQUEST.get("support_request_relative_url")
if support_request_relative_url is None:
return return
person = context.getDestinationSectionValue(portal_type="Person") support_request = portal.restrictedTraverse(support_request_relative_url)
if not person:
return
if support_request.getSimulationState() not in ["validated", "suspended"]: if support_request.getSimulationState() not in ["validated", "suspended"]:
support_request.validate() support_request.validate()
# Send Notification message # Send Notification message
message = description message = description
notification_reference = notification_message_reference
notification_message = portal.portal_notifications.getDocumentValue( notification_message = portal.portal_notifications.getDocumentValue(
reference=notification_reference) reference=notification_message_reference)
if notification_message is not None: if notification_message is not None:
mapping_dict = {'instance_tree_title':context.getTitle(), mapping_dict = {'instance_tree_title':context.getTitle(),
'instance': instance.getTitle(), 'instance': instance.getTitle(),
...@@ -39,5 +41,5 @@ if notification_message is not None: ...@@ -39,5 +41,5 @@ if notification_message is not None:
message = notification_message.asText( message = notification_message.asText(
substitution_method_parameter_dict={'mapping_dict':mapping_dict}) substitution_method_parameter_dict={'mapping_dict':mapping_dict})
return support_request.SupportRequest_trySendNotificationMessage( support_request.notify(message_title=ticket_title, message=message)
ticket_title, message, person.getRelativeUrl()) return context.REQUEST.get("ticket_notified_item")
""" Close Support Request which are related to a Destroy Requested Instance. """ """ Close Support Request which are related to a Destroy Requested Instance. """
portal = context.getPortalObject()
if context.getSimulationState() == "invalidated": if context.getSimulationState() == "invalidated":
return return
document = context.getAggregateValue() document = context.getAggregateValue()
if document is not None and document.getSlapState() == "destroy_requested": if document is not None and document.getSlapState() == "destroy_requested":
person = context.getDestinationDecision(portal_type="Person") person = context.getDestinationDecision(portal_type="Person")
if not person: if not person:
return return
if context.getSimulationState() != "invalidated":
context.invalidate()
# Send Notification message # Send Notification message
message = """ Closing this ticket as the Instance Tree was destroyed by the user. message = """ Closing this ticket as the Instance Tree was destroyed by the user.
""" """
notification_reference = "slapos-crm-support-request-close-destroyed-notification"
portal = context.getPortalObject()
notification_message = portal.portal_notifications.getDocumentValue( notification_message = portal.portal_notifications.getDocumentValue(
reference=notification_reference) reference="slapos-crm-support-request-close-destroyed-notification")
if notification_message is not None: if notification_message is not None:
mapping_dict = {'instance_tree_title':document.getTitle()} mapping_dict = {'instance_tree_title': document.getTitle()}
message = notification_message.asText( message = notification_message.asText(
substitution_method_parameter_dict={'mapping_dict':mapping_dict}) substitution_method_parameter_dict={'mapping_dict':mapping_dict})
return context.SupportRequest_trySendNotificationMessage( context.notify(message_title="Instance Tree was destroyed was destroyed by the user",
"Instance Tree was destroyed was destroyed by the user", message, person) message=message)
context.invalidate()
return context.REQUEST.get("ticket_notified_item")
...@@ -2,7 +2,6 @@ if context.getSimulationState() == "invalidated": ...@@ -2,7 +2,6 @@ if context.getSimulationState() == "invalidated":
return return
document = context.getAggregateValue(portal_type="Instance Tree") document = context.getAggregateValue(portal_type="Instance Tree")
if document is None: if document is None:
return return
......
...@@ -27,8 +27,6 @@ from erp5.component.test.SlapOSTestCaseMixin import \ ...@@ -27,8 +27,6 @@ from erp5.component.test.SlapOSTestCaseMixin import \
from DateTime import DateTime from DateTime import DateTime
from App.Common import rfc1123_date from App.Common import rfc1123_date
from Products.ERP5Type.Cache import DEFAULT_CACHE_SCOPE from Products.ERP5Type.Cache import DEFAULT_CACHE_SCOPE
from Products.ERP5Type.tests.utils import createZODBPythonScript
import json import json
import feedparser import feedparser
...@@ -655,13 +653,6 @@ class TestSlapOSComputeNode_notifyWrongAllocationScope(TestCRMSkinsMixin): ...@@ -655,13 +653,6 @@ class TestSlapOSComputeNode_notifyWrongAllocationScope(TestCRMSkinsMixin):
'assert reference == "slapos-crm-compute_node_allocation_scope.notification"\n' \ 'assert reference == "slapos-crm-compute_node_allocation_scope.notification"\n' \
'return context.restrictedTraverse(' \ 'return context.restrictedTraverse(' \
'context.REQUEST["test_ComputeNodeNotAllowedAllocationScope_OpenPublic"])') 'context.REQUEST["test_ComputeNodeNotAllowedAllocationScope_OpenPublic"])')
@simulate('SupportRequest_trySendNotificationMessage',
'message_title, message, destination_relative_url',
'context.portal_workflow.doActionFor(' \
'context, action="edit_action", ' \
'comment="Visited by SupportRequest_trySendNotificationMessage ' \
'%s %s %s" % (message_title, message, destination_relative_url))\n' \
'return 1')
def test_ComputeNodeNotAllowedAllocationScope_OpenPublic(self): def test_ComputeNodeNotAllowedAllocationScope_OpenPublic(self):
compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0] compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
person = compute_node.getSourceAdministrationValue() person = compute_node.getSourceAdministrationValue()
...@@ -677,13 +668,14 @@ class TestSlapOSComputeNode_notifyWrongAllocationScope(TestCRMSkinsMixin): ...@@ -677,13 +668,14 @@ class TestSlapOSComputeNode_notifyWrongAllocationScope(TestCRMSkinsMixin):
self.assertNotEqual(None, ticket) self.assertNotEqual(None, ticket)
self.assertEqual(ticket.getSimulationState(), 'suspended') self.assertEqual(ticket.getSimulationState(), 'suspended')
self.assertEqual('Visited by SupportRequest_trySendNotificationMessage ' \ event_list = ticket.getFollowUpRelatedValueList()
'%s %s %s' % \ self.assertEqual(len(event_list), 1)
('Allocation scope of %s changed to %s' % (compute_node.getReference(), event = event_list[0]
'open/personal'),
'Test NM content\n%s\n' % compute_node.getReference(), person.getRelativeUrl()),
ticket.workflow_history['edit_workflow'][-1]['comment'])
self.assertEqual(event.getTitle(),
'Allocation scope of %s changed to %s' % (compute_node.getReference(), 'open/personal'))
self.assertIn(compute_node.getReference(), event.getTextContent())
self.assertEqual(event.getDestination(), person.getRelativeUrl())
@simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0') @simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0')
@simulate('NotificationTool_getDocumentValue', @simulate('NotificationTool_getDocumentValue',
...@@ -691,13 +683,6 @@ class TestSlapOSComputeNode_notifyWrongAllocationScope(TestCRMSkinsMixin): ...@@ -691,13 +683,6 @@ class TestSlapOSComputeNode_notifyWrongAllocationScope(TestCRMSkinsMixin):
'assert reference == "slapos-crm-compute_node_allocation_scope.notification"\n' \ 'assert reference == "slapos-crm-compute_node_allocation_scope.notification"\n' \
'return context.restrictedTraverse(' \ 'return context.restrictedTraverse(' \
'context.REQUEST["test_ComputeNodeNotAllowedAllocationScope_OpenFriend"])') 'context.REQUEST["test_ComputeNodeNotAllowedAllocationScope_OpenFriend"])')
@simulate('SupportRequest_trySendNotificationMessage',
'message_title, message, destination_relative_url',
'context.portal_workflow.doActionFor(' \
'context, action="edit_action", ' \
'comment="Visited by SupportRequest_trySendNotificationMessage ' \
'%s %s %s" % (message_title, message, destination_relative_url))\n' \
'return 1')
def test_ComputeNodeNotAllowedAllocationScope_OpenFriend(self): def test_ComputeNodeNotAllowedAllocationScope_OpenFriend(self):
compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0] compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
person = compute_node.getSourceAdministrationValue() person = compute_node.getSourceAdministrationValue()
...@@ -712,12 +697,15 @@ class TestSlapOSComputeNode_notifyWrongAllocationScope(TestCRMSkinsMixin): ...@@ -712,12 +697,15 @@ class TestSlapOSComputeNode_notifyWrongAllocationScope(TestCRMSkinsMixin):
self.tic() self.tic()
self.assertEqual(compute_node.getAllocationScope(), 'open/personal') self.assertEqual(compute_node.getAllocationScope(), 'open/personal')
self.assertEqual(ticket.getSimulationState(), 'suspended') self.assertEqual(ticket.getSimulationState(), 'suspended')
self.assertEqual('Visited by SupportRequest_trySendNotificationMessage ' \
'%s %s %s' % \ event_list = ticket.getFollowUpRelatedValueList()
('Allocation scope of %s changed to %s' % (compute_node.getReference(), self.assertEqual(len(event_list), 1)
'open/personal'), event = event_list[0]
'Test NM content\n%s\n' % compute_node.getReference(), person.getRelativeUrl()),
ticket.workflow_history['edit_workflow'][-1]['comment']) self.assertEqual(event.getTitle(),
'Allocation scope of %s changed to %s' % (compute_node.getReference(), 'open/personal'))
self.assertIn(compute_node.getReference(), event.getTextContent())
self.assertEqual(event.getDestination(), person.getRelativeUrl())
@simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0') @simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0')
@simulate('ComputeNode_hasContactedRecently', '*args, **kwargs','return False') @simulate('ComputeNode_hasContactedRecently', '*args, **kwargs','return False')
...@@ -726,13 +714,6 @@ class TestSlapOSComputeNode_notifyWrongAllocationScope(TestCRMSkinsMixin): ...@@ -726,13 +714,6 @@ class TestSlapOSComputeNode_notifyWrongAllocationScope(TestCRMSkinsMixin):
'assert reference == "slapos-crm-compute-node-allocation-scope-closed.notification"\n' \ 'assert reference == "slapos-crm-compute-node-allocation-scope-closed.notification"\n' \
'return context.restrictedTraverse(' \ 'return context.restrictedTraverse(' \
'context.REQUEST["test_ComputeNodeToCloseAllocationScope_OpenPersonal"])') 'context.REQUEST["test_ComputeNodeToCloseAllocationScope_OpenPersonal"])')
@simulate('SupportRequest_trySendNotificationMessage',
'message_title, message, destination_relative_url',
'context.portal_workflow.doActionFor(' \
'context, action="edit_action", ' \
'comment="Visited by SupportRequest_trySendNotificationMessage ' \
'%s %s %s" % (message_title, message, destination_relative_url))\n' \
'return 1')
def test_ComputeNodeToCloseAllocationScope_OpenPersonal(self): def test_ComputeNodeToCloseAllocationScope_OpenPersonal(self):
compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0] compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
person = compute_node.getSourceAdministrationValue() person = compute_node.getSourceAdministrationValue()
...@@ -747,12 +728,16 @@ class TestSlapOSComputeNode_notifyWrongAllocationScope(TestCRMSkinsMixin): ...@@ -747,12 +728,16 @@ class TestSlapOSComputeNode_notifyWrongAllocationScope(TestCRMSkinsMixin):
self.assertEqual('suspended', support_request.getSimulationState()) self.assertEqual('suspended', support_request.getSimulationState())
self.assertEqual(compute_node.getAllocationScope(), target_allocation_scope) self.assertEqual(compute_node.getAllocationScope(), target_allocation_scope)
self.assertEqual('Visited by SupportRequest_trySendNotificationMessage ' \
'%s %s %s' % \ event_list = support_request.getFollowUpRelatedValueList()
('Allocation scope of %s changed to %s' % (compute_node.getReference(), self.assertEqual(len(event_list), 1)
target_allocation_scope), event = event_list[0]
'Test NM content\n%s\n' % compute_node.getReference(), person.getRelativeUrl()),
support_request.workflow_history['edit_workflow'][-1]['comment']) self.assertEqual(event.getTitle(),
'Allocation scope of %s changed to %s' % \
(compute_node.getReference(), target_allocation_scope))
self.assertIn(compute_node.getReference(), event.getTextContent())
self.assertEqual(event.getDestination(), person.getRelativeUrl())
def test_ComputeNodeNormalAllocationScope_OpenPersonal(self): def test_ComputeNodeNormalAllocationScope_OpenPersonal(self):
compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0] compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
...@@ -988,189 +973,6 @@ class TestSlapOSisSupportRequestCreationClosed(TestCRMSkinsMixin): ...@@ -988,189 +973,6 @@ class TestSlapOSisSupportRequestCreationClosed(TestCRMSkinsMixin):
self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed()) self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed())
class TestSlapOSGenerateSupportRequestForSlapOS(TestCRMSkinsMixin):
def afterSetUp(self):
TestCRMSkinsMixin.afterSetUp(self)
self.tic()
self._cancelTestSupportRequestList()
def test_compute_node_Base_generateSupportRequestForSlapOS(self):
self._makeComputeNode()
title = "Test Support Request %s" % self.compute_node.getReference()
support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
title, title, self.compute_node.getRelativeUrl()
)
self.tic()
self.assertNotEqual(support_request, None)
self.assertEqual(support_request.getSimulationState(), "validated")
self.assertEqual(support_request.getRelativeUrl(),
self.portal.REQUEST.get("support_request_in_progress", None))
# The support request is added to compute_node owner.
self.assertEqual(support_request.getDestinationDecision(),
self.compute_node.getSourceAdministration())
self.assertEqual(support_request.getTitle(), title)
self.assertEqual(support_request.getDescription(), title)
self.assertEqual(support_request.getAggregateValue(),
self.compute_node)
def test_software_instance_Base_generateSupportRequestForSlapOS(self):
instance_tree = self._makeInstanceTree()
self._makeSoftwareInstance(instance_tree,
self.generateNewSoftwareReleaseUrl())
instance = instance_tree.getSuccessorValue()
title = "Test Support Request %s" % instance.getReference()
support_request = instance.Base_generateSupportRequestForSlapOS(
title, title, instance.getRelativeUrl()
)
self.tic()
self.assertNotEqual(support_request, None)
self.assertEqual(support_request.getSimulationState(), "validated")
self.assertEqual(support_request.getRelativeUrl(),
self.portal.REQUEST.get("support_request_in_progress", None))
# The support request is added to compute_node owner.
self.assertEqual(support_request.getDestinationDecision(),
instance_tree.getDestinationSection())
self.assertEqual(support_request.getTitle(), title)
self.assertEqual(support_request.getDescription(), title)
self.assertEqual(support_request.getAggregateValue(),
instance)
def test_instance_tree_Base_generateSupportRequestForSlapOS(self):
instance_tree = self._makeInstanceTree()
title = "Test Support Request %s" % instance_tree.getReference()
support_request = instance_tree.Base_generateSupportRequestForSlapOS(
title, title, instance_tree.getRelativeUrl()
)
self.tic()
self.assertNotEqual(support_request, None)
self.assertEqual(support_request.getSimulationState(), "validated")
self.assertEqual(support_request.getRelativeUrl(),
self.portal.REQUEST.get("support_request_in_progress", None))
# The support request is added to compute_node owner.
self.assertEqual(support_request.getDestinationDecision(),
instance_tree.getDestinationSection())
self.assertEqual(support_request.getTitle(), title)
self.assertEqual(support_request.getDescription(), title)
self.assertEqual(support_request.getAggregateValue(),
instance_tree)
def test_software_installation_Base_generateSupportRequestForSlapOS(self):
software_installation = self._makeSoftwareInstallation()
title = "Test Support Request %s" % software_installation.generateNewId()
support_request = software_installation.Base_generateSupportRequestForSlapOS(
title, title, software_installation.getRelativeUrl()
)
self.tic()
self.assertNotEqual(support_request, None)
self.assertEqual(support_request.getSimulationState(), "validated")
self.assertEqual(support_request.getRelativeUrl(),
self.portal.REQUEST.get("support_request_in_progress", None))
# The support request is added to compute_node owner.
self.assertEqual(support_request.getDestinationDecision(),
software_installation.getDestinationSection())
self.assertEqual(support_request.getTitle(), title)
self.assertEqual(support_request.getDescription(), title)
self.assertEqual(support_request.getAggregateValue(),
software_installation)
def test_Base_generateSupportRequestForSlapOS_do_not_recreate_if_open(self):
self._makeComputeNode(owner=self.makePerson(user=0))
title = "Test Support Request %s" % self.compute_node.getReference()
support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
title, title, self.compute_node.getRelativeUrl()
)
self.tic()
self.portal.REQUEST.set("support_request_in_progress", None)
same_support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
title, title, self.compute_node.getRelativeUrl()
)
self.assertEqual(support_request, same_support_request)
def test_Base_generateSupportRequestForSlapOS_do_not_recreate_if_suspended(self):
self._makeComputeNode(owner=self.makePerson(user=0))
title = "Test Support Request %s" % self.compute_node.getReference()
support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
title, title, self.compute_node.getRelativeUrl()
)
support_request.suspend()
self.tic()
self.portal.REQUEST.set("support_request_in_progress", None)
same_support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
title, title, self.compute_node.getRelativeUrl()
)
self.assertEqual(support_request, same_support_request)
def test_Base_generateSupportRequestForSlapOS_recreate_if_closed(self):
self._makeComputeNode(owner=self.makePerson(user=0))
title = "Test Support Request %s" % self.compute_node.getReference()
support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
title, title, self.compute_node.getRelativeUrl())
self.tic()
support_request.invalidate()
self.tic()
self.portal.REQUEST.set("support_request_in_progress", None)
support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
title, title, self.compute_node.getRelativeUrl()
)
self.tic()
self.assertNotEqual(support_request, None)
def test_Base_generateSupportRequestForSlapOS_recreate(self):
self._makeComputeNode(owner=self.makePerson(user=0))
title = "Test Support Request %s" % self.compute_node.getRelativeUrl()
support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
title, title, self.compute_node.getRelativeUrl())
same_support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
title, title, self.compute_node.getRelativeUrl()
)
self.assertEqual(support_request, same_support_request)
def test_Base_generateSupportRequestForSlapOS_inprogress(self):
self._makeComputeNode(owner=self.makePerson(user=0))
title = "Test Support Request %s" % self.compute_node.getRelativeUrl()
support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
title, title, self.compute_node.getRelativeUrl())
in_progress = support_request.getRelativeUrl()
self.portal.REQUEST.set("support_request_in_progress", in_progress)
title = "Test Support Request %s" % self.compute_node.getRelativeUrl()
support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
title, title, self.compute_node.getRelativeUrl())
self.assertEqual(support_request.getRelativeUrl(), in_progress)
class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin): class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin):
def beforeTearDown(self): def beforeTearDown(self):
...@@ -1181,11 +983,6 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin): ...@@ -1181,11 +983,6 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin):
TestCRMSkinsMixin.afterSetUp(self) TestCRMSkinsMixin.afterSetUp(self)
self._cancelTestSupportRequestList("% TESTCOMPT-%") self._cancelTestSupportRequestList("% TESTCOMPT-%")
def _makeSupportRequest(self):
return self.portal.restrictedTraverse(
self.portal.portal_preferences.getPreferredSupportRequestTemplate()).\
Base_createCloneDocument(batch_mode=1)
def _makeNotificationMessage(self, reference): def _makeNotificationMessage(self, reference):
notification_message = self.portal.notification_message_module.newContent( notification_message = self.portal.notification_message_module.newContent(
portal_type="Notification Message", portal_type="Notification Message",
...@@ -1205,56 +1002,36 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin): ...@@ -1205,56 +1002,36 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin):
) )
return support_request return support_request
def _simulateBase_generateSupportRequestForSlapOS(self):
script_name = 'Base_generateSupportRequestForSlapOS'
if script_name in self.portal.portal_skins.custom.objectIds():
raise ValueError('Precondition failed: %s exists in custom' % script_name)
createZODBPythonScript(self.portal.portal_skins.custom,
script_name,
'*args, **kw',
'# Script body\n'
"""return context.getPortalObject().REQUEST['_simulateBase_generateSupportRequestForSlapOS']""")
transaction.commit()
@simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0') @simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0')
def test_ComputeNode_checkState_call_support_request(self): def test_ComputeNode_checkState_call_support_request(self):
compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0] compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
try: try:
self.pinDateTime(DateTime()-1.1) d = DateTime() - 1.1
self.pinDateTime(d)
compute_node.setAccessStatus("#access ") compute_node.setAccessStatus("#access ")
finally: finally:
self.unpinDateTime() self.unpinDateTime()
self._simulateBase_generateSupportRequestForSlapOS() compute_node_support_request = compute_node.ComputeNode_checkState()
support_request = self._makeSupportRequest() self.assertNotEqual(compute_node_support_request, None)
self.portal.REQUEST.set('_simulateBase_generateSupportRequestForSlapOS', self.assertIn("[MONITORING] Lost contact with compute_node",
support_request) compute_node_support_request.getTitle())
self.assertIn("has not contacted the server for more than 30 minutes",
try: compute_node_support_request.getDescription())
compute_node_support_request = compute_node.ComputeNode_checkState() self.assertIn(d.strftime("%Y/%m/%d %H:%M:%S"),
finally: compute_node_support_request.getDescription())
self._dropScript("Base_generateSupportRequestForSlapOS")
self.assertEqual(support_request,
compute_node_support_request)
@simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0') @simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0')
def test_ComputeNode_checkState_empty_cache(self): def test_ComputeNode_checkState_empty_cache(self):
compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0] compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
compute_node_support_request = compute_node.ComputeNode_checkState()
self._simulateBase_generateSupportRequestForSlapOS()
support_request = self._makeSupportRequest() compute_node_support_request = compute_node.ComputeNode_checkState()
self.portal.REQUEST.set('_simulateBase_generateSupportRequestForSlapOS', self.assertNotEqual(compute_node_support_request, None)
support_request) self.assertIn("[MONITORING] Lost contact with compute_node",
compute_node_support_request.getTitle())
try: self.assertIn("has not contacted the server (No Contact Information)",
compute_node_support_request = compute_node.ComputeNode_checkState() compute_node_support_request.getDescription())
finally:
self._dropScript("Base_generateSupportRequestForSlapOS")
self.assertEqual(support_request,
compute_node_support_request)
@simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0') @simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0')
@simulate('NotificationTool_getDocumentValue', @simulate('NotificationTool_getDocumentValue',
...@@ -1262,12 +1039,6 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin): ...@@ -1262,12 +1039,6 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin):
'assert reference == "slapos-crm-compute_node_check_state.notification"\n' \ 'assert reference == "slapos-crm-compute_node_check_state.notification"\n' \
'return context.restrictedTraverse(' \ 'return context.restrictedTraverse(' \
'context.REQUEST["test_ComputeNode_checkState_notify"])') 'context.REQUEST["test_ComputeNode_checkState_notify"])')
@simulate('SupportRequest_trySendNotificationMessage',
'message_title, message, destination_relative_url',
'context.portal_workflow.doActionFor(' \
'context, action="edit_action", ' \
'comment="Visited by SupportRequest_trySendNotificationMessage ' \
'%s %s %s" % (message_title, message, destination_relative_url))')
def test_ComputeNode_checkState_notify(self): def test_ComputeNode_checkState_notify(self):
compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0] compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
person = compute_node.getSourceAdministrationValue() person = compute_node.getSourceAdministrationValue()
...@@ -1286,14 +1057,15 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin): ...@@ -1286,14 +1057,15 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin):
ticket_title = "[MONITORING] Lost contact with compute_node %s" % compute_node.getReference() ticket_title = "[MONITORING] Lost contact with compute_node %s" % compute_node.getReference()
ticket = self._getGeneratedSupportRequest(compute_node.getUid(), ticket_title) ticket = self._getGeneratedSupportRequest(compute_node.getUid(), ticket_title)
self.assertNotEqual(ticket, None) self.assertNotEqual(ticket, None)
self.assertEqual('Visited by SupportRequest_trySendNotificationMessage ' \ event_list = ticket.getFollowUpRelatedValueList()
'%s %s %s' % ( \ self.assertEqual(len(event_list), 1)
ticket_title, event = event_list[0]
'Test NM content\n%s\n' % compute_node.getReference(),
person.getRelativeUrl()),
ticket.workflow_history['edit_workflow'][-1]['comment'])
self.assertEqual(event.getTitle(), ticket.getTitle())
self.assertIn(compute_node.getReference(), event.getTextContent())
self.assertEqual(event.getDestination(), person.getRelativeUrl())
@simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0') @simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0')
@simulate('NotificationTool_getDocumentValue', @simulate('NotificationTool_getDocumentValue',
...@@ -1301,12 +1073,6 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin): ...@@ -1301,12 +1073,6 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin):
'assert reference == "slapos-crm-compute_node_check_state.notification"\n' \ 'assert reference == "slapos-crm-compute_node_check_state.notification"\n' \
'return context.restrictedTraverse(' \ 'return context.restrictedTraverse(' \
'context.REQUEST["test_ComputeNode_checkState_empty_cache_notify"])') 'context.REQUEST["test_ComputeNode_checkState_empty_cache_notify"])')
@simulate('SupportRequest_trySendNotificationMessage',
'message_title, message, destination_relative_url',
'context.portal_workflow.doActionFor(' \
'context, action="edit_action", ' \
'comment="Visited by SupportRequest_trySendNotificationMessage ' \
'%s %s %s" % (message_title, message, destination_relative_url))')
def test_ComputeNode_checkState_empty_cache_notify(self): def test_ComputeNode_checkState_empty_cache_notify(self):
compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0] compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
person = compute_node.getSourceAdministrationValue() person = compute_node.getSourceAdministrationValue()
...@@ -1320,13 +1086,13 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin): ...@@ -1320,13 +1086,13 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin):
ticket_title = "[MONITORING] Lost contact with compute_node %s" % compute_node.getReference() ticket_title = "[MONITORING] Lost contact with compute_node %s" % compute_node.getReference()
ticket = self._getGeneratedSupportRequest(compute_node.getUid(), ticket_title) ticket = self._getGeneratedSupportRequest(compute_node.getUid(), ticket_title)
self.assertNotEqual(ticket, None) self.assertNotEqual(ticket, None)
self.assertEqual('Visited by SupportRequest_trySendNotificationMessage ' \ event_list = ticket.getFollowUpRelatedValueList()
'%s %s %s' % ( \ self.assertEqual(len(event_list), 1)
ticket_title, event = event_list[0]
'Test NM content\n%s\n' % compute_node.getReference(),
person.getRelativeUrl()),
ticket.workflow_history['edit_workflow'][-1]['comment'])
self.assertEqual(event.getTitle(), ticket.getTitle())
self.assertIn(compute_node.getReference(), event.getTextContent())
self.assertEqual(event.getDestination(), person.getRelativeUrl())
class TestSlapOSInstanceTree_createSupportRequestEvent(SlapOSTestCaseMixin): class TestSlapOSInstanceTree_createSupportRequestEvent(SlapOSTestCaseMixin):
...@@ -1341,8 +1107,7 @@ class TestSlapOSInstanceTree_createSupportRequestEvent(SlapOSTestCaseMixin): ...@@ -1341,8 +1107,7 @@ class TestSlapOSInstanceTree_createSupportRequestEvent(SlapOSTestCaseMixin):
return notification_message.getRelativeUrl() return notification_message.getRelativeUrl()
def _makeInstanceTree(self): def _makeInstanceTree(self):
person = self.portal.person_module.template_member\ person = self.makePerson(user=1)
.Base_createCloneDocument(batch_mode=1)
instance_tree = self.portal\ instance_tree = self.portal\
.instance_tree_module.template_instance_tree\ .instance_tree_module.template_instance_tree\
.Base_createCloneDocument(batch_mode=1) .Base_createCloneDocument(batch_mode=1)
...@@ -1371,12 +1136,6 @@ class TestSlapOSInstanceTree_createSupportRequestEvent(SlapOSTestCaseMixin): ...@@ -1371,12 +1136,6 @@ class TestSlapOSInstanceTree_createSupportRequestEvent(SlapOSTestCaseMixin):
'assert reference == "test-slapos-crm-check.notification"\n' \ 'assert reference == "test-slapos-crm-check.notification"\n' \
'return context.restrictedTraverse(' \ 'return context.restrictedTraverse(' \
'context.REQUEST["testInstanceTree_createSupportRequestEvent"])') 'context.REQUEST["testInstanceTree_createSupportRequestEvent"])')
@simulate('SupportRequest_trySendNotificationMessage',
'message_title, message, destination_relative_url',
'context.portal_workflow.doActionFor(' \
'context, action="edit_action", ' \
'comment="Visited by SupportRequest_trySendNotificationMessage ' \
'%s %s %s" % (message_title, message, destination_relative_url))')
def testInstanceTree_createSupportRequestEvent(self): def testInstanceTree_createSupportRequestEvent(self):
instance_tree = self._makeInstanceTree() instance_tree = self._makeInstanceTree()
person = instance_tree.getDestinationSectionValue() person = instance_tree.getDestinationSectionValue()
...@@ -1392,12 +1151,14 @@ class TestSlapOSInstanceTree_createSupportRequestEvent(SlapOSTestCaseMixin): ...@@ -1392,12 +1151,14 @@ class TestSlapOSInstanceTree_createSupportRequestEvent(SlapOSTestCaseMixin):
instance_tree.getUid()) instance_tree.getUid())
self.assertNotEqual(ticket, None) self.assertNotEqual(ticket, None)
self.assertEqual(ticket.getSimulationState(), "validated") self.assertEqual(ticket.getSimulationState(), "validated")
self.assertEqual('Visited by SupportRequest_trySendNotificationMessage ' \ self.assertNotEqual(ticket, None)
'%s %s %s' % ( \ event_list = ticket.getFollowUpRelatedValueList()
ticket_title, self.assertEqual(len(event_list), 1)
'Test NM content\n%s\n' % instance_tree.getReference(), event = event_list[0]
person.getRelativeUrl()),
ticket.workflow_history['edit_workflow'][-1]['comment']) self.assertEqual(event.getTitle(), ticket_title)
self.assertIn(instance_tree.getReference(), event.getTextContent())
self.assertEqual(event.getDestination(), person.getRelativeUrl())
ticket.suspend() ticket.suspend()
self.tic() self.tic()
...@@ -1734,95 +1495,6 @@ class TestSlapOSHasError(SlapOSTestCaseMixin): ...@@ -1734,95 +1495,6 @@ class TestSlapOSHasError(SlapOSTestCaseMixin):
None, None,
instance_tree.InstanceTree_checkSoftwareInstanceState()) instance_tree.InstanceTree_checkSoftwareInstanceState())
class TestSupportRequestTrySendNotificationMessage(SlapOSTestCaseMixin):
def test_SupportRequest_trySendNotificationMessage(self):
self._makeComputeNode(owner=self.makePerson(user=0))
person = self.compute_node.getSourceAdministrationValue()
title = "Test Support Request %s" % self.compute_node.getReference()
text_content='Test NM content<br/>%s<br/>' % self.compute_node.getReference()
support_request = self.portal.support_request_module.newContent(\
title=title, description=title,
destination_decision=self.compute_node.getSourceAdministration(),
aggregate_value=self.compute_node.getRelativeUrl())
support_request.validate()
self.tic()
first_event = support_request.SupportRequest_trySendNotificationMessage(
message_title=title, message=text_content,
destination_relative_url=person.getRelativeUrl()
)
self.assertNotEqual(first_event, None)
self.tic()
self.assertEqual(
support_request.getFollowUpRelatedList(),
[first_event.getRelativeUrl()])
self.assertEqual(title, first_event.getTitle())
self.assertEqual(text_content, first_event.getTextContent())
self.assertNotEqual(None, first_event.getStartDate())
self.assertEqual("service_module/slapos_crm_information",
first_event.getResource())
self.assertEqual(first_event.getDestination(), person.getRelativeUrl())
self.assertEqual(first_event.getFollowUp(), support_request.getRelativeUrl())
event = support_request.SupportRequest_trySendNotificationMessage(
message_title=title, message=text_content,
destination_relative_url=person.getRelativeUrl()
)
self.assertEqual(event, first_event)
self.assertEqual(title, event.getTitle())
self.assertEqual(text_content, event.getTextContent())
self.assertNotEqual(None, event.getStartDate())
self.assertEqual("service_module/slapos_crm_information",
event.getResource())
self.assertEqual(event.getDestination(), person.getRelativeUrl())
title += "__zz"
event = support_request.SupportRequest_trySendNotificationMessage(
message_title=title, message=text_content,
destination_relative_url=person.getRelativeUrl(),
)
self.assertEqual(event.getTitle(), title)
self.assertEqual(text_content, event.getTextContent())
self.assertNotEqual(None, event.getStartDate())
self.assertEqual("service_module/slapos_crm_information",
event.getResource())
self.assertEqual(event.getDestination(), person.getRelativeUrl())
another_support_request = self.portal.support_request_module.newContent(\
title=title, description=title,
destination_decision=self.compute_node.getSourceAdministration(),
aggregate_value=self.compute_node.getRelativeUrl())
another_support_request.validate()
self.tic()
another_first_event = \
another_support_request.SupportRequest_trySendNotificationMessage(
message_title=title, message=text_content,
destination_relative_url=person.getRelativeUrl())
self.assertNotEqual(another_first_event, None)
self.tic()
self.assertEqual(
another_support_request.getFollowUpRelatedList(),
[another_first_event.getRelativeUrl()])
self.assertEqual(title, another_first_event.getTitle())
self.assertEqual(text_content, another_first_event.getTextContent())
self.assertNotEqual(None, another_first_event.getStartDate())
self.assertEqual("service_module/slapos_crm_information",
another_first_event.getResource())
self.assertEqual(another_first_event.getDestination(), person.getRelativeUrl())
self.assertEqual(another_first_event.getFollowUp(),
another_support_request.getRelativeUrl())
class TestSupportRequestUpdateMonitoringState(SlapOSTestCaseMixin): class TestSupportRequestUpdateMonitoringState(SlapOSTestCaseMixin):
def _makeInstanceTree(self): def _makeInstanceTree(self):
...@@ -1873,10 +1545,6 @@ class TestSupportRequestUpdateMonitoringState(SlapOSTestCaseMixin): ...@@ -1873,10 +1545,6 @@ class TestSupportRequestUpdateMonitoringState(SlapOSTestCaseMixin):
support_request.SupportRequest_updateMonitoringState()) support_request.SupportRequest_updateMonitoringState())
@simulate('ERP5Site_isSupportRequestCreationClosed', '','return 0') @simulate('ERP5Site_isSupportRequestCreationClosed', '','return 0')
@simulate('SupportRequest_trySendNotificationMessage',
"message_title, message, source_relative_url",
"""assert "destroyed" in message
return "Visited by SupportRequest_trySendNotificationMessage %s %s" % (message_title, source_relative_url)""")
def testSupportRequest_updateMonitoringDestroyRequestedState(self): def testSupportRequest_updateMonitoringDestroyRequestedState(self):
support_request = self._makeSupportRequest() support_request = self._makeSupportRequest()
self.assertEqual(None, self.assertEqual(None,
...@@ -1887,20 +1555,29 @@ return "Visited by SupportRequest_trySendNotificationMessage %s %s" % (message_t ...@@ -1887,20 +1555,29 @@ return "Visited by SupportRequest_trySendNotificationMessage %s %s" % (message_t
support_request.setAggregateValue( support_request.setAggregateValue(
self._makeComputeNode(owner=self.makePerson(user=0))[0]) self._makeComputeNode(owner=self.makePerson(user=0))[0])
support_request.setDestinationDecisionValue(self.makePerson(user=0))
self.assertEqual(None, self.assertEqual(None,
support_request.SupportRequest_updateMonitoringDestroyRequestedState()) support_request.SupportRequest_updateMonitoringDestroyRequestedState())
hs = self._makeInstanceTree() hs = self._makeInstanceTree()
support_request.setAggregateValue(hs) support_request.setAggregateValue(hs)
self.tic()
hs.getSlapState = getFakeSlapState hs.getSlapState = getFakeSlapState
self.commit() self.commit()
support_request.setDestinationDecisionValue(self.makePerson(user=0)) self.assertNotEqual(None,
expected_text = """Visited by SupportRequest_trySendNotificationMessage Instance Tree was destroyed was destroyed by the user %s""" % support_request.getDestinationDecision()
self.assertEqual(expected_text,
support_request.SupportRequest_updateMonitoringDestroyRequestedState()) support_request.SupportRequest_updateMonitoringDestroyRequestedState())
self.tic()
event_list = support_request.getFollowUpRelatedValueList()
self.assertEqual(len(event_list), 1)
event = event_list[0]
self.assertEqual(event.getTitle(), 'Instance Tree was destroyed was destroyed by the user')
self.assertEqual(event.getDestination(), support_request.getDestinationDecision())
self.assertEqual("invalidated", self.assertEqual("invalidated",
support_request.getSimulationState()) support_request.getSimulationState())
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2002-2012 Nexedi SA and Contributors. All Rights Reserved.
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin #, simulate
import transaction
class TestSlapOSCoreTicketSlapInterfaceWorkflow(SlapOSTestCaseMixin):
def afterSetUp(self):
SlapOSTestCaseMixin.afterSetUp(self)
portal = self.getPortalObject()
self.ticket_trade_condition = portal.sale_trade_condition_module.slapos_ticket_trade_condition
person_user = self.makePerson()
self.tic()
# Login as new user
self.login(person_user.getUserId())
new_person = self.portal.portal_membership.getAuthenticatedMember().getUserValue()
self.assertEqual(person_user.getRelativeUrl(), new_person.getRelativeUrl())
self.support_request = portal.support_request_module.newContent(
portal_type="Support Request",
destination_decision=person_user.getRelativeUrl(),
specialise=self.ticket_trade_condition.getRelativeUrl()
)
# Value set by the init
self.assertTrue(self.support_request.getReference().startswith("SR-"),
"Reference don't start with SR- : %s" % self.support_request.getReference())
def beforeTearDown(self):
transaction.abort()
def test_SupportRequest_approveRegistration_no_reference(self):
self.support_request.setReference(None)
self.assertRaises(ValueError, self.support_request.approveRegistration)
def test_SupportRequest_approveRegistration_already_validated(self):
# Login as admin since user cannot re-approve a validated project
self.login()
self.support_request.validate()
# Don't raise if support request is validated
self.assertEqual(self.support_request.approveRegistration(), None)
def test_SupportRequest_approveRegistration(self):
person = self.portal.portal_membership.getAuthenticatedMember().getUserValue()
self.support_request.approveRegistration()
self.tic()
self.logout()
self.login(person.getUserId())
self.assertEqual(self.support_request.getSimulationState(),
'validated')
self.assertEqual(self.support_request.getSourceSection(),
self.ticket_trade_condition.getSourceSection())
self.assertEqual(self.support_request.getSourceTrade(),
self.ticket_trade_condition.getSourceSection())
self.assertEqual(self.support_request.getSource(),
self.ticket_trade_condition.getSource())
self.assertNotEqual(self.support_request.getStartDate(),
None)
event = self.support_request.getCausalityValue()
self.assertNotEqual(event, None)
event_relative_url = self.support_request.REQUEST.get("event_relative_url")
self.assertEqual(event.getRelativeUrl(), event_relative_url)
self.assertEqual(event.getTitle(), self.support_request.getTitle())
def test_SupportRequest_requestEvent_noParameter(self):
self.assertRaises(TypeError, self.support_request.requestEvent)
self.assertRaises(TypeError, self.support_request.requestEvent, event_title="A")
self.assertRaises(TypeError, self.support_request.requestEvent, event_content="A")
def test_SupportRequest_requestEvent(self):
person = self.portal.portal_membership.getAuthenticatedMember().getUserValue()
self.support_request.approveRegistration()
self.tic()
self.logout()
self.login(person.getUserId())
self.support_request.requestEvent(
event_title="A",
event_content="B"
)
self.tic()
event_relative_url = self.support_request.REQUEST.get("event_relative_url")
event = self.portal.restrictedTraverse(event_relative_url)
self.assertEqual(event.getSimulationState(), "stopped")
self.assertEqual(self.support_request.getSimulationState(),
'validated')
self.assertEqual(self.support_request.getDestinationDecision(),
event.getSource())
self.assertEqual(person, event.getSourceValue())
self.assertEqual(self.support_request.getResource(),
event.getResource())
self.assertEqual(self.support_request,
event.getFollowUpValue())
self.assertEqual(event.getTitle(), "A")
self.assertEqual(event.getTextContent(), "B")
self.assertEqual(event.getContentType(), "text/plain")
self.assertEqual(event.getPortalType(), "Web Message")
self.assertEqual(event.getDestination(),
self.support_request.getSource())
def test_SupportRequest_notify_noParameter(self):
self.assertRaises(TypeError, self.support_request.notify)
self.assertRaises(TypeError, self.support_request.notify, message_title="A")
self.assertRaises(TypeError, self.support_request.notify, message="A")
self.assertRaises(TypeError, self.support_request.notify, destination_relative_url="A")
def test_SupportRequest_notify(self):
person = self.portal.portal_membership.getAuthenticatedMember().getUserValue()
self.support_request.approveRegistration()
self.tic()
self.logout()
self.login()
self.support_request.notify(
message_title="A",
message="B")
event = self.support_request.REQUEST.get("ticket_notified_item")
self.assertEqual(event.getSimulationState(), "delivered")
self.assertEqual(self.support_request.getSimulationState(),
'validated')
self.assertEqual(self.support_request.getDestinationDecision(),
event.getDestination())
self.assertEqual(person, event.getDestinationValue())
self.assertEqual("service_module/slapos_crm_information",
event.getResource())
self.assertEqual(self.support_request,
event.getFollowUpValue())
self.assertEqual(event.getTitle(), "A")
self.assertEqual(event.getTextContent(), "B")
self.assertEqual(event.getContentType(), "text/html")
self.assertEqual(event.getPortalType(), "Web Message")
self.assertEqual(event.getSource(),
self.support_request.getSource())
# Retry now to see if doesn't create a new message
self.support_request.notify(
message_title="A",
message="B")
self.tic()
self.assertEqual(event,
self.support_request.REQUEST.get("ticket_notified_item"))
# Retry, now it must create a new one
self.support_request.notify(
message_title="C",
message="B")
self.tic()
self.assertNotEqual(event,
self.support_request.REQUEST.get("ticket_notified_item"))
# Remove completly the ticket_notified_item and try to create a new one
# It should find it anyway from catalog.
self.support_request.REQUEST.set("ticket_notified_item", None)
self.commit()
# Retry, now it must create a new one
self.support_request.notify(
message_title="A",
message="B")
self.tic()
self.assertEqual(event,
self.support_request.REQUEST.get("ticket_notified_item"))
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Test Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testSlapOSCloudTicketSlapInterfaceWorkflow</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test.erp5.testSlapOSCloudTicketSlapInterfaceWorkflow</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Test Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_count</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_mt_index</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>_tree</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>source/portal_workflow/ticket_slap_interface_workflow/state_draft</string>
</tuple>
</value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>person_slap_interface_workflow</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ticket_slap_interface_workflow</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>manager_bypass</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow</string> </value>
</item>
<item>
<key> <string>state_variable</string> </key>
<value> <string>slap_state</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Ticket Slap Interface Workflow</string> </value>
</item>
<item>
<key> <string>workflow_managed_permission</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Length" module="BTrees.Length"/>
</pickle>
<pickle> <int>0</int> </pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
</ZopeData>
ticket = state_object["object"] ticket = state_change["object"]
from DateTime import DateTime from DateTime import DateTime
portal = context.getPortalObject() portal = context.getPortalObject()
# XXX unhardcode the trade condition, by adding a preference if ticket.getSimulationState() != "draft":
if ticket.getSpecialise() != "sale_trade_condition_module/slapos_ticket_trade_condition":
return return
if ticket.getSimulationState() != "draft": if ticket.getReference() in [None, ""]:
raise ValueError("Reference is missing on the Ticket")
# Get the user id of the context owner.
local_role_list = ticket.get_local_roles()
for group, role_list in local_role_list:
if 'Owner' in role_list:
user_id = group
break
person = portal.portal_catalog.getResultValue(user_id=user_id)
if person is None:
# Value was created by super user, so there isn't a point on continue
return return
ticket.validate() # XXX unhardcode the trade condition, by adding a preference
if ticket.getSpecialise() != "sale_trade_condition_module/slapos_ticket_trade_condition":
return
trade_condition = portal.sale_trade_condition_module.slapos_ticket_trade_condition trade_condition = portal.sale_trade_condition_module.slapos_ticket_trade_condition
web_message = context.Ticket_createInitialEvent(state_object)
ticket.edit( ticket.edit(
source_section = trade_condition.getSourceSection(), source_section=trade_condition.getSourceSection(),
source_trade=trade_condition.getSourceSection(), source_trade=trade_condition.getSourceSection(),
source=trade_condition.getSource(), source=trade_condition.getSource())
causality_value=web_message)
ticket.setStartDate(DateTime()) ticket.setStartDate(DateTime())
# Copy original post into the original message. ticket.requestEvent(
web_message.edit( event_title=ticket.getTitle(),
title=ticket.getTitle(), event_content=ticket.getDescription()
# content_type="text/plain",
text_content=ticket.getDescription(),
source=ticket.getDestinationDecision(),
# destination=trade_condition.getSource(),
# resource=ticket.getResource(),
# start_date=DateTime(),
follow_up_value=ticket,
) )
event_relative_url = context.REQUEST.get("event_relative_url")
ticket.setCausality(event_relative_url)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_Ticket_approveRegistration</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Ticket_approveRegistration</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>state_object</string> </value> <value> <string>state_change</string> </value>
</item> </item>
<item> <item>
<key> <string>description</string> </key> <key> <string>description</string> </key>
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>script_Ticket_createInitialEvent</string> </value> <value> <string>script_Ticket_checkConsistency</string> </value>
</item> </item>
<item> <item>
<key> <string>portal_type</string> </key> <key> <string>portal_type</string> </key>
......
ticket = state_change["object"]
from DateTime import DateTime
portal = ticket.getPortalObject()
# Get required arguments
kwargs = state_change.kwargs
# Required args
# Raise TypeError if all parameters are not provided
try:
message_title = kwargs['message_title']
message = kwargs['message']
except KeyError:
raise TypeError("Ticket_notify takes exactly 2 arguments")
resource = portal.service_module.slapos_crm_information.getRelativeUrl()
# create Web message if needed for this ticket
last_event = ticket.portal_catalog.getResultValue(
title=message_title,
follow_up_uid=ticket.getUid(),
sort_on=[('delivery.start_date', 'DESC')],
)
if last_event:
# User has already been notified for this problem.
ticket.REQUEST.set("ticket_notified_item", last_event)
return
transactional_event = ticket.REQUEST.get("ticket_notified_item", None)
if transactional_event is not None:
if (transactional_event.getFollowUpUid() == ticket.getUid()) and \
(transactional_event.getTitle() == message_title):
ticket.REQUEST.set("ticket_notified_item", transactional_event)
return
template = portal.restrictedTraverse(
portal.portal_preferences.getPreferredWebMessageTemplate())
event = template.Base_createCloneDocument(batch_mode=1)
event.edit(
title=message_title,
text_content=message,
start_date = DateTime(),
resource = resource,
source=ticket.getSource(),
destination=ticket.getDestinationDecision(),
follow_up=ticket.getRelativeUrl(),
)
event.stop()
event.deliver()
ticket.serialize()
ticket.REQUEST.set("ticket_notified_item", event)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_Ticket_notify</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Ticket_notify</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
ticket = state_change["object"]
from DateTime import DateTime
portal = context.getPortalObject()
# Get required arguments
kwargs = state_change.kwargs
# Required args
# Raise TypeError if all parameters are not provided
try:
title = kwargs['event_title']
text_content = kwargs['event_content']
except KeyError:
raise TypeError, "Ticket_requestEvent takes exactly 2 argument"
web_message = portal.event_module.newContent(
portal_type="Web Message",
title=title,
text_content=text_content,
source=ticket.getDestinationDecision(),
content_type="text/plain",
destination=ticket.getSource(),
resource=ticket.getResource(),
follow_up=ticket.getRelativeUrl()
)
web_message.stop(comment="Submitted from the renderjs app")
if portal.portal_workflow.isTransitionPossible(ticket, "validate"):
ticket.validate(comment="See %s" % web_message.getRelativeUrl())
ticket.REQUEST.set("event_relative_url", web_message.getRelativeUrl())
...@@ -50,13 +50,14 @@ ...@@ -50,13 +50,14 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>state_object</string> </value> <value> <string>state_change</string> </value>
</item> </item>
<item> <item>
<key> <string>_proxy_roles</string> </key> <key> <string>_proxy_roles</string> </key>
<value> <value>
<tuple> <tuple>
<string>Assignor</string> <string>Assignor</string>
<string>Owner</string>
</tuple> </tuple>
</value> </value>
</item> </item>
...@@ -68,7 +69,7 @@ ...@@ -68,7 +69,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>script_SupportRequest_createInitialWebMessage</string> </value> <value> <string>script_Ticket_requestEvent</string> </value>
</item> </item>
<item> <item>
<key> <string>portal_type</string> </key> <key> <string>portal_type</string> </key>
...@@ -76,9 +77,7 @@ ...@@ -76,9 +77,7 @@
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <value> <string>Ticket_requestEvent</string> </value>
<none/>
</value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow State" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>acquire_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>destination/portal_workflow/ticket_slap_interface_workflow/transition_approve_registration</string>
<string>destination/portal_workflow/ticket_slap_interface_workflow/transition_notify</string>
<string>destination/portal_workflow/ticket_slap_interface_workflow/transition_request_event</string>
</tuple>
</value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>state_draft</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow State</string> </value>
</item>
<item>
<key> <string>state_permission_role_list_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>state_type</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Draft</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Transition" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/ticket_slap_interface_workflow/script_Ticket_checkConsistency</string>
<string>after_script/portal_workflow/ticket_slap_interface_workflow/script_Ticket_approveRegistration</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_approve_registration</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Approve Registration</string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Transition" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/ticket_slap_interface_workflow/script_Ticket_checkConsistency</string>
<string>after_script/portal_workflow/ticket_slap_interface_workflow/script_Ticket_notify</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_notify</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Notify</string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Transition" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/ticket_slap_interface_workflow/script_Ticket_checkConsistency</string>
<string>after_script/portal_workflow/ticket_slap_interface_workflow/script_Ticket_requestEvent</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_request_event</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Request Event</string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>The last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_action</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>transition/getReference|nothing</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>The name of the user who performed the last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_actor</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>user/getUserName</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Comments about the last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_comment</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>python:state_change.kwargs.get(\'comment\', \'\')</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Error message if validation failed</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_error_message</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Provides access to workflow history</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_history</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>state_change/getHistory</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>portal type (use as filter for worklists)</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_portal_type</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Time of the last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_time</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>state_change/getDateTime</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -32,6 +32,12 @@ ...@@ -32,6 +32,12 @@
</tuple> </tuple>
</value> </value>
</item> </item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>ticket_workflow</string> </value> <value> <string>ticket_workflow</string> </value>
......
...@@ -3,4 +3,5 @@ Incident Response | ticket_workflow ...@@ -3,4 +3,5 @@ Incident Response | ticket_workflow
Regularisation Request | edit_workflow Regularisation Request | edit_workflow
Regularisation Request | pricing_interaction_workflow Regularisation Request | pricing_interaction_workflow
Regularisation Request | ticket_interaction_workflow Regularisation Request | ticket_interaction_workflow
Regularisation Request | ticket_workflow Regularisation Request | ticket_workflow
\ No newline at end of file Support Request | ticket_slap_interface_workflow
\ No newline at end of file
test.erp5.testSlapOSCRMSkins test.erp5.testSlapOSCRMSkins
test.erp5.testSlapOSCRMRegularisationRequestSkins test.erp5.testSlapOSCRMRegularisationRequestSkins
test.erp5.testSlapOSCRMAlarm test.erp5.testSlapOSCRMAlarm
\ No newline at end of file test.erp5.testSlapOSCloudTicketSlapInterfaceWorkflow
\ No newline at end of file
ticket_slap_interface_workflow
ticket_workflow ticket_workflow
\ No newline at end of file
...@@ -123,14 +123,6 @@ ...@@ -123,14 +123,6 @@
<type>Software Instance</type> <type>Software Instance</type>
<workflow>local_permission_slapos_interaction_workflow</workflow> <workflow>local_permission_slapos_interaction_workflow</workflow>
</chain> </chain>
<chain>
<type>Support Request</type>
<workflow>slapos_erp5_interaction_workflow</workflow>
</chain>
<chain>
<type>Web Message</type>
<workflow>slapos_erp5_interaction_workflow</workflow>
</chain>
<chain> <chain>
<type>Wechat Event</type> <type>Wechat Event</type>
<workflow>local_permission_slapos_interaction_workflow</workflow> <workflow>local_permission_slapos_interaction_workflow</workflow>
......
# Added this script to be running as Owner
portal = context.getPortalObject()
return portal.event_module.newContent(
portal_type="Web Message",
)
web_message = state_object["object"]
portal = context.getPortalObject()
person = portal.portal_membership.getAuthenticatedMember().getUserValue()
if person is None:
return
if web_message.getSimulationState() != "draft":
return
if not web_message.hasStartDate():
web_message.setStartDate(DateTime())
# The user isn't the customer, so it is not comming from the user
# interface.
ticket = web_message.getFollowUpValue()
if ticket.getDestinationDecision() != person.getRelativeUrl():
return
# The user isn't the sender, so it is not comming from UI, but from
# an alarm.
source = web_message.getSource()
if source != person.getRelativeUrl():
return
edit_kw = {"content_type":"text/plain"}
# Copy destination and resource from ticket.
if web_message.getDestination() is None:
edit_kw["destination"] = ticket.getSource()
if web_message.getResource() is None:
edit_kw["resource"] = ticket.getResource()
web_message.edit(**edit_kw)
web_message.stop(comment="Submitted from the renderjs app")
if portal.portal_workflow.isTransitionPossible(ticket, "validate"):
ticket.validate(comment="See %s" % web_message.getRelativeUrl())
...@@ -34,6 +34,4 @@ Sale Packing List | local_permission_slapos_interaction_workflow ...@@ -34,6 +34,4 @@ Sale Packing List | local_permission_slapos_interaction_workflow
Slave Instance | local_permission_slapos_interaction_workflow Slave Instance | local_permission_slapos_interaction_workflow
Software Installation | local_permission_slapos_interaction_workflow Software Installation | local_permission_slapos_interaction_workflow
Software Instance | local_permission_slapos_interaction_workflow Software Instance | local_permission_slapos_interaction_workflow
Support Request | slapos_erp5_interaction_workflow
Web Message | slapos_erp5_interaction_workflow
Wechat Event | local_permission_slapos_interaction_workflow Wechat Event | local_permission_slapos_interaction_workflow
\ No newline at end of file
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
.declareAcquiredMethod("updatePanel", "updatePanel") .declareAcquiredMethod("updatePanel", "updatePanel")
.declareAcquiredMethod("jio_getAttachment", "jio_getAttachment") .declareAcquiredMethod("jio_getAttachment", "jio_getAttachment")
.declareAcquiredMethod("getSetting", "getSetting") .declareAcquiredMethod("getSetting", "getSetting")
.declareAcquiredMethod("getSettingList", "getSettingList")
.declareAcquiredMethod("getUrlFor", "getUrlFor") .declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("redirect", "redirect") .declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("jio_post", "jio_post") .declareAcquiredMethod("jio_putAttachment", "jio_putAttachment")
.declareAcquiredMethod("jio_get", "jio_get") .declareAcquiredMethod("jio_get", "jio_get")
.declareAcquiredMethod("notifySubmitting", "notifySubmitting") .declareAcquiredMethod("notifySubmitting", "notifySubmitting")
.declareAcquiredMethod("notifySubmitted", 'notifySubmitted') .declareAcquiredMethod("notifySubmitted", 'notifySubmitted')
...@@ -26,6 +27,7 @@ ...@@ -26,6 +27,7 @@
return this.triggerSubmit(); return this.triggerSubmit();
}) })
.onEvent('submit', function () { .onEvent('submit', function () {
var gadget = this; var gadget = this;
return gadget.notifySubmitting() return gadget.notifySubmitting()
...@@ -33,28 +35,31 @@ ...@@ -33,28 +35,31 @@
return gadget.getDeclaredGadget('form_view'); return gadget.getDeclaredGadget('form_view');
}) })
.push(function (form_gadget) { .push(function (form_gadget) {
return form_gadget.getContent(); return RSVP.all([form_gadget.getContent(),
gadget.getSettingList(['me', 'hateoas_url'])]);
}) })
.push(function (content) { .push(function (result) {
var property, doc = {}; var doc = result[0],
for (property in content) { me = result[1][0],
if ((content.hasOwnProperty(property)) && url = result[1][1];
// Remove undefined keys added by Gadget fields return gadget.jio_putAttachment(me,
(property !== "undefined") && url + me + "/Person_requestSupport",
// Remove default_*:int keys added by ListField {title: doc.title,
!(property.endsWith(":int") && property.startsWith("default_"))) { description: doc.description,
doc[property] = content[property]; resource: doc.resource});
}
}
return gadget.jio_post(doc);
}) })
.push(function (key) { .push(function (attachment) {
return jIO.util.readBlobAsText(attachment.target.response);
})
.push(function (response) {
return JSON.parse(response.target.result);
})
.push(function (result) {
return gadget.notifySubmitted({message: gadget.message_translation, status: 'success'}) return gadget.notifySubmitted({message: gadget.message_translation, status: 'success'})
.push(function () { .push(function () {
// Workaround, find a way to open document without break gadget. // Workaround, find a way to open document without break gadget.
return gadget.redirect({"command": "change", return gadget.redirect({"command": "change",
"options": {"jio_key": key, "page": "slap_controller"}}); "options": {"jio_key": result.relative_url, "page": "slap_controller"}});
}); });
}); });
}) })
...@@ -88,20 +93,19 @@ ...@@ -88,20 +93,19 @@
gadget.getDeclaredGadget('form_view'), gadget.getDeclaredGadget('form_view'),
gadget.jio_getAttachment("ticket_resource_list", gadget.jio_getAttachment("ticket_resource_list",
hateoas_url + "Ticket_getResourceItemListAsJSON"), hateoas_url + "Ticket_getResourceItemListAsJSON"),
window.getSettingMe(gadget),
gadget.getTranslationList(translation_list) gadget.getTranslationList(translation_list)
]); ]);
}) })
.push(function (result) { .push(function (result) {
gadget.message_translation = result[3][0]; gadget.message_translation = result[2][0];
page_title_translation = result[3][10]; page_title_translation = result[2][10];
return result[0].render({ return result[0].render({
erp5_document: { erp5_document: {
"_embedded": {"_view": { "_embedded": {"_view": {
"my_title": { "my_title": {
"description": result[3][1], "description": result[2][1],
"title": result[3][2], "title": result[2][2],
"default": "", "default": "",
"css_class": "", "css_class": "",
"required": 1, "required": 1,
...@@ -112,7 +116,7 @@ ...@@ -112,7 +116,7 @@
}, },
"my_description": { "my_description": {
"description": "", "description": "",
"title": result[3][3], "title": result[2][3],
"default": "", "default": "",
"css_class": "", "css_class": "",
"required": 1, "required": 1,
...@@ -122,8 +126,8 @@ ...@@ -122,8 +126,8 @@
"type": "TextAreaField" "type": "TextAreaField"
}, },
"my_resource": { "my_resource": {
"description": result[3][0], "description": result[2][0],
"title": result[3][4], "title": result[2][4],
"default": "", "default": "",
"items": result[1], "items": result[1],
"css_class": "", "css_class": "",
...@@ -132,52 +136,6 @@ ...@@ -132,52 +136,6 @@
"key": "resource", "key": "resource",
"hidden": 0, "hidden": 0,
"type": "ListField" "type": "ListField"
},
"my_destination_decision": {
"description": result[3][0],
"title": result[3][5],
"default": result[2],
"css_class": "",
"required": 1,
"editable": 1,
"key": "destination_decision",
"hidden": 1,
"type": "StringField"
},
"my_specialise": {
"description": "",
"title": result[3][6],
// Auto Set a hardcoded trade Condition
// Please replace it by a getSetting.
"default": "sale_trade_condition_module/slapos_ticket_trade_condition",
"css_class": "",
"required": 1,
"editable": 1,
"key": "specialise",
"hidden": 1,
"type": "StringField"
},
"my_portal_type": {
"description": result[3][0],
"title": result[3][7],
"default": "Support Request",
"css_class": "",
"required": 1,
"editable": 1,
"key": "portal_type",
"hidden": 1,
"type": "StringField"
},
"my_parent_relative_url": {
"description": "",
"title": result[3][9],
"default": "support_request_module",
"css_class": "",
"required": 1,
"editable": 1,
"key": "parent_relative_url",
"hidden": 1,
"type": "StringField"
} }
}}, }},
"_links": { "_links": {
...@@ -193,7 +151,7 @@ ...@@ -193,7 +151,7 @@
[["my_resource"]] [["my_resource"]]
], [ ], [
"center", "center",
[["my_title"], ["my_description"], ["my_specialise"], ["my_destination_decision"], ["my_portal_type"], ["my_parent_relative_url"]] [["my_title"], ["my_description"]]
]] ]]
} }
}); });
......
...@@ -279,7 +279,7 @@ ...@@ -279,7 +279,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>987.11835.35244.22135</string> </value> <value> <string>997.18055.28455.10120</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -297,7 +297,7 @@ ...@@ -297,7 +297,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1602260862.83</float> <float>1641264462.37</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
import json
portal = context.getPortalObject()
person = portal.portal_membership.getAuthenticatedMember().getUserValue()
request = context.REQUEST
response = request.RESPONSE
if person is None:
response.setStatus(403)
else:
request_kw = {"support_request_title": title,
"support_request_description": description,
"support_request_resource": resource,
"support_request_aggregate": aggregate}
person.requestSupport(**request_kw)
support_relative_url = request.get('support_request_relative_url')
response.setHeader('Content-Type', "application/json")
return json.dumps({
"relative_url": support_relative_url
})
...@@ -50,11 +50,11 @@ ...@@ -50,11 +50,11 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string></string> </value> <value> <string>title, description, resource, aggregate=None</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>UpgradeDecision_getComputeNode</string> </value> <value> <string>Person_requestSupport</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -2,14 +2,10 @@ ...@@ -2,14 +2,10 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/> <global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item> <item>
<key> <string>_bind_names</string> </key> <key> <string>_bind_names</string> </key>
<value> <value>
...@@ -24,18 +20,6 @@ ...@@ -24,18 +20,6 @@
<key> <string>_asgns</string> </key> <key> <string>_asgns</string> </key>
<value> <value>
<dictionary> <dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item> <item>
<key> <string>name_subpath</string> </key> <key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value> <value> <string>traverse_subpath</string> </value>
...@@ -49,12 +33,24 @@ ...@@ -49,12 +33,24 @@
</value> </value>
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>content_type</string> </key>
<value> <string></string> </value> <value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>UpgradeDecision_getInstanceTree</string> </value> <value> <string>testSlapOSJSServerTicketRelated</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
<html xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:metal="http://xml.zope.org/namespaces/metal">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test SlapOS JS Server</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr>
<td rowspan="1" colspan="3">Test SlapOS JS Server Add related Ticket</td>
</tr>
</thead>
<tbody>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_init" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/set_default_available_language"/>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_login" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_front_page" />
<tal:block define="document_title python: 'TEST-SLAPOSJS-COMPUTER 0';">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/create_simple_compute_node" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
<tal:block define="menu_item python: 'Servers'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '1'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
<td></td>
</tr>
<tal:block tal:define="header python: 'Compute Node: ${title}';
dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-COMPUTER 0'}) ">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
</tal:block>
<tr>
<td colspan="3"><b tal:content="python: 'Add an Support Request'"> Menu Item </b></td>
</tr>
<tal:block define="menu_action python: 'Add Ticket'">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_submenu_action" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//input[@id="title"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//input[@id="title"]</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@id="title"]</td>
<td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0</td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//textarea[@id="description"]</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//textarea[@id="description"]</td>
<td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED DESCRIPTION</td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//select[@id="resource"]</td>
<td></td>
</tr>
<tr>
<td>select</td>
<td>//select[@id="resource"]</td>
<td>Complaint</td>
</tr>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_proceed" />
<tal:block tal:define="notification_configuration python: {'class': 'success',
'text': 'New Ticket created.'}">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/wait_for_notification" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/wait_for_content_loaded" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
<tal:block define="menu_item python: 'Servers'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '1'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
<td></td>
</tr>
<tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '1'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0"]</td>
<td></td>
</tr>
<tal:block tal:define="header python: 'Support Request : ${title}';
dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '1'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
<td></td>
</tr>
<tr>
<td>verifyTextPresent</td>
<td>Demo User Functional</td>
<td></td>
</tr>
<tr>
<td>verifyTextPresent</td>
<td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0</td>
<td></td>
</tr>
<tr>
<td>verifyTextPresent</td>
<td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED DESCRIPTION</td>
<td></td>
</tr>
<tal:block tal:define="menu_action python: 'Add'">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_submenu_action" />
</tal:block>
<tal:block tal:define="header python: 'New Message'">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//textarea[@id="text_content"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//textarea[@id="text_content"]</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//textarea[@id="text_content"]</td>
<td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED NEW MESSAGE</td>
</tr>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_proceed" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/wait_for_content_loaded" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
<tal:block define="menu_item python: 'Servers'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '1'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
<td></td>
</tr>
<tal:block tal:define="header python: 'Compute Node: ${title}';
dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-COMPUTER 0'}) ">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '1'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0"]</td>
<td></td>
</tr>
<tal:block tal:define="header python: 'Support Request : ${title}';
dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(2)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '2'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
<td></td>
</tr>
<tr>
<td>verifyTextPresent</td>
<td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED NEW MESSAGE</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
<tal:block define="menu_item python: 'Servers'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '1'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
<td></td>
</tr>
<tal:block tal:define="header python: 'Compute Node: ${title}';
dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-COMPUTER 0'}) ">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
</tal:block>
<tr>
<td colspan="3"><b> Update Allocation Scope</b></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//select[@id="allocation_scope"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//select[@id="allocation_scope"]</td>
<td></td>
</tr>
<tr>
<td>select</td>
<td>//select[@id="allocation_scope"]</td>
<td tal:content="python: '%s' % (here.Base_translateString('Closed forever', lang=lang))"></td>
</tr>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/save" />
<tal:block define="menu_item python: 'Servers'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
<tal:block define="menu_item python: 'Servers'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(0)', 'footer': 'No records'}">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_logout" />
</tbody>
</table>
</body>
</html>
\ No newline at end of file
...@@ -2,14 +2,10 @@ ...@@ -2,14 +2,10 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/> <global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item> <item>
<key> <string>_bind_names</string> </key> <key> <string>_bind_names</string> </key>
<value> <value>
...@@ -24,18 +20,6 @@ ...@@ -24,18 +20,6 @@
<key> <string>_asgns</string> </key> <key> <string>_asgns</string> </key>
<value> <value>
<dictionary> <dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item> <item>
<key> <string>name_subpath</string> </key> <key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value> <value> <string>traverse_subpath</string> </value>
...@@ -49,12 +33,24 @@ ...@@ -49,12 +33,24 @@
</value> </value>
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>content_type</string> </key>
<value> <string></string> </value> <value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>UpgradeDecision_upgradeComputeNode</string> </value> <value> <string>testSlapOSJSServiceTicketRelated</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
<html xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:metal="http://xml.zope.org/namespaces/metal">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test SlapOS JS Service</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr>
<td rowspan="1" colspan="3">Test SlapOS JS Service</td>
</tr>
</thead>
<tbody>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_init" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/set_default_available_language"/>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_login" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_front_page" />
<tal:block define="menu_item python: 'Services'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(0)', 'footer': 'No records'}">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tal:block define="menu_action python: 'Add'">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_submenu_action" />
</tal:block>
<tr>
<td colspan="3"><b> Request a Software </b></td>
</tr>
<tal:block define="software_product python: 'Frontend'">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/select_software_product" />
</tal:block>
<tal:block define="software_release python: 'Frontend'">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/select_software_release" />
</tal:block>
<tr>
<td colspan="3"><b> Fill Request form </b></td>
</tr>
<tal:block tal:define="header python: '3/3 Request Service: ${title}';
dummy python: context.REQUEST.set('mapping', {'title': 'Frontend'}) ">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//input[@id="title"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//input[@id="title"]</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@id="title"]</td>
<td>TEST-SLAPOSJS-SERVICE-FRONTEND 0</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url,
'gadget_erp5_page_slap_parameter_form.html')]//select[@name="software_type"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url,
'gadget_erp5_page_slap_parameter_form.html')]//select[@name="software_type"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url,
'gadget_erp5_page_slap_parameter_form.html')]//select[@name="software_type"]//option[text()="Custom Personal"]
</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url,
'gadget_erp5_page_slap_parameter_form.html')]//select[@name="software_type"]//option[text()="Custom Personal"]
</td>
<td></td>
</tr>
<tr>
<td>select</td>
<td>//div[contains(@data-gadget-url,
'gadget_erp5_page_slap_parameter_form.html')]//select[@name="software_type"]</td>
<td>Custom Personal</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name="//domain"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//input[@name="//domain"]</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="//domain"]</td>
<td>www.erp5.com</td>
</tr>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_proceed" />
<tal:block tal:define="notification_configuration python: {'class': 'success',
'text': 'New service created.'}">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/wait_for_notification" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
<tal:block define="menu_item python: 'Services'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url,
'gadget_slapos_panel.html')]//img[contains(@src, 'gadget_slapos_panel.png?format=png')]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url,
'gadget_slapos_panel.html')]//img[contains(@src, 'gadget_slapos_panel.png?format=png')]</td>
<td></td>
</tr>
<tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '1'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
<td></td>
</tr>
<tr tal:define="dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SERVICE-FRONTEND 0'})">
<td>waitForElementPresent</td>
<td tal:content="python: '//a[@data-i18n= \'%s\']' % (here.Base_translateString('Instance Tree: ${title}', mapping=context.REQUEST.get('mapping', {}), lang=lang))"></td>
<td></td>
</tr>
<tr tal:define="dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SERVICE-FRONTEND 0'})">
<td>assertElementPresent</td>
<td tal:content="python: '//a[@data-i18n= \'%s\']' % (here.Base_translateString('Instance Tree: ${title}', mapping=context.REQUEST.get('mapping', {}), lang=lang))"></td>
<td></td>
</tr>
<tr>
<td colspan="3"><b tal:content="python: 'Add an Support Request'"> Menu Item </b></td>
</tr>
<tal:block define="menu_action python: 'Add Ticket'">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_submenu_action" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//input[@id="title"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//input[@id="title"]</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@id="title"]</td>
<td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0</td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//textarea[@id="description"]</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//textarea[@id="description"]</td>
<td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED DESCRIPTION</td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//select[@id="resource"]</td>
<td></td>
</tr>
<tr>
<td>select</td>
<td>//select[@id="resource"]</td>
<td>Complaint</td>
</tr>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_proceed" />
<tal:block tal:define="notification_configuration python: {'class': 'success',
'text': 'New Ticket created.'}">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/wait_for_notification" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/wait_for_content_loaded" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
<tal:block define="menu_item python: 'Services'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '1'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
<td></td>
</tr>
<tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '1'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0"]</td>
<td></td>
</tr>
<tal:block tal:define="header python: 'Support Request : ${title}';
dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '1'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
<td></td>
</tr>
<tr>
<td>verifyTextPresent</td>
<td>Demo User Functional</td>
<td></td>
</tr>
<tr>
<td>verifyTextPresent</td>
<td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0</td>
<td></td>
</tr>
<tr>
<td>verifyTextPresent</td>
<td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED DESCRIPTION</td>
<td></td>
</tr>
<tal:block tal:define="menu_action python: 'Add'">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_submenu_action" />
</tal:block>
<tal:block tal:define="header python: 'New Message'">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//textarea[@id="text_content"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//textarea[@id="text_content"]</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//textarea[@id="text_content"]</td>
<td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED NEW MESSAGE</td>
</tr>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_proceed" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/wait_for_content_loaded" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
<tal:block define="menu_item python: 'Services'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '1'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
<td></td>
</tr>
<tr tal:define="dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SERVICE-FRONTEND 0'})">
<td>waitForElementPresent</td>
<td tal:content="python: '//a[@data-i18n= \'%s\']' % (here.Base_translateString('Instance Tree: ${title}', mapping=context.REQUEST.get('mapping', {}), lang=lang))"></td>
<td></td>
</tr>
<tr tal:define="dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SERVICE-FRONTEND 0'})">
<td>assertElementPresent</td>
<td tal:content="python: '//a[@data-i18n= \'%s\']' % (here.Base_translateString('Instance Tree: ${title}', mapping=context.REQUEST.get('mapping', {}), lang=lang))"></td>
<td></td>
</tr>
<tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '1'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0"]</td>
<td></td>
</tr>
<tal:block tal:define="header python: 'Support Request : ${title}';
dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(2)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '2'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
<td></td>
</tr>
<tr>
<td>verifyTextPresent</td>
<td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED NEW MESSAGE</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
<tal:block define="menu_item python: 'Services'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '1'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
<td></td>
</tr>
<tr tal:define="dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SERVICE-FRONTEND 0'})">
<td>waitForElementPresent</td>
<td tal:content="python: '//a[@data-i18n= \'%s\']' % (here.Base_translateString('Instance Tree: ${title}', mapping=context.REQUEST.get('mapping', {}), lang=lang))"></td>
<td></td>
</tr>
<tr tal:define="dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SERVICE-FRONTEND 0'})">
<td>assertElementPresent</td>
<td tal:content="python: '//a[@data-i18n= \'%s\']' % (here.Base_translateString('Instance Tree: ${title}', mapping=context.REQUEST.get('mapping', {}), lang=lang))"></td>
<td></td>
</tr>
<tal:block define="menu_action python: 'Destroy'">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_submenu_action" />
</tal:block>
<tal:block tal:define="header python: 'Destroy Instance Tree: ${title}';
dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SERVICE-FRONTEND 0'}) ">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_proceed" />
<tal:block tal:define="notification_configuration python: {'class': 'success',
'text': 'Service is Destroyed.'}">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/wait_for_notification" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
<tal:block define="menu_item python: 'Services'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(0)', 'footer': 'No records'}">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_logout" />
</tbody>
</table>
</body>
</html>
\ No newline at end of file
...@@ -5,6 +5,6 @@ ...@@ -5,6 +5,6 @@
</chain> </chain>
<chain> <chain>
<type>Upgrade Decision</type> <type>Upgrade Decision</type>
<workflow>edit_workflow, ticket_interaction_workflow, upgrade_decision_workflow</workflow> <workflow>edit_workflow, ticket_interaction_workflow, upgrade_decision_workflow, upgrade_slap_interface_workflow</workflow>
</chain> </chain>
</workflow_chain> </workflow_chain>
\ No newline at end of file
portal = context.getPortalObject() portal = context.getPortalObject()
portal.portal_catalog.searchAndActivate( portal.portal_catalog.searchAndActivate(
portal_type="Upgrade Decision Line", portal_type="Upgrade Decision Line",
simulation_state=["confirmed", "draft", "planned"], simulation_state=["confirmed", "draft", "planned"],
......
...@@ -41,22 +41,18 @@ for software_release in software_release_list: ...@@ -41,22 +41,18 @@ for software_release in software_release_list:
# If exist upgrade decision in progress try to cancel it # If exist upgrade decision in progress try to cancel it
decision_in_progress = newer_release.\ decision_in_progress = newer_release.\
SoftwareRelease_getUpgradeDecisionInProgress(compute_node.getUid()) SoftwareRelease_getUpgradeDecisionInProgress(compute_node.getUid())
if decision_in_progress and \ if decision_in_progress:
not decision_in_progress.UpgradeDecision_tryToCancel( decision_in_progress.reviewRegistration(
newer_release.getUrlString()): software_release_url=newer_release.getUrlString())
continue if decision_in_progress.getSimulationState() != "cancelled":
continue
upgrade_decision = newer_release.SoftwareRelease_createUpgradeDecision( upgrade_decision = newer_release.SoftwareRelease_createUpgradeDecision(
source_url=compute_node.getRelativeUrl(), source_url=compute_node.getRelativeUrl(),
title=title) title=title)
if context.getUpgradeScope() == "auto": upgrade_decision.approveRegistration(
upgrade_decision.start() upgrade_scope=compute_node.getUpgradeScope("ask_confirmation"))
elif context.getUpgradeScope("ask_confirmation") == "ask_confirmation" \
and upgrade_decision.getSimulationState() != "planned":
upgrade_decision.plan()
upgrade_decision.setStartDate(DateTime())
upgrade_decision_list.append(upgrade_decision) upgrade_decision_list.append(upgrade_decision)
return upgrade_decision_list return upgrade_decision_list
...@@ -2,7 +2,7 @@ from DateTime import DateTime ...@@ -2,7 +2,7 @@ from DateTime import DateTime
portal = context.getPortalObject() portal = context.getPortalObject()
instance_tree = context instance_tree = context
upgrade_scope = context.getUpgradeScope() upgrade_scope = context.getUpgradeScope("ask_confirmation")
if upgrade_scope in ["never", "disabled"]: if upgrade_scope in ["never", "disabled"]:
return return
...@@ -22,7 +22,6 @@ if instance_tree.getSlapState() == "destroy_requested": ...@@ -22,7 +22,6 @@ if instance_tree.getSlapState() == "destroy_requested":
return return
tag = "%s_requestUpgradeDecisionCreation_inProgress" % instance_tree.getUid() tag = "%s_requestUpgradeDecisionCreation_inProgress" % instance_tree.getUid()
activate_kw = {'tag': tag}
if portal.portal_activities.countMessageWithTag(tag) > 0: if portal.portal_activities.countMessageWithTag(tag) > 0:
# nothing to do # nothing to do
return return
...@@ -52,22 +51,18 @@ if newer_release is None: ...@@ -52,22 +51,18 @@ if newer_release is None:
decision_in_progress = newer_release.\ decision_in_progress = newer_release.\
SoftwareRelease_getUpgradeDecisionInProgress(instance_tree.getUid()) SoftwareRelease_getUpgradeDecisionInProgress(instance_tree.getUid())
if decision_in_progress and \ if decision_in_progress:
not decision_in_progress.UpgradeDecision_tryToCancel( decision_in_progress.reviewRegistration(
newer_release.getUrlString()): software_release_url=newer_release.getUrlString())
return if decision_in_progress.getSimulationState() != "cancelled":
return
upgrade_decision = newer_release.SoftwareRelease_createUpgradeDecision( upgrade_decision = newer_release.SoftwareRelease_createUpgradeDecision(
source_url=instance_tree.getRelativeUrl(), source_url=instance_tree.getRelativeUrl(),
title=decision_title title=decision_title
) )
with upgrade_decision.defaultActivateParameterDict(activate_kw):
upgrade_decision.plan()
upgrade_decision.setStartDate(DateTime())
if upgrade_scope == "auto":
upgrade_decision.start()
# Prevent concurrent transaction to create 2 upgrade decision for the same instance_tree upgrade_decision.approveRegistration(
instance_tree.serialize() upgrade_scope=upgrade_scope)
return upgrade_decision return upgrade_decision
instance_tree = context.getAggregateValue(portal_type="Instance Tree") context.getParentValue().reviewUpgrade()
software_release = context.getAggregateValue(portal_type="Software Release")
upgrade_decision = context.getParentValue()
if upgrade_decision.getSimulationState() == "cancelled":
return
if software_release.getValidationState() == "archived":
upgrade_decision.cancel(comment="Software Release is archived.")
return
if instance_tree is not None:
if instance_tree.getUpgradeScope() in ['never', 'disabled']:
upgrade_decision.cancel("Upgrade scope was disabled on the related Instance Tree")
elif instance_tree.getSlapState() == "destroy_requested":
upgrade_decision.cancel(comment="Instance Tree is destroyed.")
elif instance_tree.getUrlString() == software_release.getUrlString():
upgrade_decision.cancel(comment="Instance tree is already upgraded.")
return
compute_node = context.getAggregateValue(portal_type="Compute Node")
if compute_node is not None:
if compute_node.getUpgradeScope() in ['never', 'disabled']:
upgrade_decision.cancel("Upgrade scope was disabled on the related Instance Tree")
return
elif compute_node.getAllocationScope() in ["closed/forever", "closed/termination"]:
upgrade_decision.cancel(comment="Compute Node is closed.")
return
already_deployed = len(context.portal_catalog(limit=1,
portal_type="Compute Partition",
parent_reference=compute_node.getReference(),
software_release_url=software_release.getUrlString()))
if already_deployed:
upgrade_decision.cancel(comment="Compute Node already has the software release")
document_list = []
for decision_line in context.contentValues():
try:
document_list.extend(
decision_line.getAggregateValueList(portal_type=document_portal_type))
except:
raise ValueError(context)
if len(document_list) > 1:
raise ValueError("It is only allowed to have more them 1 %s" % document_list)
if len(document_list) == 0:
return None
return document_list[0]
...@@ -50,11 +50,11 @@ ...@@ -50,11 +50,11 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>title, description, source_relative_url</string> </value> <value> <string>document_portal_type="Instance Tree"</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>Base_generateSupportRequestForSlapOS</string> </value> <value> <string>UpgradeDecision_getAggregateValue</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
compute_node_list = []
for decision_line in context.contentValues():
compute_node_list.extend(
decision_line.getAggregateValueList(portal_type="Compute Node"))
if len(compute_node_list) > 1:
raise ValueError("It is only allowed to have more them 1 Compute Node")
if len(compute_node_list) == 0:
return None
return compute_node_list[0]
instance_tree_list = []
for decision_line in context.contentValues():
instance_tree_list.extend(
decision_line.getAggregateValueList(portal_type="Instance Tree"))
if len(instance_tree_list) > 1:
raise ValueError("It is only allowed to have more them 1 Instance Tree")
if len(instance_tree_list) == 0:
return None
return instance_tree_list[0]
software_release_list = []
for decision_line in context.contentValues():
software_release_list.extend(
decision_line.getAggregateValueList(portal_type="Software Release"))
if len(software_release_list) > 1:
raise ValueError("It is only allowed to have more them 1 Software Release")
if len(software_release_list) == 0:
return None
return software_release_list[0]
portal = context.getPortalObject() portal = context.getPortalObject()
instance_tree = context.UpgradeDecision_getInstanceTree() instance_tree = context.UpgradeDecision_getAggregateValue("Instance Tree")
compute_node = context.UpgradeDecision_getComputeNode() compute_node = context.UpgradeDecision_getAggregateValue("Compute Node")
software_release = context.UpgradeDecision_getSoftwareRelease() software_release = context.UpgradeDecision_getAggregateValue("Software Release")
if instance_tree is not None: if instance_tree is not None:
if instance_tree.getUrlString() == software_release.getUrlString(): if instance_tree.getUrlString() == software_release.getUrlString():
......
from DateTime import DateTime from DateTime import DateTime
# Review if the upgrade is applicable before notify.
context.reviewUpgrade()
if context.getSimulationState() != 'planned': if context.getSimulationState() != 'planned':
# XXX Don't notify the ones which are not planned. # XXX Don't notify the ones which are not planned.
return return
portal = context.getPortalObject() portal = context.getPortalObject()
...@@ -10,9 +13,9 @@ person = context.getDestinationDecisionValue(portal_type="Person") ...@@ -10,9 +13,9 @@ person = context.getDestinationDecisionValue(portal_type="Person")
if not person: if not person:
raise ValueError("Inconsistent Upgrade Decision, No Destination Decision") raise ValueError("Inconsistent Upgrade Decision, No Destination Decision")
instance_tree = context.UpgradeDecision_getInstanceTree() instance_tree = context.UpgradeDecision_getAggregateValue("Instance Tree")
compute_node = context.UpgradeDecision_getComputeNode() compute_node = context.UpgradeDecision_getAggregateValue("Compute Node")
software_release = context.UpgradeDecision_getSoftwareRelease() software_release = context.UpgradeDecision_getAggregateValue("Software Release")
software_product_title = software_release.getAggregateTitle( software_product_title = software_release.getAggregateTitle(
portal_type="Software Product") portal_type="Software Product")
...@@ -21,8 +24,8 @@ mapping_dict = { ...@@ -21,8 +24,8 @@ mapping_dict = {
'software_release_name': software_release.getTitle(), 'software_release_name': software_release.getTitle(),
'software_release_reference': software_release.getReference(), 'software_release_reference': software_release.getReference(),
'new_software_release_url': software_release.getUrlString(), 'new_software_release_url': software_release.getUrlString(),
} }
if instance_tree is not None: if instance_tree is not None:
notification_message_reference = 'slapos-upgrade-instance-tree.notification' notification_message_reference = 'slapos-upgrade-instance-tree.notification'
title = "New Upgrade available for %s" % instance_tree.getTitle() title = "New Upgrade available for %s" % instance_tree.getTitle()
...@@ -30,11 +33,8 @@ if instance_tree is not None: ...@@ -30,11 +33,8 @@ if instance_tree is not None:
'instance_tree_title': instance_tree.getTitle(), 'instance_tree_title': instance_tree.getTitle(),
'old_software_release_url': instance_tree.getUrlString()}) 'old_software_release_url': instance_tree.getUrlString()})
elif compute_node is not None: elif compute_node is not None:
notification_message_reference = 'slapos-upgrade-compute-node.notification' notification_message_reference = 'slapos-upgrade-compute-node.notification'
title = "New Software available for Installation at %s" % compute_node.getTitle() title = "New Software available for Installation at %s" % compute_node.getTitle()
mapping_dict.update(**{'compute_node_title': compute_node.getTitle(), mapping_dict.update(**{'compute_node_title': compute_node.getTitle(),
'compute_node_reference': compute_node.getReference()}) 'compute_node_reference': compute_node.getReference()})
...@@ -49,8 +49,10 @@ notification_message = portal.portal_notifications.getDocumentValue( ...@@ -49,8 +49,10 @@ notification_message = portal.portal_notifications.getDocumentValue(
message = notification_message.asEntireHTML( message = notification_message.asEntireHTML(
substitution_method_parameter_dict={'mapping_dict': mapping_dict}) substitution_method_parameter_dict={'mapping_dict': mapping_dict})
event = context.SupportRequest_trySendNotificationMessage(title, context.notify(message_title=title,
message, person.getRelativeUrl()) message=message,
destination_relative_url=person.getRelativeUrl())
event = context.REQUEST.get("upgrade_decision_notified_item")
if event is not None: if event is not None:
context.confirm() context.confirm()
...@@ -12,9 +12,10 @@ person = context.getDestinationDecisionValue(portal_type="Person") ...@@ -12,9 +12,10 @@ person = context.getDestinationDecisionValue(portal_type="Person")
if not person: if not person:
raise ValueError("Inconsistent Upgrade Decision, No Destination Decision") raise ValueError("Inconsistent Upgrade Decision, No Destination Decision")
instance_tree = context.UpgradeDecision_getInstanceTree()
compute_node = context.UpgradeDecision_getComputeNode() instance_tree = context.UpgradeDecision_getAggregateValue("Instance Tree")
software_release = context.UpgradeDecision_getSoftwareRelease() compute_node = context.UpgradeDecision_getAggregateValue("Compute Node")
software_release = context.UpgradeDecision_getAggregateValue("Software Release")
software_product_title = software_release.getAggregateTitle( software_product_title = software_release.getAggregateTitle(
portal_type="Software Product") portal_type="Software Product")
...@@ -51,8 +52,10 @@ notification_message = portal.portal_notifications.getDocumentValue( ...@@ -51,8 +52,10 @@ notification_message = portal.portal_notifications.getDocumentValue(
message = notification_message.asEntireHTML( message = notification_message.asEntireHTML(
substitution_method_parameter_dict={'mapping_dict': mapping_dict}) substitution_method_parameter_dict={'mapping_dict': mapping_dict})
event = context.SupportRequest_trySendNotificationMessage(title, context.notify(message_title=title,
message, person.getRelativeUrl()) message=message,
destination_relative_url=person.getRelativeUrl())
event = context.REQUEST.get("upgrade_decision_notified_item")
if event is not None: if event is not None:
context.setStopDate(DateTime()) context.setStopDate(DateTime())
......
if context.UpgradeDecision_upgradeInstanceTree(): return context.requestUpgrade()
return True
if context.UpgradeDecision_upgradeComputeNode():
return True
return False
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>**kw</string> </value> <value> <string></string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>new_url_string</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>UpgradeDecision_tryToCancel</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
if context.getSimulationState() != 'started':
# Update Decision is not on started state, Upgrade is not possible!
return False
compute_node = context.UpgradeDecision_getComputeNode()
software_release = context.UpgradeDecision_getSoftwareRelease()
if compute_node is None:
return False
if software_release is None:
return False
software_release_url = software_release.getUrlString()
compute_node.requestSoftwareRelease(
software_release_url=software_release_url,
state="available")
context.stop()
return True
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2002-2012 Nexedi SA and Contributors. All Rights Reserved.
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin, simulate
#from zExceptions import Unauthorized
import transaction
class TestSlapOSCoreProjectSlapInterfaceWorkflow(SlapOSTestCaseMixin):
def afterSetUp(self):
SlapOSTestCaseMixin.afterSetUp(self)
portal = self.getPortalObject()
person_user = self.makePerson()
self.tic()
self.login()
self.compute_node = self.portal.compute_node_module.template_compute_node\
.Base_createCloneDocument(batch_mode=1)
new_id = self.generateNewId()
self.compute_node.edit(
title="compute node %s" % (new_id, ),
reference="TESTCOMP-%s" % (new_id, ),
source_administration=person_user.getRelativeUrl()
)
self.compute_node.validate()
self.upgrade_decision = portal.upgrade_decision_module.newContent(
portal_type="Upgrade Decision",
)
# Value set by the init
self.assertTrue(self.upgrade_decision.getReference().startswith("UD-"),
"Reference don't start with UD- : %s" % self.upgrade_decision.getReference())
self.software_release = self._makeSoftwareRelease()
self.tic()
def _addUpgradeLine(self, aggregate):
self.upgrade_decision.newContent(
portal_type="Upgrade Decision Line",
aggregate_value_list=[self.software_release,
aggregate]
)
def beforeTearDown(self):
transaction.abort()
def test_upgrade_decision_approveRegistration_no_line(self):
self.assertRaises(ValueError, self.upgrade_decision.approveRegistration)
def test_upgrade_decision_approveRegistration_no_aggregate(self):
self.upgrade_decision.newContent(
portal_type="Upgrade Decision Line",
aggregate=self.software_release.getRelativeUrl()
)
self.assertRaises(ValueError, self.upgrade_decision.approveRegistration)
def test_upgrade_decision_approveRegistration_no_upgrade_scope(self):
self._addUpgradeLine(self.compute_node)
self.assertRaises(TypeError, self.upgrade_decision.approveRegistration)
def test_upgrade_decision_approveRegistration_computer(self):
self._addUpgradeLine(self.compute_node)
self.upgrade_decision.approveRegistration(
upgrade_scope="ask_confirmation"
)
self.assertEqual("planned",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.compute_node.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
# Call again does nothing
self.upgrade_decision.approveRegistration(
upgrade_scope="ask_confirmation"
)
self.assertEqual("planned",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.compute_node.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
self.tic()
# Call again does nothing again
self.upgrade_decision.approveRegistration(
upgrade_scope="ask_confirmation"
)
self.assertEqual("planned",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.compute_node.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
def test_upgrade_decision_approveRegistration_instance_tree(self):
self._makeTree()
self._addUpgradeLine(self.instance_tree)
self.upgrade_decision.approveRegistration(
upgrade_scope="ask_confirmation"
)
self.assertEqual("planned",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.instance_tree.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
# Call again does nothing
self.upgrade_decision.approveRegistration(
upgrade_scope="ask_confirmation"
)
self.assertEqual("planned",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.instance_tree.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
self.tic()
# Call again does nothing again
self.upgrade_decision.approveRegistration(
upgrade_scope="ask_confirmation"
)
self.assertEqual("planned",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.instance_tree.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
def test_upgrade_decision_approveRegistration_computer_auto(self):
self._addUpgradeLine(self.compute_node)
self.upgrade_decision.approveRegistration(
upgrade_scope="auto"
)
self.assertEqual("started",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.compute_node.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
# Call again does nothing
self.upgrade_decision.approveRegistration(
upgrade_scope="auto"
)
self.assertEqual("started",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.compute_node.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
self.tic()
# Call again does nothing again
self.upgrade_decision.approveRegistration(
upgrade_scope="auto"
)
self.assertEqual("started",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.compute_node.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
def test_upgrade_decision_approveRegistration_instance_tree_auto(self):
self._makeTree()
self._addUpgradeLine(self.instance_tree)
self.upgrade_decision.approveRegistration(
upgrade_scope="auto"
)
self.assertEqual("started",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.instance_tree.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
# Call again does nothing
self.upgrade_decision.approveRegistration(
upgrade_scope="auto"
)
self.assertEqual("started",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.instance_tree.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
self.tic()
# Call again does nothing again
# Call again does nothing
self.upgrade_decision.approveRegistration(
upgrade_scope="auto"
)
self.assertEqual("started",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.instance_tree.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
def test_upgrade_decision_reviewRegistration_no_software_release_url(self):
self.assertRaises(TypeError, self.upgrade_decision.reviewRegistration)
def test_upgrade_decision_reviewRegistration_draft(self):
# Do nothing as draft
software_release = self.generateNewSoftwareReleaseUrl()
self.upgrade_decision.reviewRegistration(software_release_url=software_release)
def test_upgrade_decision_reviewRegistration(self):
self._addUpgradeLine(self.compute_node)
software_release = self.generateNewSoftwareReleaseUrl()
self.upgrade_decision.reviewRegistration(
software_release_url=software_release)
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.plan()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=software_release)
self.assertEqual("cancelled",
self.upgrade_decision.getSimulationState())
def test_upgrade_decision_reviewRegistration_confirm(self):
self._addUpgradeLine(self.compute_node)
software_release = self.generateNewSoftwareReleaseUrl()
self.upgrade_decision.reviewRegistration(
software_release_url=software_release)
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.confirm()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=software_release)
self.assertEqual("cancelled",
self.upgrade_decision.getSimulationState())
def test_upgrade_decision_reviewRegistration_rejected(self):
self._addUpgradeLine(self.compute_node)
software_release = self.generateNewSoftwareReleaseUrl()
self.upgrade_decision.reviewRegistration(
software_release_url=software_release)
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.reject()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=software_release)
self.assertEqual("rejected",
self.upgrade_decision.getSimulationState())
def test_upgrade_decision_reviewRegistration_same_url(self):
self._addUpgradeLine(self.compute_node)
self.upgrade_decision.reviewRegistration(
software_release_url=self.software_release.getUrlString())
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.plan()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=self.software_release.getUrlString())
self.assertEqual("planned",
self.upgrade_decision.getSimulationState())
def test_upgrade_decision_reviewRegistration_confirm_same_url(self):
self._addUpgradeLine(self.compute_node)
self.upgrade_decision.reviewRegistration(
software_release_url=self.software_release.getUrlString())
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.confirm()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=self.software_release.getUrlString())
self.assertEqual("confirmed",
self.upgrade_decision.getSimulationState())
def test_upgrade_decision_reviewRegistration_rejected_same_url(self):
self._addUpgradeLine(self.compute_node)
self.upgrade_decision.reviewRegistration(
software_release_url=self.software_release.getUrlString())
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.reject()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=self.software_release.getUrlString())
self.assertEqual("rejected",
self.upgrade_decision.getSimulationState())
def test_upgrade_decision_reviewRegistration_started(self):
self._addUpgradeLine(self.compute_node)
software_release = self.generateNewSoftwareReleaseUrl()
self.upgrade_decision.reviewRegistration(
software_release_url=software_release)
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.plan()
self.upgrade_decision.start()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=software_release)
self.assertEqual("started",
self.upgrade_decision.getSimulationState())
def test_upgrade_decision_reviewRegistration_instance_tree(self):
self._makeTree()
self._addUpgradeLine(self.instance_tree)
self.upgrade_decision.reviewRegistration(
software_release_url=self.instance_tree.getUrlString())
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.plan()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=self.instance_tree.getUrlString())
self.assertEqual("cancelled",
self.upgrade_decision.getSimulationState())
def test_upgrade_decision_reviewRegistration_instance_tree_confirmed(self):
self._makeTree()
self._addUpgradeLine(self.instance_tree)
self.upgrade_decision.reviewRegistration(
software_release_url=self.instance_tree.getUrlString())
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.confirm()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=self.instance_tree.getUrlString())
self.assertEqual("cancelled",
self.upgrade_decision.getSimulationState())
def test_upgrade_decision_reviewRegistration_instance_tree_started(self):
self._makeTree()
self._addUpgradeLine(self.instance_tree)
self.upgrade_decision.reviewRegistration(
software_release_url=self.instance_tree.getUrlString())
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.start()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=self.instance_tree.getUrlString())
self.assertEqual("started",
self.upgrade_decision.getSimulationState())
@simulate('InstanceTree_isUpgradePossible',
'software_release_url', 'return 1')
def test_upgrade_decision_requestUpgrade_instance_tree(self):
self._makeTree()
self._addUpgradeLine(self.instance_tree)
self.tic()
slap_state = self.instance_tree.getSlapState()
self.upgrade_decision.requestUpgrade()
self.assertNotEqual(self.software_release.getUrlString(),
self.instance_tree.getUrlString())
self.upgrade_decision.confirm()
self.upgrade_decision.start()
# Check that url_string change, but slap state doesn't
self.assertNotEqual(self.software_release.getUrlString(),
self.instance_tree.getUrlString())
self.upgrade_decision.requestUpgrade()
self.assertEqual(self.software_release.getUrlString(),
self.instance_tree.getUrlString())
self.assertEqual(slap_state, self.instance_tree.getSlapState())
self.assertEqual('stopped', self.upgrade_decision.getSimulationState())
def test_upgrade_decision_requestUpgrade_instance_tree_no_software_release(self):
self._makeTree()
self.upgrade_decision.newContent(
portal_type="Upgrade Decision Line",
aggregate_value_list=[self.instance_tree]
)
self.upgrade_decision.confirm()
self.upgrade_decision.start()
self.tic()
self.upgrade_decision.requestUpgrade()
self.assertEqual('started', self.upgrade_decision.getSimulationState())
def test_upgrade_decision_requestUpgrade_compute_node_no_software_release(self):
self.upgrade_decision.newContent(
portal_type="Upgrade Decision Line",
aggregate_value_list=[self.compute_node]
)
self.upgrade_decision.confirm()
self.upgrade_decision.start()
self.tic()
self.upgrade_decision.requestUpgrade()
self.assertEqual('started', self.upgrade_decision.getSimulationState())
def test_upgrade_decision_requestUpgrade_only_software_release(self):
self.upgrade_decision.newContent(
portal_type="Upgrade Decision Line",
aggregate_value_list=[self.software_release]
)
self.upgrade_decision.confirm()
self.upgrade_decision.start()
self.tic()
self.upgrade_decision.requestUpgrade()
self.assertEqual('started', self.upgrade_decision.getSimulationState())
def test_upgrade_decision_requestUpgrade_duplicated(self):
self._makeTree()
self.upgrade_decision.newContent(
portal_type="Upgrade Decision Line",
aggregate_value_list=[
self.software_release,
self.instance_tree,
self.compute_node]
)
self.upgrade_decision.confirm()
self.upgrade_decision.start()
self.tic()
self.assertRaises(ValueError, self.upgrade_decision.requestUpgrade)
self.assertEqual('started', self.upgrade_decision.getSimulationState())
def test_upgrade_decision_requestUpgrade_compute_node(self):
self._addUpgradeLine(self.compute_node)
self.upgrade_decision.confirm()
self.upgrade_decision.start()
self.tic()
self.upgrade_decision.requestUpgrade()
self.tic()
self.assertEqual('stopped', self.upgrade_decision.getSimulationState())
software_installation = self.compute_node.getAggregateRelatedValue(
portal_type='Software Installation')
self.assertEqual('start_requested', software_installation.getSlapState())
self.assertEqual(self.software_release.getUrlString(),
software_installation.getUrlString())
self.assertEqual('validated', software_installation.getValidationState())
@simulate('InstanceTree_isUpgradePossible',
'software_release_url', 'return 0')
def test_upgrade_decision_requestUpgrade_instance_tree_not_possible(self):
self._makeTree()
self._addUpgradeLine(self.instance_tree)
self.assertNotEqual(self.instance_tree.getUrlString(),
self.software_release.getUrlString())
slap_state = self.instance_tree.getSlapState()
self.upgrade_decision.confirm()
self.upgrade_decision.start()
self.tic()
self.upgrade_decision.requestUpgrade()
self.tic()
self.assertEqual('started', self.upgrade_decision.getSimulationState())
self.assertNotEqual(self.instance_tree.getUrlString(),
self.software_release.getUrlString())
self.assertEqual(slap_state,
self.instance_tree.getSlapState())
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Test Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testSlapOSCloudUpgradeSlapInterfaceWorkflow</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test.erp5.testSlapOSCloudUpgradeSlapInterfaceWorkflow</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Test Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -284,11 +284,12 @@ class TestSlapOSPDMCreateUpgradeDecisionSkins(TestSlapOSPDMMixinSkins): ...@@ -284,11 +284,12 @@ class TestSlapOSPDMCreateUpgradeDecisionSkins(TestSlapOSPDMMixinSkins):
self.assertNotEqual(up_decision, None) self.assertNotEqual(up_decision, None)
self.assertEqual(up_decision.getSimulationState(), 'planned') self.assertEqual(up_decision.getSimulationState(), 'planned')
self.assertEqual(up_decision.UpgradeDecision_getInstanceTree().\ self.assertEqual(up_decision.UpgradeDecision_getAggregateValue("Instance Tree").\
getReference(), instance_tree.getReference()) getReference(), instance_tree.getReference())
self.assertEqual(up_decision.UpgradeDecision_getSoftwareRelease().\ self.assertEqual(software_release2.getUrlString(),
getUrlString(), software_release2.getUrlString()) up_decision.UpgradeDecision_getAggregateValue("Software Release").\
getUrlString())
self.tic() self.tic()
up_decision2 = instance_tree.InstanceTree_createUpgradeDecision() up_decision2 = instance_tree.InstanceTree_createUpgradeDecision()
...@@ -331,7 +332,7 @@ class TestSlapOSPDMCreateUpgradeDecisionSkins(TestSlapOSPDMMixinSkins): ...@@ -331,7 +332,7 @@ class TestSlapOSPDMCreateUpgradeDecisionSkins(TestSlapOSPDMMixinSkins):
up_decision2 = instance_tree.InstanceTree_createUpgradeDecision() up_decision2 = instance_tree.InstanceTree_createUpgradeDecision()
self.assertEqual(up_decision2.getSimulationState(), 'planned') self.assertEqual(up_decision2.getSimulationState(), 'planned')
self.assertEqual(up_decision.getSimulationState(), 'cancelled') self.assertEqual(up_decision.getSimulationState(), 'cancelled')
release = up_decision2.UpgradeDecision_getSoftwareRelease() release = up_decision2.UpgradeDecision_getAggregateValue("Software Release")
self.assertEqual(release.getUrlString(), self.assertEqual(release.getUrlString(),
software_release3.getUrlString()) software_release3.getUrlString())
...@@ -414,7 +415,7 @@ class TestSlapOSPDMCreateUpgradeDecisionSkins(TestSlapOSPDMMixinSkins): ...@@ -414,7 +415,7 @@ class TestSlapOSPDMCreateUpgradeDecisionSkins(TestSlapOSPDMMixinSkins):
decision2 = instance_tree.InstanceTree_createUpgradeDecision() decision2 = instance_tree.InstanceTree_createUpgradeDecision()
self.assertEqual(decision2.getSimulationState(), 'planned') self.assertEqual(decision2.getSimulationState(), 'planned')
self.assertEqual(up_decision.getSimulationState(), 'rejected') self.assertEqual(up_decision.getSimulationState(), 'rejected')
release = decision2.UpgradeDecision_getSoftwareRelease() release = decision2.UpgradeDecision_getAggregateValue("Software Release")
self.assertEqual(release.getUrlString(), self.assertEqual(release.getUrlString(),
software_release3.getUrlString()) software_release3.getUrlString())
\ No newline at end of file
...@@ -338,7 +338,7 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins): ...@@ -338,7 +338,7 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision) upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValue(compute_node) upgrade_decision_line.setAggregateValue(compute_node)
found_compute_node = upgrade_decision.UpgradeDecision_getComputeNode() found_compute_node = upgrade_decision.UpgradeDecision_getAggregateValue("Compute Node")
self.assertEqual(compute_node.getRelativeUrl(), self.assertEqual(compute_node.getRelativeUrl(),
found_compute_node.getRelativeUrl()) found_compute_node.getRelativeUrl())
...@@ -351,7 +351,7 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins): ...@@ -351,7 +351,7 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision) upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
found_compute_node = upgrade_decision.UpgradeDecision_getComputeNode() found_compute_node = upgrade_decision.UpgradeDecision_getAggregateValue("Compute Node")
self.assertEqual(compute_node.getRelativeUrl(), self.assertEqual(compute_node.getRelativeUrl(),
found_compute_node.getRelativeUrl()) found_compute_node.getRelativeUrl())
...@@ -365,13 +365,14 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins): ...@@ -365,13 +365,14 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision) upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValue(compute_node) upgrade_decision_line.setAggregateValue(compute_node)
self.assertRaises(ValueError, upgrade_decision.UpgradeDecision_getComputeNode) self.assertRaises(ValueError, upgrade_decision.UpgradeDecision_getAggregateValue,
document_portal_type="Compute Node")
def testUpgradeDecision_getComputeNode_O_compute_node(self): def testUpgradeDecision_getComputeNode_O_compute_node(self):
upgrade_decision = self._makeUpgradeDecision() upgrade_decision = self._makeUpgradeDecision()
self._makeUpgradeDecisionLine(upgrade_decision) self._makeUpgradeDecisionLine(upgrade_decision)
found_compute_node = upgrade_decision.UpgradeDecision_getComputeNode() found_compute_node = upgrade_decision.UpgradeDecision_getAggregateValue("Compute Node")
self.assertEqual(None, found_compute_node) self.assertEqual(None, found_compute_node)
...@@ -382,7 +383,7 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins): ...@@ -382,7 +383,7 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision) upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValue(instance_tree) upgrade_decision_line.setAggregateValue(instance_tree)
found_instance_tree = upgrade_decision.UpgradeDecision_getInstanceTree() found_instance_tree = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
self.assertEqual(instance_tree.getRelativeUrl(), self.assertEqual(instance_tree.getRelativeUrl(),
found_instance_tree.getRelativeUrl()) found_instance_tree.getRelativeUrl())
...@@ -396,7 +397,7 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins): ...@@ -396,7 +397,7 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision) upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
found_instance_tree = upgrade_decision.UpgradeDecision_getInstanceTree() found_instance_tree = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
self.assertEqual(instance_tree.getRelativeUrl(), self.assertEqual(instance_tree.getRelativeUrl(),
found_instance_tree.getRelativeUrl()) found_instance_tree.getRelativeUrl())
...@@ -411,28 +412,29 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins): ...@@ -411,28 +412,29 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision) upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValue(instance_tree) upgrade_decision_line.setAggregateValue(instance_tree)
self.assertRaises(ValueError, upgrade_decision.UpgradeDecision_getInstanceTree) self.assertRaises(ValueError, upgrade_decision.UpgradeDecision_getAggregateValue,
document_portal_type="Instance Tree")
def testUpgradeDecision_getInstanceTree_O_hosting(self): def testUpgradeDecision_getInstanceTree_O_hosting(self):
upgrade_decision = self._makeUpgradeDecision() upgrade_decision = self._makeUpgradeDecision()
self._makeUpgradeDecisionLine(upgrade_decision) self._makeUpgradeDecisionLine(upgrade_decision)
found_instance_tree = upgrade_decision.UpgradeDecision_getInstanceTree() found_instance_tree = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
self.assertEqual(None, found_instance_tree) self.assertEqual(None, found_instance_tree)
def testUpgradeDecision_getSoftwareRelease(self): def testUpgradeDecision_getAggregateValue_SoftwareRelease(self):
software_release = self._makeSoftwareRelease() software_release = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision() upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision) upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValue(software_release) upgrade_decision_line.setAggregateValue(software_release)
found_software_release = upgrade_decision.UpgradeDecision_getSoftwareRelease() found_software_release = upgrade_decision.UpgradeDecision_getAggregateValue("Software Release")
self.assertEqual(software_release.getRelativeUrl(), self.assertEqual(software_release.getRelativeUrl(),
found_software_release.getRelativeUrl()) found_software_release.getRelativeUrl())
def testUpgradeDecision_getSoftwareRelease_2_lines(self): def testUpgradeDecision_getAggregateValue_SoftwareRelease_2_lines(self):
software_release = self._makeSoftwareRelease() software_release = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision() upgrade_decision = self._makeUpgradeDecision()
...@@ -441,11 +443,11 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins): ...@@ -441,11 +443,11 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision) upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
found_software_release = upgrade_decision.UpgradeDecision_getSoftwareRelease() found_software_release = upgrade_decision.UpgradeDecision_getAggregateValue("Software Release")
self.assertEqual(software_release.getRelativeUrl(), self.assertEqual(software_release.getRelativeUrl(),
found_software_release.getRelativeUrl()) found_software_release.getRelativeUrl())
def testUpgradeDecision_getSoftwareRelease_2_sr(self): def testUpgradeDecision_getAggregateValue_SoftwareRelease_2_sr(self):
software_release = self._makeSoftwareRelease() software_release = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision() upgrade_decision = self._makeUpgradeDecision()
...@@ -455,212 +457,16 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins): ...@@ -455,212 +457,16 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision) upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValue(software_release) upgrade_decision_line.setAggregateValue(software_release)
self.assertRaises(ValueError, upgrade_decision.UpgradeDecision_getSoftwareRelease) self.assertRaises(ValueError, upgrade_decision.UpgradeDecision_getAggregateValue,
document_portal_type="Software Release")
def testUpgradeDecision_getSoftwareRelease_O_sr(self): def testUpgradeDecision_getAggregateValue_SoftwareRelease_O_sr(self):
upgrade_decision = self._makeUpgradeDecision() upgrade_decision = self._makeUpgradeDecision()
self._makeUpgradeDecisionLine(upgrade_decision) self._makeUpgradeDecisionLine(upgrade_decision)
found_software_release = upgrade_decision.UpgradeDecision_getSoftwareRelease() found_software_release = upgrade_decision.UpgradeDecision_getAggregateValue("Software Release")
self.assertEqual(None, found_software_release) self.assertEqual(None, found_software_release)
@simulate('InstanceTree_isUpgradePossible',
'software_release_url', 'return 1')
def testUpgradeDecision_upgradeInstanceTree(self):
person = self._makePerson()
instance_tree = self._makeInstanceTree()
instance_tree.edit(
destination_section_value = person.getRelativeUrl())
self._makeSoftwareInstance(instance_tree,
instance_tree.getUrlString())
software_release = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList(
[software_release, instance_tree])
self.tic()
slap_state = instance_tree.getSlapState()
self.assertFalse(upgrade_decision.UpgradeDecision_upgradeInstanceTree())
self.assertNotEqual(software_release.getUrlString(),
instance_tree.getUrlString())
upgrade_decision.confirm()
upgrade_decision.start()
# Check that url_string change, but slap state doesn't
self.assertNotEqual(software_release.getUrlString(),
instance_tree.getUrlString())
self.assertTrue(upgrade_decision.UpgradeDecision_upgradeInstanceTree())
self.assertEqual(software_release.getUrlString(),
instance_tree.getUrlString())
self.assertEqual(slap_state, instance_tree.getSlapState())
self.assertEqual('stopped', upgrade_decision.getSimulationState())
@simulate('InstanceTree_isUpgradePossible',
'software_release_url', 'return 1')
def testUpgradeDecision_processUpgradeeInstanceTree(self):
person = self._makePerson()
instance_tree = self._makeInstanceTree()
instance_tree.edit(
destination_section_value = person.getRelativeUrl())
self._makeSoftwareInstance(instance_tree,
instance_tree.getUrlString())
software_release = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList(
[software_release, instance_tree])
self.tic()
slap_state = instance_tree.getSlapState()
self.assertFalse(upgrade_decision.UpgradeDecision_processUpgrade())
self.assertNotEqual(software_release.getUrlString(),
instance_tree.getUrlString())
upgrade_decision.confirm()
upgrade_decision.start()
# Check that url_string change, but slap state doesn't
self.assertNotEqual(software_release.getUrlString(),
instance_tree.getUrlString())
self.assertTrue(upgrade_decision.UpgradeDecision_processUpgrade())
self.assertEqual(software_release.getUrlString(),
instance_tree.getUrlString())
self.assertEqual(slap_state, instance_tree.getSlapState())
self.assertEqual('stopped', upgrade_decision.getSimulationState())
def testUpgradeDecision_upgradeInstanceTree_no_software_release(self):
person = self._makePerson()
instance_tree = self._makeInstanceTree()
instance_tree.edit(
destination_section_value = person.getRelativeUrl())
self._makeSoftwareInstance(instance_tree,
instance_tree.getUrlString())
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([instance_tree])
self.tic()
upgrade_decision.confirm()
upgrade_decision.start()
self.assertFalse(upgrade_decision.UpgradeDecision_upgradeInstanceTree())
self.assertEqual('started', upgrade_decision.getSimulationState())
def testUpgradeDecision_upgradeInstanceTree_no_hosting_subscripion(self):
software_release = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release])
self.tic()
upgrade_decision.confirm()
upgrade_decision.start()
self.assertFalse(upgrade_decision.UpgradeDecision_upgradeInstanceTree())
self.assertEqual('started', upgrade_decision.getSimulationState())
def testUpgradeDecision_upgradeComputeNode_no_software_release(self):
person = self._makePerson()
compute_node, _ = self._makeComputeNode(owner=person)
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([compute_node])
self.tic()
upgrade_decision.confirm()
upgrade_decision.start()
self.assertFalse(upgrade_decision.UpgradeDecision_upgradeComputeNode())
self.assertEqual('started', upgrade_decision.getSimulationState())
def testUpgradeDecision_upgradeComputeNode_no_hosting_subscripion(self):
software_release = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release])
self.tic()
upgrade_decision.confirm()
upgrade_decision.start()
self.assertFalse(upgrade_decision.UpgradeDecision_upgradeComputeNode())
self.assertEqual('started', upgrade_decision.getSimulationState())
def testUpgradeDecision_upgradeComputeNode(self):
self._makePerson()
compute_node, _ = self._makeComputeNode()
software_release = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release, compute_node])
url = software_release.getUrlString()
self.tic()
self.assertFalse(upgrade_decision.UpgradeDecision_upgradeComputeNode())
upgrade_decision.confirm()
upgrade_decision.start()
self.assertTrue(upgrade_decision.UpgradeDecision_upgradeComputeNode())
self.tic()
software_installation = compute_node.getAggregateRelatedValue(
portal_type='Software Installation')
self.assertEqual('start_requested', software_installation.getSlapState())
self.assertEqual(url, software_installation.getUrlString())
self.assertEqual('validated', software_installation.getValidationState())
self.assertEqual('stopped', upgrade_decision.getSimulationState())
def testUpgradeDecision_processUpgradeComputeNode(self):
self._makePerson()
compute_node, _ = self._makeComputeNode()
software_release = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release, compute_node])
url = software_release.getUrlString()
self.tic()
self.assertFalse(upgrade_decision.UpgradeDecision_processUpgrade())
upgrade_decision.confirm()
upgrade_decision.start()
self.assertTrue(upgrade_decision.UpgradeDecision_processUpgrade())
self.tic()
software_installation = compute_node.getAggregateRelatedValue(
portal_type='Software Installation')
self.assertEqual('start_requested', software_installation.getSlapState())
self.assertEqual(url, software_installation.getUrlString())
self.assertEqual('validated', software_installation.getValidationState())
self.assertEqual('stopped', upgrade_decision.getSimulationState())
def testSoftwareRelease_createUpgradeDecision_compute_node(self): def testSoftwareRelease_createUpgradeDecision_compute_node(self):
person = self._makePerson() person = self._makePerson()
compute_node, _ = self._makeComputeNode(owner=person) compute_node, _ = self._makeComputeNode(owner=person)
...@@ -893,54 +699,6 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins): ...@@ -893,54 +699,6 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
self.assertEqual(in_progress, None) self.assertEqual(in_progress, None)
def testUpgradeDecision_tryToCancel(self):
compute_node, _ = self._makeComputeNode()
software_release = self._makeSoftwareRelease()
software_release2 = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release, compute_node])
upgrade_decision.confirm()
upgrade_decision2 = self._makeUpgradeDecision()
upgrade_decision_line2 = self._makeUpgradeDecisionLine(upgrade_decision2)
upgrade_decision_line2.setAggregateValueList([software_release, compute_node])
upgrade_decision2.confirm()
upgrade_decision2.start()
url = software_release.getUrlString()
url2 = software_release2.getUrlString()
# Cancel is not possible with the same url_string
self.assertEqual(upgrade_decision.UpgradeDecision_tryToCancel(url), False)
self.assertEqual(upgrade_decision.UpgradeDecision_tryToCancel(url2), True)
self.assertEqual(upgrade_decision.getSimulationState(), 'cancelled')
# Cancel is no longer possible
self.assertEqual(upgrade_decision2.UpgradeDecision_tryToCancel(url), False)
self.assertEqual(upgrade_decision2.UpgradeDecision_tryToCancel(url2), False)
self.assertEqual(upgrade_decision2.getSimulationState(), 'started')
def testUpgradeDecision_tryToCancel_withRejected(self):
compute_node, _ = self._makeComputeNode()
software_release = self._makeSoftwareRelease()
software_release2 = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release, compute_node])
upgrade_decision.confirm()
upgrade_decision.reject()
url = software_release.getUrlString()
url2 = software_release2.getUrlString()
# Try to cancel rejected UD with the same sr will return False
self.assertEqual(upgrade_decision.UpgradeDecision_tryToCancel(url), False)
self.assertEqual(upgrade_decision.getSimulationState(), 'rejected')
# Try to cancel rejected UD will return True with url2
self.assertEqual(upgrade_decision.UpgradeDecision_tryToCancel(url2), True)
self.assertEqual(upgrade_decision.getSimulationState(), 'rejected')
def testComputeNode_checkAndCreateUpgradeDecision_auto(self): def testComputeNode_checkAndCreateUpgradeDecision_auto(self):
person = self._makePerson() person = self._makePerson()
compute_node, _ = self._makeComputeNode(owner=person, compute_node, _ = self._makeComputeNode(owner=person,
...@@ -966,10 +724,10 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins): ...@@ -966,10 +724,10 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
self.assertEqual(len(upgrade_decision), 1) self.assertEqual(len(upgrade_decision), 1)
self.assertEqual(upgrade_decision[0].getSimulationState(), 'started') self.assertEqual(upgrade_decision[0].getSimulationState(), 'started')
compute_node_aggregate = upgrade_decision[0].UpgradeDecision_getComputeNode() compute_node_aggregate = upgrade_decision[0].UpgradeDecision_getAggregateValue("Compute Node")
self.assertEqual(compute_node_aggregate.getReference(), self.assertEqual(compute_node_aggregate,
compute_node.getReference()) compute_node)
release = upgrade_decision[0].UpgradeDecision_getSoftwareRelease() release = upgrade_decision[0].UpgradeDecision_getAggregateValue("Software Release")
self.assertEqual(release.getUrlString(), self.assertEqual(release.getUrlString(),
software_release2.getUrlString()) software_release2.getUrlString())
self.tic() self.tic()
...@@ -1001,7 +759,7 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins): ...@@ -1001,7 +759,7 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
self.assertEqual(upgrade_decision.getSimulationState(), 'cancelled') self.assertEqual(upgrade_decision.getSimulationState(), 'cancelled')
self.assertEqual(upgrade_decision2.getSimulationState(), 'planned') self.assertEqual(upgrade_decision2.getSimulationState(), 'planned')
release = upgrade_decision2.UpgradeDecision_getSoftwareRelease() release = upgrade_decision2.UpgradeDecision_getAggregateValue("Software Release")
self.assertEqual(release.getUrlString(), self.assertEqual(release.getUrlString(),
software_release3.getUrlString()) software_release3.getUrlString())
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_count</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_mt_index</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>_tree</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>source/portal_workflow/upgrade_slap_interface_workflow/state_draft</string>
</tuple>
</value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>person_slap_interface_workflow</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>upgrade_slap_interface_workflow</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>manager_bypass</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow</string> </value>
</item>
<item>
<key> <string>state_variable</string> </key>
<value> <string>slap_state</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Upgrade Slap Interface Workflow</string> </value>
</item>
<item>
<key> <string>workflow_managed_permission</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Length" module="BTrees.Length"/>
</pickle>
<pickle> <int>0</int> </pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
</ZopeData>
upgrade_decision = state_change["object"]
from DateTime import DateTime
portal = upgrade_decision.getPortalObject()
document = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
if document is None:
document = upgrade_decision.UpgradeDecision_getAggregateValue("Compute Node")
if document is None:
raise ValueError("No Compute Node or Instance Tree associated to upgrade.")
# Get required arguments
kwargs = state_change.kwargs
# Required args
# Raise TypeError if all parameters are not provided
try:
upgrade_scope = kwargs['upgrade_scope']
except KeyError:
raise TypeError("UpgradeDecision_approveRegistration takes exactly 1 arguments")
tag = "%s_requestUpgradeDecisionCreation_inProgress" % document.getUid()
activate_kw = {'tag': tag}
if portal.portal_activities.countMessageWithTag(tag) > 0:
# nothing to do
return
with upgrade_decision.defaultActivateParameterDict(activate_kw):
if upgrade_decision.getSimulationState() == "draft":
upgrade_decision.plan()
upgrade_decision.setStartDate(DateTime())
if upgrade_scope == "auto":
if upgrade_decision.getSimulationState() == "planned":
upgrade_decision.start()
# Prevent concurrent transaction to create 2 upgrade decision for the same instance_tree
document.serialize()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_UpgradeDecision_approveRegistration</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>UpgradeDecision_approveRegistration</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -50,19 +50,17 @@ ...@@ -50,19 +50,17 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>state_object</string> </value> <value> <string>state_change</string> </value>
</item> </item>
<item> <item>
<key> <string>_proxy_roles</string> </key> <key> <string>description</string> </key>
<value> <value>
<tuple> <none/>
<string>Assignor</string>
</tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>script_WebMessage_stopAndReopenTicket</string> </value> <value> <string>script_UpgradeDecision_checkConsistency</string> </value>
</item> </item>
<item> <item>
<key> <string>portal_type</string> </key> <key> <string>portal_type</string> </key>
......
support_request = context upgrade_decision = state_change["object"]
from DateTime import DateTime
portal = context.getPortalObject() portal = context.getPortalObject()
# Get required arguments
kwargs = state_change.kwargs
# Required args
# Raise TypeError if all parameters are not provided
try:
message_title = kwargs['message_title']
message = kwargs['message']
destination_relative_url = kwargs['destination_relative_url']
except KeyError:
raise TypeError("UpgradeDecision_requestEvent takes exactly 3 arguments")
resource = portal.service_module.slapos_crm_information.getRelativeUrl() resource = portal.service_module.slapos_crm_information.getRelativeUrl()
# create Web message if needed for this ticket # create Web message if needed for this ticket
last_event = context.portal_catalog.getResultValue( last_event = portal.portal_catalog.getResultValue(
title=message_title, title=message_title,
follow_up_uid=support_request.getUid(), follow_up_uid=upgrade_decision.getUid(),
sort_on=[('delivery.start_date', 'DESC')], sort_on=[('delivery.start_date', 'DESC')],
) )
if last_event: if last_event:
# User has already been notified for this problem. # User has already been notified for this problem.
return last_event return last_event
transactional_event = context.REQUEST.get("support_request_notified_item", None) transactional_event = context.REQUEST.get("upgrade_decision_notified_item", None)
if transactional_event is not None: if transactional_event is not None:
if (transactional_event.getFollowUpUid() == support_request.getUid()) and \ if (transactional_event.getFollowUpUid() == upgrade_decision.getUid()) and \
(transactional_event.getTitle() == message_title): (transactional_event.getTitle() == message_title):
return transactional_event return transactional_event
...@@ -28,14 +42,12 @@ event.edit( ...@@ -28,14 +42,12 @@ event.edit(
text_content=message, text_content=message,
start_date = DateTime(), start_date = DateTime(),
resource = resource, resource = resource,
source=support_request.getSource(), source=upgrade_decision.getSource(),
destination=destination_relative_url, destination=destination_relative_url,
follow_up=support_request.getRelativeUrl(), follow_up=upgrade_decision.getRelativeUrl(),
) )
event.stop() event.stop()
event.deliver() event.deliver()
support_request.serialize() upgrade_decision.serialize()
context.REQUEST.set("support_request_notified_item", event) upgrade_decision.REQUEST.set("upgrade_decision_notified_item", event)
return event
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_UpgradeDecision_notify</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>UpgradeDecision_notify</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
if context.getSimulationState() != 'started': upgrade_decision = state_change["object"]
# Update Decision is not on started state, Upgrade is not possible! from DateTime import DateTime
return False
instance_tree = context.UpgradeDecision_getInstanceTree() if upgrade_decision.getSimulationState() != 'started':
software_release = context.UpgradeDecision_getSoftwareRelease() # Update Decision is not on started state, Upgrade is not possible!
return
if instance_tree is None: instance_tree = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
return False software_release = upgrade_decision.UpgradeDecision_getAggregateValue("Software Release")
compute_node = upgrade_decision.UpgradeDecision_getAggregateValue("Compute Node")
if software_release is None: if software_release is None:
return False return
if compute_node is None and instance_tree is None:
return
if compute_node is not None and instance_tree is not None:
raise ValueError("Something is wrong, you cannot upgrade Compute Node and Instance Tree on the same decision.")
software_release_url = software_release.getUrlString() software_release_url = software_release.getUrlString()
person = instance_tree.getDestinationSectionValue(portal_type="Person")
if compute_node is not None:
compute_node.requestSoftwareRelease(
software_release_url=software_release_url,
state="available")
upgrade_decision.stop(comment="Upgrade Processed for the Compute Node!")
return
# Test if the Software is available at the ComputeNode. # Test if the Software is available at the ComputeNode.
if not instance_tree.InstanceTree_isUpgradePossible( if not instance_tree.InstanceTree_isUpgradePossible(
...@@ -26,7 +40,8 @@ elif status == "stop_requested": ...@@ -26,7 +40,8 @@ elif status == "stop_requested":
state = "stopped" state = "stopped"
elif status == "destroy_requested": elif status == "destroy_requested":
state = "destroyed" state = "destroyed"
person = instance_tree.getDestinationSectionValue(portal_type="Person")
person.requestSoftwareInstance( person.requestSoftwareInstance(
state=state, state=state,
software_release=software_release_url, software_release=software_release_url,
...@@ -37,6 +52,5 @@ person.requestSoftwareInstance( ...@@ -37,6 +52,5 @@ person.requestSoftwareInstance(
shared=instance_tree.isRootSlave() shared=instance_tree.isRootSlave()
) )
context.stop() upgrade_decision.stop(
comment="Upgrade Processed for the Instance Tree!")
return True
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_UpgradeDecision_requestUpgrade</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>UpgradeDecision_requestUpgrade</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
upgrade_decision = context upgrade_decision = state_change["object"]
from DateTime import DateTime
cancellable_state_list = ['confirmed', 'planned'] cancellable_state_list = ['confirmed', 'planned']
require_state_list = ['rejected', 'confirmed', 'planned'] require_state_list = ['rejected', 'confirmed', 'planned']
simulation_state = upgrade_decision.getSimulationState() simulation_state = upgrade_decision.getSimulationState()
# Get required arguments
kwargs = state_change.kwargs
# Required args
# Raise TypeError if all parameters are not provided
try:
software_release_url = kwargs['software_release_url']
except KeyError:
raise TypeError("UpgradeDecision_reviewRegistration takes exactly 1 arguments")
if simulation_state in require_state_list: if simulation_state in require_state_list:
current_release = upgrade_decision.UpgradeDecision_getSoftwareRelease() current_release = upgrade_decision.UpgradeDecision_getAggregateValue("Software Release")
if not current_release: if not current_release:
# This upgrade decision is not valid # This upgrade decision is not valid
return False return
instance_tree = upgrade_decision.UpgradeDecision_getInstanceTree()
instance_tree = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
if instance_tree is not None: if instance_tree is not None:
current_instance_tree_release = instance_tree.getUrlString() current_instance_tree_release = instance_tree.getUrlString()
if current_instance_tree_release == new_url_string: if current_instance_tree_release == software_release_url:
if simulation_state in cancellable_state_list: if simulation_state in cancellable_state_list:
upgrade_decision.cancel() upgrade_decision.cancel(comment="Instance tree is already upgraded.")
return True return
if current_release.getUrlString() == new_url_string: if current_release.getUrlString() == software_release_url:
# Cannot cancel because the software releases are the same # Cannot cancel because the software releases are the same
return False return False
if simulation_state in cancellable_state_list: if simulation_state in cancellable_state_list:
upgrade_decision.cancel() upgrade_decision.cancel()
return True
else:
return False
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/> <global name="Workflow Script" module="erp5.portal_type"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
...@@ -50,11 +50,33 @@ ...@@ -50,11 +50,33 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string></string> </value> <value> <string>state_change</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>UpgradeDecision_getSoftwareRelease</string> </value> <value> <string>script_UpgradeDecision_reviewRegistration</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>UpgradeDecision_reviewRegistration</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
upgrade_decision = state_change["object"]
from DateTime import DateTime
portal = upgrade_decision.getPortalObject()
instance_tree = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
software_release = upgrade_decision.UpgradeDecision_getAggregateValue("Software Release")
if upgrade_decision.getSimulationState() == "cancelled":
return
if software_release.getValidationState() == "archived":
upgrade_decision.cancel(comment="Software Release is archived.")
return
if instance_tree is not None:
if instance_tree.getUpgradeScope() in ['never', 'disabled']:
upgrade_decision.cancel("Upgrade scope was disabled on the related Instance Tree")
elif instance_tree.getSlapState() == "destroy_requested":
upgrade_decision.cancel(comment="Instance Tree is destroyed.")
elif instance_tree.getUrlString() == software_release.getUrlString():
upgrade_decision.cancel(comment="Instance tree is already upgraded.")
return
compute_node = upgrade_decision.UpgradeDecision_getAggregateValue("Compute Node")
if compute_node is not None:
if compute_node.getUpgradeScope() in ['never', 'disabled']:
upgrade_decision.cancel("Upgrade scope was disabled on the related Instance Tree")
return
elif compute_node.getAllocationScope() in ["closed/forever", "closed/termination"]:
upgrade_decision.cancel(comment="Compute Node is closed.")
return
already_deployed = len(portal.portal_catalog(limit=1,
portal_type="Compute Partition",
parent_reference=compute_node.getReference(),
software_release_url=software_release.getUrlString()))
if already_deployed:
upgrade_decision.cancel(comment="Compute Node already has the software release")
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_UpgradeDecision_reviewUpgrade</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>UpgradeDecision_reviewUpgrade</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow State" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>acquire_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>destination/portal_workflow/upgrade_slap_interface_workflow/transition_approve_registration</string>
<string>destination/portal_workflow/upgrade_slap_interface_workflow/transition_notify</string>
<string>destination/portal_workflow/upgrade_slap_interface_workflow/transition_request_upgrade</string>
<string>destination/portal_workflow/upgrade_slap_interface_workflow/transition_review_registration</string>
<string>destination/portal_workflow/upgrade_slap_interface_workflow/transition_review_upgrade</string>
</tuple>
</value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>state_draft</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow State</string> </value>
</item>
<item>
<key> <string>state_permission_role_list_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>state_type</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Draft</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Transition" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency</string>
<string>after_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_approveRegistration</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_approve_registration</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Approve Registration</string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Transition" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency</string>
<string>after_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_notify</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Create an event for the Upgrade Decision</string> </value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_notify</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Notify</string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Transition" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency</string>
<string>after_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_requestUpgrade</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Perform the Upgrade</string> </value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_request_upgrade</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Request Upgrade</string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Transition" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency</string>
<string>after_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_reviewRegistration</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Cancel if the current upgrade isn\'t valid anymore. </string> </value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_review_registration</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Review Registration</string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Transition" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency</string>
<string>after_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_reviewUpgrade</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Review if the upgrade still applicable</string> </value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_review_upgrade</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Review Upgrade</string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>The last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_action</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>transition/getReference|nothing</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>The name of the user who performed the last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_actor</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>user/getUserName</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Comments about the last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_comment</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>python:state_change.kwargs.get(\'comment\', \'\')</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Error message if validation failed</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_error_message</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Provides access to workflow history</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_history</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>state_change/getHistory</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>portal type (use as filter for worklists)</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_portal_type</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Time of the last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_time</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>state_change/getDateTime</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -2,4 +2,5 @@ Software Product | -validation_workflow ...@@ -2,4 +2,5 @@ Software Product | -validation_workflow
Software Product | commerce_validation_workflow Software Product | commerce_validation_workflow
Upgrade Decision | edit_workflow Upgrade Decision | edit_workflow
Upgrade Decision | ticket_interaction_workflow Upgrade Decision | ticket_interaction_workflow
Upgrade Decision | upgrade_decision_workflow Upgrade Decision | upgrade_decision_workflow
\ No newline at end of file Upgrade Decision | upgrade_slap_interface_workflow
\ No newline at end of file
test.erp5.testSlapOSPDMAlarm test.erp5.testSlapOSPDMAlarm
test.erp5.testSlapOSPDMSkins test.erp5.testSlapOSPDMSkins
test.erp5.testSlapOSPDMDestroySoftwareInstallationWithArchivedSoftwareReleaseAlarm test.erp5.testSlapOSPDMDestroySoftwareInstallationWithArchivedSoftwareReleaseAlarm
test.erp5.testSlapOSPDMCreateUpgradeDecisionSkins test.erp5.testSlapOSPDMCreateUpgradeDecisionSkins
\ No newline at end of file test.erp5.testSlapOSCloudUpgradeSlapInterfaceWorkflow
\ No newline at end of file
upgrade_decision_workflow upgrade_decision_workflow
\ No newline at end of file upgrade_slap_interface_workflow
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment