Commit 08396e5e authored by Romain Courteaud's avatar Romain Courteaud

slapos_crm: test InstanceTree_checkSoftwareInstanceState

parent 82db4d63
......@@ -4,10 +4,6 @@ from erp5.component.module.DateUtils import addToDate
instance_tree = context
portal = context.getPortalObject()
if instance_tree.getMonitorScope() == "disabled":
# Don't generate ticket if Monitor Scope is marked to disable
return
if portal.ERP5Site_isSupportRequestCreationClosed():
# Stop ticket creation
return
......@@ -20,14 +16,11 @@ if (date_check_limit - instance_tree.getCreationDate()) < 0:
software_instance_list = context.portal_catalog(
portal_type=["Software Instance", "Slave Instance"],
specialise_uid=instance_tree.getUid(),
specialise__uid=instance_tree.getUid(),
**{"slapos_item.slap_state": ["start_requested"]})
has_newest_allocated_instance = False
has_unallocated_instance = False
failing_instance = None
# Check if at least one software Instance is Allocated
notification_message_reference = None
for instance in software_instance_list:
if (date_check_limit - instance.getCreationDate()) < 0:
continue
......@@ -36,19 +29,48 @@ for instance in software_instance_list:
continue
compute_partition = instance.getAggregateValue()
if compute_partition is not None:
has_newest_allocated_instance = True
if instance.getPortalType() == "Software Instance" and \
compute_partition.getParentValue().getMonitorScope() == "enabled" and \
if compute_partition is None:
notification_message_reference = 'slapos-crm-instance-tree-instance-allocation.notification'
elif (instance.getPortalType() == "Software Instance") and \
(compute_partition.getParentValue().getMonitorScope() == "enabled") and \
instance.SoftwareInstance_hasReportedError(tolerance=30):
return context.InstanceTree_createSupportRequestEvent(
instance, 'slapos-crm-instance-tree-instance-state.notification')
notification_message_reference = 'slapos-crm-instance-tree-instance-state.notification'
if notification_message_reference is not None:
ticket_title = "Instance Tree %s is failing." % context.getTitle()
error_message = instance.SoftwareInstance_hasReportedError(include_message=True)
description = "%s contains software instances which are unallocated or reporting errors." % (
context.getTitle())
if error_message:
description += "\n\nMessage: %s" % str(error_message)
else:
has_unallocated_instance = True
failing_instance = instance
error_message = "No message!"
if has_unallocated_instance and has_newest_allocated_instance:
return context.InstanceTree_createSupportRequestEvent(
failing_instance, 'slapos-crm-instance-tree-instance-allocation.notification')
project = context.getFollowUpValue()
support_request = project.Project_createSupportRequestWithCausality(
ticket_title,
description,
causality=context.getRelativeUrl(),
destination_decision=context.getDestinationSectionValue()
)
if support_request is None:
return
return
event = support_request.SupportRequest_getLastEvent(ticket_title)
if event is None:
support_request.Ticket_createProjectEvent(
ticket_title, 'outgoing', 'Web Message',
portal.service_module.slapos_crm_information.getRelativeUrl(),
text_content=description,
content_type='text/plain',
notification_message=notification_message_reference,
#language=XXX,
substitution_method_parameter_dict={
'instance_tree_title':context.getTitle(),
'instance': instance.getTitle(),
'error_text': error_message
}
)
return
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()
error_message = instance.SoftwareInstance_hasReportedError(include_message=True)
description = "%s contains software instances which are unallocated or reporting errors." % (
context.getTitle())
if error_message:
description += "\n\nMessage: %s" % error_message
else:
error_message = "No message!"
support_request = context.Base_getSupportRequestInProgress(
title=ticket_title)
if support_request is None:
person.notify(support_request_title=ticket_title,
support_request_description=description,
aggregate=context.getRelativeUrl())
support_request_relative_url = context.REQUEST.get("support_request_relative_url")
if support_request_relative_url is None:
return
support_request = portal.restrictedTraverse(support_request_relative_url)
if support_request is None:
return
if support_request.getSimulationState() not in ["validated", "suspended"]:
support_request.validate()
# Send Notification message
message = description
notification_message = portal.portal_notifications.getDocumentValue(
reference=notification_message_reference)
if notification_message is not None:
mapping_dict = {'instance_tree_title':context.getTitle(),
'instance': instance.getTitle(),
'error_text': error_message}
message = notification_message.asText(
substitution_method_parameter_dict={'mapping_dict':mapping_dict})
event = support_request.SupportRequest_getLastEvent(ticket_title)
if event is None:
support_request.notify(message_title=ticket_title, message=message)
return context.REQUEST.get("ticket_notified_item")
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>instance, notification_message_reference</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>InstanceTree_createSupportRequestEvent</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -1037,6 +1037,195 @@ class TestSlapOSCrmMonitoringCheckInstanceInError(SlapOSTestCaseMixinWithAbort):
slapos_crm_check_instance_in_error
self._test_alarm_not_visited(alarm, host_sub, "InstanceTree_checkSoftwareInstanceState")
def _makeNotificationMessage(self, reference):
notification_message = self.portal.notification_message_module.newContent(
portal_type="Notification Message",
title='The Compute Node %s is building for too long' % reference,
text_content='Test NM content<br/>%s<br/>' % reference,
content_type='text/html',
)
return notification_message.getRelativeUrl()
def _getGeneratedSupportRequest(self, compute_node_uid, request_title):
return self.portal.portal_catalog.getResultValue(
portal_type='Support Request',
title=request_title,
simulation_state='validated',
causality__uid=compute_node_uid
)
@simulate('ERP5Site_isSupportRequestCreationClosed', '','return 0')
@simulate('NotificationTool_getDocumentValue',
'reference=None, **kw',
'assert reference == "slapos-crm-instance-tree-instance-state.notification", reference\n' \
'return context.restrictedTraverse(' \
'context.REQUEST["test_InstanceTree_checkSoftwareInstanceState_notify"])')
def test_InstanceTree_checkSoftwareInstanceState_script_notifyError(self):
try:
self.pinDateTime(DateTime()-1.1)
self._makeComputeNode(self.addProject())
self._makeComplexComputeNode(self.addProject())
software_instance = self.start_requested_software_instance
instance_tree = software_instance.getSpecialiseValue()
software_instance.setErrorStatus("")
finally:
self.unpinDateTime()
self.portal.REQUEST['test_InstanceTree_checkSoftwareInstanceState_notify'] = \
self._makeNotificationMessage(instance_tree.getReference())
self.tic()
instance_tree.InstanceTree_checkSoftwareInstanceState()
self.tic()
ticket_title = "Instance Tree %s is failing." % (
instance_tree.getTitle()
)
ticket = self._getGeneratedSupportRequest(instance_tree.getUid(), ticket_title)
self.assertNotEqual(ticket, None)
event_list = ticket.getFollowUpRelatedValueList()
self.assertEqual(len(event_list), 1)
event = event_list[0]
self.assertEqual(event.getTitle(), ticket.getTitle())
self.assertIn(instance_tree.getReference(), event.getTextContent())
self.assertEqual(event.getFollowUp(), ticket.getRelativeUrl())
self.assertEqual(event.getSourceProject(), instance_tree.getFollowUp())
self.assertEqual(ticket.getSourceProject(), instance_tree.getFollowUp())
self.assertEqual(ticket.getCausality(), instance_tree.getRelativeUrl())
self.assertEqual(ticket.getSimulationState(), "validated")
self.assertEqual(event.getSimulationState(), "delivered")
self.assertEqual(event.getPortalType(), "Web Message")
@simulate('ERP5Site_isSupportRequestCreationClosed', '','return 0')
def test_InstanceTree_checkSoftwareInstanceState_script_notifyErrorTolerance(self):
try:
self.pinDateTime(DateTime()-1.1)
self._makeComputeNode(self.addProject())
self._makeComplexComputeNode(self.addProject())
software_instance = self.start_requested_software_instance
instance_tree = software_instance.getSpecialiseValue()
finally:
self.unpinDateTime()
software_instance.setErrorStatus("")
self.portal.REQUEST['test_InstanceTree_checkSoftwareInstanceState_notify'] = \
self._makeNotificationMessage(instance_tree.getReference())
self.tic()
instance_tree.InstanceTree_checkSoftwareInstanceState()
self.tic()
ticket_title = "Instance Tree %s is failing." % (
instance_tree.getTitle()
)
ticket = self._getGeneratedSupportRequest(instance_tree.getUid(), ticket_title)
self.assertEqual(ticket, None)
@simulate('ERP5Site_isSupportRequestCreationClosed', '','return 0')
@simulate('NotificationTool_getDocumentValue',
'reference=None, **kw',
'assert reference == "slapos-crm-instance-tree-instance-allocation.notification", reference\n' \
'return context.restrictedTraverse(' \
'context.REQUEST["test_InstanceTree_checkSoftwareInstanceState_notify"])')
def test_InstanceTree_checkSoftwareInstanceState_script_notifyNotAllocated(self):
try:
self.pinDateTime(DateTime()-1.1)
self._makeComputeNode(self.addProject())
self._makeComplexComputeNode(self.addProject())
software_instance = self.start_requested_software_instance
instance_tree = software_instance.getSpecialiseValue()
finally:
self.unpinDateTime()
self.portal.REQUEST['test_InstanceTree_checkSoftwareInstanceState_notify'] = \
self._makeNotificationMessage(instance_tree.getReference())
self.tic()
software_instance.edit(aggregate=None)
instance_tree.InstanceTree_checkSoftwareInstanceState()
self.tic()
ticket_title = "Instance Tree %s is failing." % (
instance_tree.getTitle()
)
ticket = self._getGeneratedSupportRequest(instance_tree.getUid(), ticket_title)
self.assertNotEqual(ticket, None)
event_list = ticket.getFollowUpRelatedValueList()
self.assertEqual(len(event_list), 1)
event = event_list[0]
self.assertEqual(event.getTitle(), ticket.getTitle())
self.assertIn(instance_tree.getReference(), event.getTextContent())
self.assertEqual(event.getFollowUp(), ticket.getRelativeUrl())
self.assertEqual(event.getSourceProject(), instance_tree.getFollowUp())
self.assertEqual(ticket.getSourceProject(), instance_tree.getFollowUp())
self.assertEqual(ticket.getCausality(), instance_tree.getRelativeUrl())
self.assertEqual(ticket.getSimulationState(), "validated")
self.assertEqual(event.getSimulationState(), "delivered")
self.assertEqual(event.getPortalType(), "Web Message")
@simulate('ERP5Site_isSupportRequestCreationClosed', '','return 0')
def test_InstanceTree_checkSoftwareInstanceState_script_tooEarly(self):
try:
self.pinDateTime(DateTime())
self._makeComputeNode(self.addProject())
self._makeComplexComputeNode(self.addProject())
software_instance = self.start_requested_software_instance
instance_tree = software_instance.getSpecialiseValue()
software_instance.setErrorStatus("")
finally:
self.unpinDateTime()
self.portal.REQUEST['test_InstanceTree_checkSoftwareInstanceState_notify'] = \
self._makeNotificationMessage(instance_tree.getReference())
self.tic()
instance_tree.InstanceTree_checkSoftwareInstanceState()
self.tic()
ticket_title = "Instance Tree %s is failing." % (
instance_tree.getTitle()
)
ticket = self._getGeneratedSupportRequest(instance_tree.getUid(), ticket_title)
self.assertEqual(ticket, None)
@simulate('ERP5Site_isSupportRequestCreationClosed', '','return 1')
def test_InstanceTree_checkSoftwareInstanceState_script_closed(self):
try:
self.pinDateTime(DateTime()-1)
self._makeComputeNode(self.addProject())
self._makeComplexComputeNode(self.addProject())
software_instance = self.start_requested_software_instance
instance_tree = software_instance.getSpecialiseValue()
software_instance.setErrorStatus("")
finally:
self.unpinDateTime()
self.portal.REQUEST['test_InstanceTree_checkSoftwareInstanceState_notify'] = \
self._makeNotificationMessage(instance_tree.getReference())
self.tic()
instance_tree.InstanceTree_checkSoftwareInstanceState()
self.tic()
ticket_title = "Instance Tree %s is failing." % (
instance_tree.getTitle()
)
ticket = self._getGeneratedSupportRequest(instance_tree.getUid(), ticket_title)
self.assertEqual(ticket, None)
class TestSlaposCrmUpdateSupportRequestState(SlapOSTestCaseMixinWithAbort):
......
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