Commit b56538c9 authored by Romain Courteaud's avatar Romain Courteaud

slapos_cloud: fix SLA tests

parent dea873c9
...@@ -81,7 +81,7 @@ def withAbort(func): ...@@ -81,7 +81,7 @@ def withAbort(func):
class TemporaryAlarmScript(object): class TemporaryAlarmScript(object):
""" """
Context manager for temporary python scripts Context manager for temporary alarm python scripts
""" """
def __init__(self, portal, script_name, fake_return="", attribute=None): def __init__(self, portal, script_name, fake_return="", attribute=None):
self.script_name = script_name self.script_name = script_name
...@@ -611,6 +611,91 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -611,6 +611,91 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
url_string='type%s' % self.generateNewId(), url_string='type%s' % self.generateNewId(),
) )
def bootstrapAllocableInstanceTree(self, is_allocated=False, shared=False, node="compute"):
project = self.addProject()
person = self.makePerson(project)
software_product = self._makeSoftwareProduct(project)
release_variation = software_product.contentValues(portal_type='Software Product Release Variation')[0]
type_variation = software_product.contentValues(portal_type='Software Product Type Variation')[0]
self.tic()
if node == "compute":
person.requestComputeNode(compute_node_title='test compute node',
project_reference=project.getReference())
self.tic()
compute_node = self.portal.portal_catalog.getResultValue(
portal_type='Compute Node',
reference=self.portal.REQUEST.get('compute_node_reference')
)
assert compute_node is not None
# The edit above will update capacity scope due the interaction workflow
# The line above force capacity scope to be open, keeping the previous
# behaviour.
compute_node.edit(capacity_scope='open')
elif node == "remote":
compute_node = self.portal.compute_node_module.newContent(
portal_type="Remote Node",
follow_up_value=project
)
elif node == "instance":
compute_node = self.portal.compute_node_module.newContent(
portal_type="Instance Node",
follow_up_value=project
)
else:
raise ValueError("Unsupported node value: %s" % node)
request_kw = dict(
software_release=release_variation.getUrlString(),
software_type=type_variation.getTitle(),
instance_xml=self.generateSafeXml(),
sla_xml=self.generateSafeXml(),
shared=shared,
software_title='test tree',
state='started',
project_reference=project.getReference()
)
person.requestSoftwareInstance(**request_kw)
instance_tree = self.portal.REQUEST.get('request_instance_tree')
if is_allocated:
if (node == "instance") and (shared):
real_compute_node = self.portal.compute_node_module.newContent(
portal_type="Compute Node",
follow_up_value=project
)
# The edit above will update capacity scope due the interaction workflow
# The line above force capacity scope to be open, keeping the previous
# behaviour.
real_compute_node.edit(capacity_scope='open')
real_compute_node.validate()
partition = real_compute_node.newContent(
portal_type='Compute Partition',
reference='reference%s' % self.generateNewId()
)
software_instance = self.portal.software_instance_module.newContent(
portal_type="Software Instance",
follow_up_value=project,
aggregate_value=partition
)
compute_node.edit(specialise_value=software_instance)
elif (node == "instance") and (not shared):
raise NotImplementedError('can not allocate on instance node')
else:
partition = compute_node.newContent(
portal_type='Compute Partition',
reference='reference%s' % self.generateNewId()
)
instance = instance_tree.getSuccessorValue()
instance.edit(aggregate_value=partition)
partition.validate()
partition.markFree()
partition.markBusy()
self.tic()
return software_product, release_variation, type_variation, compute_node, instance_tree
def addAllocationSupply(self, title, node, software_product, def addAllocationSupply(self, title, node, software_product,
software_release, software_type, software_release, software_type,
destination_value=None, destination_value=None,
......
# Copyright (c) 2002-2012 Nexedi SA and Contributors. All Rights Reserved. # Copyright (c) 2002-2012 Nexedi SA and Contributors. All Rights Reserved.
import transaction import transaction
from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin, simulate from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin, simulate, TemporaryAlarmScript
from Products.ERP5Type.tests.utils import createZODBPythonScript
from unittest import skip from unittest import skip
...@@ -15,43 +14,11 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin): ...@@ -15,43 +14,11 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin):
SlapOSTestCaseMixin._makeTree(self, project, SlapOSTestCaseMixin._makeTree(self, project,
requested_template_id=requested_template_id) requested_template_id=requested_template_id)
def _simulatePerson_isAllowedToAllocate(self):
script_name = 'Person_isAllowedToAllocate'
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, **kwargs',
'# Script body\n'
"""portal_workflow = context.portal_workflow
portal_workflow.doActionFor(context, action='edit_action', comment='Visited by Person_isAllowedToAllocate')
return True""" )
transaction.commit()
def _simulatePerson_isNotAllowedToAllocate(self):
script_name = 'Person_isAllowedToAllocate'
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, **kwargs',
'# Script body\n'
"""return False""")
transaction.commit()
def _dropPerson_isAllowedToAllocate(self):
script_name = 'Person_isAllowedToAllocate'
if script_name in self.portal.portal_skins.custom.objectIds():
self.portal.portal_skins.custom.manage_delObjects(script_name)
transaction.commit()
def test_person_allocation_checked(self): def test_person_allocation_checked(self):
self._makeTree(self.project) self._makeTree(self.project)
self._simulatePerson_isAllowedToAllocate() with TemporaryAlarmScript(self.portal, 'Person_isAllowedToAllocate',
try: fake_return="True"):
self.software_instance.SoftwareInstance_tryToAllocatePartition() self.software_instance.SoftwareInstance_tryToAllocatePartition()
finally:
self._dropPerson_isAllowedToAllocate()
self.assertEqual( self.assertEqual(
'Visited by Person_isAllowedToAllocate', 'Visited by Person_isAllowedToAllocate',
self.person_user.workflow_history['edit_workflow'][-1]['comment']) self.person_user.workflow_history['edit_workflow'][-1]['comment'])
...@@ -65,11 +32,9 @@ return True""" ) ...@@ -65,11 +32,9 @@ return True""" )
self.assertEqual(None, self.software_instance.getAggregateValue( self.assertEqual(None, self.software_instance.getAggregateValue(
portal_type='Compute Partition')) portal_type='Compute Partition'))
self._simulatePerson_isNotAllowedToAllocate() with TemporaryAlarmScript(self.portal, 'Person_isAllowedToAllocate',
try: fake_return="False"):
self.software_instance.SoftwareInstance_tryToAllocatePartition() self.software_instance.SoftwareInstance_tryToAllocatePartition()
finally:
self._dropPerson_isAllowedToAllocate()
self.assertEqual(None, self.software_instance.getAggregateValue( self.assertEqual(None, self.software_instance.getAggregateValue(
portal_type='Compute Partition')) portal_type='Compute Partition'))
self.assertEqual( self.assertEqual(
...@@ -229,34 +194,17 @@ return True""" ) ...@@ -229,34 +194,17 @@ return True""" )
portal_type='Compute Partition')) portal_type='Compute Partition'))
transaction.abort() transaction.abort()
def _simulateSoftwareInstance_tryToAllocatePartition(self): ##################################################
script_name = 'SoftwareInstance_tryToAllocatePartition' # alarm slapos_allocate_instance
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, **kwargs',
'# Script body\n'
"""portal_workflow = context.portal_workflow
portal_workflow.doActionFor(context, action='edit_action', comment='Visited by SoftwareInstance_tryToAllocatePartition') """ )
transaction.commit()
def _dropSoftwareInstance_tryToAllocatePartition(self):
script_name = 'SoftwareInstance_tryToAllocatePartition'
if script_name in self.portal.portal_skins.custom.objectIds():
self.portal.portal_skins.custom.manage_delObjects(script_name)
transaction.commit()
@simulate('Person_isAllowedToAllocate', '*args, **kwargs', 'return True') @simulate('Person_isAllowedToAllocate', '*args, **kwargs', 'return True')
def test_alarm_software_instance_unallocated(self): def test_alarm_software_instance_unallocated(self):
self._makeTree(self.project) self._makeTree(self.project)
self._simulateSoftwareInstance_tryToAllocatePartition() with TemporaryAlarmScript(self.portal, 'SoftwareInstance_tryToAllocatePartition'):
try:
self.portal.portal_alarms.slapos_allocate_instance.activeSense() self.portal.portal_alarms.slapos_allocate_instance.activeSense()
self.tic() self.tic()
finally:
self._dropSoftwareInstance_tryToAllocatePartition()
self.assertEqual( self.assertEqual(
'Visited by SoftwareInstance_tryToAllocatePartition', 'Visited by SoftwareInstance_tryToAllocatePartition',
self.software_instance.workflow_history['edit_workflow'][-1]['comment']) self.software_instance.workflow_history['edit_workflow'][-1]['comment'])
...@@ -265,12 +213,10 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by S ...@@ -265,12 +213,10 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by S
def test_alarm_slave_instance_unallocated(self): def test_alarm_slave_instance_unallocated(self):
self._makeSlaveTree(self.project) self._makeSlaveTree(self.project)
self._simulateSoftwareInstance_tryToAllocatePartition() with TemporaryAlarmScript(self.portal, 'SoftwareInstance_tryToAllocatePartition'):
try:
self.portal.portal_alarms.slapos_allocate_instance.activeSense() self.portal.portal_alarms.slapos_allocate_instance.activeSense()
self.tic() self.tic()
finally:
self._dropSoftwareInstance_tryToAllocatePartition()
self.assertEqual( self.assertEqual(
'Visited by SoftwareInstance_tryToAllocatePartition', 'Visited by SoftwareInstance_tryToAllocatePartition',
self.software_instance.workflow_history['edit_workflow'][-1]['comment']) self.software_instance.workflow_history['edit_workflow'][-1]['comment'])
...@@ -282,12 +228,11 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by S ...@@ -282,12 +228,11 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by S
self._makeComputeNode(self.project) self._makeComputeNode(self.project)
self.software_instance.setAggregate(self.partition.getRelativeUrl()) self.software_instance.setAggregate(self.partition.getRelativeUrl())
self.tic() self.tic()
self._simulateSoftwareInstance_tryToAllocatePartition()
try: with TemporaryAlarmScript(self.portal, 'SoftwareInstance_tryToAllocatePartition'):
self.portal.portal_alarms.slapos_allocate_instance.activeSense() self.portal.portal_alarms.slapos_allocate_instance.activeSense()
self.tic() self.tic()
finally:
self._dropSoftwareInstance_tryToAllocatePartition()
self.assertNotEqual( self.assertNotEqual(
'Visited by SoftwareInstance_tryToAllocatePartition', 'Visited by SoftwareInstance_tryToAllocatePartition',
self.software_instance.workflow_history['edit_workflow'][-1]['comment']) self.software_instance.workflow_history['edit_workflow'][-1]['comment'])
...@@ -299,16 +244,18 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by S ...@@ -299,16 +244,18 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by S
self._makeComputeNode(self.project) self._makeComputeNode(self.project)
self.software_instance.setAggregate(self.partition.getRelativeUrl()) self.software_instance.setAggregate(self.partition.getRelativeUrl())
self.tic() self.tic()
self._simulateSoftwareInstance_tryToAllocatePartition()
try: with TemporaryAlarmScript(self.portal, 'SoftwareInstance_tryToAllocatePartition'):
self.portal.portal_alarms.slapos_allocate_instance.activeSense() self.portal.portal_alarms.slapos_allocate_instance.activeSense()
self.tic() self.tic()
finally:
self._dropSoftwareInstance_tryToAllocatePartition()
self.assertNotEqual( self.assertNotEqual(
'Visited by SoftwareInstance_tryToAllocatePartition', 'Visited by SoftwareInstance_tryToAllocatePartition',
self.software_instance.workflow_history['edit_workflow'][-1]['comment']) self.software_instance.workflow_history['edit_workflow'][-1]['comment'])
##################################################
# SoftwareInstance_tryToAllocatePartition
##################################################
@simulate('Person_isAllowedToAllocate', '*args, **kwargs', 'return True') @simulate('Person_isAllowedToAllocate', '*args, **kwargs', 'return True')
def test_allocation_computer_guid(self): def test_allocation_computer_guid(self):
self._makeTree(self.project) self._makeTree(self.project)
...@@ -729,50 +676,65 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by S ...@@ -729,50 +676,65 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by S
def check_allocation_category_sla(self, base_category, compute_node_category, def check_allocation_category_sla(self, base_category, compute_node_category,
other_category): other_category):
self._makeTree(self.project) software_product, release_variation, type_variation, compute_node, instance_tree = self.bootstrapAllocableInstanceTree()
self.addAllocationSupply("for compute node", compute_node, software_product,
release_variation, type_variation)
self._installSoftware(
compute_node,
release_variation.getUrlString()
)
self.tic()
self._makeComputeNode(self.project) partition = compute_node.newContent(
self.assertEqual(self.compute_node.getAllocationScope(), "open") portal_type='Compute Partition',
self.assertEqual(self.compute_node.getCapacityScope(), "open") reference='reference%s' % self.generateNewId()
self.compute_node.edit(**{base_category: compute_node_category}) )
self.assertEqual(self.compute_node.getAllocationScope(), "open") partition.validate()
self.assertEqual(self.compute_node.getCapacityScope(), "open") partition.markFree()
self._installSoftware(self.compute_node, self.assertEqual(compute_node.getAllocationScope(), "open")
self.software_instance.getUrlString()) self.assertEqual(compute_node.getCapacityScope(), "open")
compute_node.edit(**{base_category: compute_node_category})
self.assertEqual(compute_node.getAllocationScope(), "open")
self.assertEqual(compute_node.getCapacityScope(), "open")
self.assertEqual(None, self.software_instance.getAggregateValue( self.tic()
software_instance = instance_tree.getSuccessorValue()
self.assertEqual(None, software_instance.getAggregateValue(
portal_type='Compute Partition')) portal_type='Compute Partition'))
# Another category # Another category
self.software_instance.setSlaXml("""<?xml version='1.0' encoding='utf-8'?> software_instance.setSlaXml("""<?xml version='1.0' encoding='utf-8'?>
<instance> <instance>
<parameter id='%s'>%s</parameter> <parameter id='%s'>%s</parameter>
</instance>""" % (base_category, other_category)) </instance>""" % (base_category, other_category))
self.software_instance.SoftwareInstance_tryToAllocatePartition() software_instance.SoftwareInstance_tryToAllocatePartition()
self.assertEqual(None, self.assertEqual(None,
self.software_instance.getAggregate(portal_type='Compute Partition')) software_instance.getAggregate(portal_type='Compute Partition'))
# No existing category # No existing category
self.software_instance.setSlaXml("""<?xml version='1.0' encoding='utf-8'?> software_instance.setSlaXml("""<?xml version='1.0' encoding='utf-8'?>
<instance> <instance>
<parameter id='%s'>foo</parameter> <parameter id='%s'>foo</parameter>
</instance>""" % (base_category)) </instance>""" % (base_category))
self.software_instance.SoftwareInstance_tryToAllocatePartition() software_instance.SoftwareInstance_tryToAllocatePartition()
self.assertEqual(None, self.assertEqual(None,
self.software_instance.getAggregate(portal_type='Compute Partition')) software_instance.getAggregate(portal_type='Compute Partition'))
# Compute Node category # Compute Node category
self.software_instance.setSlaXml("""<?xml version='1.0' encoding='utf-8'?> software_instance.setSlaXml("""<?xml version='1.0' encoding='utf-8'?>
<instance> <instance>
<parameter id='%s'>%s</parameter> <parameter id='%s'>%s</parameter>
</instance>""" % (base_category, compute_node_category)) </instance>""" % (base_category, compute_node_category))
self.software_instance.SoftwareInstance_tryToAllocatePartition() software_instance.SoftwareInstance_tryToAllocatePartition()
if self.software_instance.getAggregate(portal_type='Compute Partition') is None: self.assertEqual(
raise ValueError(self.software_instance) compute_node.contentValues(portal_type='Compute Partition')[0].getRelativeUrl(),
self.assertEqual(self.partition.getRelativeUrl(), software_instance.getAggregate(portal_type='Compute Partition'),
self.software_instance.getAggregate(portal_type='Compute Partition')) software_instance.getRelativeUrl()
)
@simulate('Person_isAllowedToAllocate', '*args, **kwargs', 'return True') @simulate('Person_isAllowedToAllocate', '*args, **kwargs', 'return True')
def test_allocation_group_sla(self): def test_allocation_group_sla(self):
......
...@@ -157,13 +157,15 @@ class TestSlapOSCloudUpgrader(SlapOSTestCaseMixin): ...@@ -157,13 +157,15 @@ class TestSlapOSCloudUpgrader(SlapOSTestCaseMixin):
computer_module = self.portal.getDefaultModule('Computer') computer_module = self.portal.getDefaultModule('Computer')
computer_nothing_to_migrate = computer_module.newContent( computer_nothing_to_migrate = computer_module.newContent(
portal_type='Computer' portal_type='Computer',
title='not to migrate'
) )
computer_to_migrate = computer_module.newContent( computer_to_migrate = computer_module.newContent(
portal_type='Computer', portal_type='Computer',
quantity=99, quantity=99,
bar='foo3' bar='foo3',
title='to migrate'
) )
# Create fake workflow history # Create fake workflow history
......
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