From e6d9f4fa82c1dff1ceccfb9bba792646fddb17d6 Mon Sep 17 00:00:00 2001 From: Romain Courteaud <romain@nexedi.com> Date: Wed, 25 Jan 2023 13:33:44 +0000 Subject: [PATCH] slapos_cloud: * drop not needed log * commit module business_application * fix SLA tests --- .../hosting_subscription_module.xml | 3 + .../instance_tree_module.xml | 3 + .../software_installation_module.xml | 3 + .../software_instance_module.xml | 3 + .../slapos_cloud/Person_findPartition.py | 2 - .../test.erp5.SlapOSTestCaseMixin.py | 87 +++++++++- ...est.erp5.testSlapOSCloudAllocationAlarm.py | 154 +++++++----------- .../test.erp5.testSlapOSCloudUpgrader.py | 6 +- 8 files changed, 160 insertions(+), 101 deletions(-) diff --git a/master/bt5/slapos_cloud/ModuleTemplateItem/hosting_subscription_module.xml b/master/bt5/slapos_cloud/ModuleTemplateItem/hosting_subscription_module.xml index 8b5bcdde4..d22c7e201 100644 --- a/master/bt5/slapos_cloud/ModuleTemplateItem/hosting_subscription_module.xml +++ b/master/bt5/slapos_cloud/ModuleTemplateItem/hosting_subscription_module.xml @@ -1,4 +1,7 @@ <module> + <category_list> + <category>business_application/slapos</category> + </category_list> <id>hosting_subscription_module</id> <permission_list> <permission type='tuple'> diff --git a/master/bt5/slapos_cloud/ModuleTemplateItem/instance_tree_module.xml b/master/bt5/slapos_cloud/ModuleTemplateItem/instance_tree_module.xml index 270efa7eb..f0673de3b 100644 --- a/master/bt5/slapos_cloud/ModuleTemplateItem/instance_tree_module.xml +++ b/master/bt5/slapos_cloud/ModuleTemplateItem/instance_tree_module.xml @@ -1,4 +1,7 @@ <module> + <category_list> + <category>business_application/slapos</category> + </category_list> <id>instance_tree_module</id> <permission_list> <permission type='tuple'> diff --git a/master/bt5/slapos_cloud/ModuleTemplateItem/software_installation_module.xml b/master/bt5/slapos_cloud/ModuleTemplateItem/software_installation_module.xml index 8aba6b714..05caca6d7 100644 --- a/master/bt5/slapos_cloud/ModuleTemplateItem/software_installation_module.xml +++ b/master/bt5/slapos_cloud/ModuleTemplateItem/software_installation_module.xml @@ -1,4 +1,7 @@ <module> + <category_list> + <category>business_application/slapos</category> + </category_list> <id>software_installation_module</id> <permission_list> <permission type='tuple'> diff --git a/master/bt5/slapos_cloud/ModuleTemplateItem/software_instance_module.xml b/master/bt5/slapos_cloud/ModuleTemplateItem/software_instance_module.xml index e11b31697..2b522e46a 100644 --- a/master/bt5/slapos_cloud/ModuleTemplateItem/software_instance_module.xml +++ b/master/bt5/slapos_cloud/ModuleTemplateItem/software_instance_module.xml @@ -1,4 +1,7 @@ <module> + <category_list> + <category>business_application/slapos</category> + </category_list> <id>software_instance_module</id> <permission_list> <permission type='tuple'> diff --git a/master/bt5/slapos_cloud/SkinTemplateItem/portal_skins/slapos_cloud/Person_findPartition.py b/master/bt5/slapos_cloud/SkinTemplateItem/portal_skins/slapos_cloud/Person_findPartition.py index 2d3f7642c..a6f6ae01c 100644 --- a/master/bt5/slapos_cloud/SkinTemplateItem/portal_skins/slapos_cloud/Person_findPartition.py +++ b/master/bt5/slapos_cloud/SkinTemplateItem/portal_skins/slapos_cloud/Person_findPartition.py @@ -180,8 +180,6 @@ if test_mode: SQL_WINDOW_SIZE = 50 -context.log(portal.portal_catalog.countResults(src__=1, **query_kw)) - # fetch at mot 50 random Compute Partitions, and check if they are ok isTransitionPossible = portal.portal_workflow.isTransitionPossible result_count = portal.portal_catalog.countResults(**query_kw)[0][0] diff --git a/master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.SlapOSTestCaseMixin.py b/master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.SlapOSTestCaseMixin.py index 3e40b129f..bdd10d7ab 100644 --- a/master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.SlapOSTestCaseMixin.py +++ b/master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.SlapOSTestCaseMixin.py @@ -81,7 +81,7 @@ def withAbort(func): 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): self.script_name = script_name @@ -611,6 +611,91 @@ class SlapOSTestCaseMixin(testSlapOSMixin): 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, software_release, software_type, destination_value=None, diff --git a/master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudAllocationAlarm.py b/master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudAllocationAlarm.py index 5a859f2ea..002f113b6 100644 --- a/master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudAllocationAlarm.py +++ b/master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudAllocationAlarm.py @@ -1,7 +1,6 @@ # Copyright (c) 2002-2012 Nexedi SA and Contributors. All Rights Reserved. import transaction -from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin, simulate -from Products.ERP5Type.tests.utils import createZODBPythonScript +from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin, simulate, TemporaryAlarmScript from unittest import skip @@ -15,43 +14,11 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin): SlapOSTestCaseMixin._makeTree(self, project, 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): self._makeTree(self.project) - self._simulatePerson_isAllowedToAllocate() - try: + with TemporaryAlarmScript(self.portal, 'Person_isAllowedToAllocate', + fake_return="True"): self.software_instance.SoftwareInstance_tryToAllocatePartition() - finally: - self._dropPerson_isAllowedToAllocate() self.assertEqual( 'Visited by Person_isAllowedToAllocate', self.person_user.workflow_history['edit_workflow'][-1]['comment']) @@ -65,11 +32,9 @@ return True""" ) self.assertEqual(None, self.software_instance.getAggregateValue( portal_type='Compute Partition')) - self._simulatePerson_isNotAllowedToAllocate() - try: + with TemporaryAlarmScript(self.portal, 'Person_isAllowedToAllocate', + fake_return="False"): self.software_instance.SoftwareInstance_tryToAllocatePartition() - finally: - self._dropPerson_isAllowedToAllocate() self.assertEqual(None, self.software_instance.getAggregateValue( portal_type='Compute Partition')) self.assertEqual( @@ -229,34 +194,17 @@ return True""" ) portal_type='Compute Partition')) transaction.abort() - def _simulateSoftwareInstance_tryToAllocatePartition(self): - script_name = 'SoftwareInstance_tryToAllocatePartition' - 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() - + ################################################## + # alarm slapos_allocate_instance + ################################################## @simulate('Person_isAllowedToAllocate', '*args, **kwargs', 'return True') def test_alarm_software_instance_unallocated(self): self._makeTree(self.project) - self._simulateSoftwareInstance_tryToAllocatePartition() - try: + with TemporaryAlarmScript(self.portal, 'SoftwareInstance_tryToAllocatePartition'): self.portal.portal_alarms.slapos_allocate_instance.activeSense() self.tic() - finally: - self._dropSoftwareInstance_tryToAllocatePartition() + self.assertEqual( 'Visited by SoftwareInstance_tryToAllocatePartition', self.software_instance.workflow_history['edit_workflow'][-1]['comment']) @@ -265,12 +213,10 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by S def test_alarm_slave_instance_unallocated(self): self._makeSlaveTree(self.project) - self._simulateSoftwareInstance_tryToAllocatePartition() - try: + with TemporaryAlarmScript(self.portal, 'SoftwareInstance_tryToAllocatePartition'): self.portal.portal_alarms.slapos_allocate_instance.activeSense() self.tic() - finally: - self._dropSoftwareInstance_tryToAllocatePartition() + self.assertEqual( 'Visited by SoftwareInstance_tryToAllocatePartition', self.software_instance.workflow_history['edit_workflow'][-1]['comment']) @@ -282,12 +228,11 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by S self._makeComputeNode(self.project) self.software_instance.setAggregate(self.partition.getRelativeUrl()) self.tic() - self._simulateSoftwareInstance_tryToAllocatePartition() - try: + + with TemporaryAlarmScript(self.portal, 'SoftwareInstance_tryToAllocatePartition'): self.portal.portal_alarms.slapos_allocate_instance.activeSense() self.tic() - finally: - self._dropSoftwareInstance_tryToAllocatePartition() + self.assertNotEqual( 'Visited by SoftwareInstance_tryToAllocatePartition', self.software_instance.workflow_history['edit_workflow'][-1]['comment']) @@ -299,16 +244,18 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by S self._makeComputeNode(self.project) self.software_instance.setAggregate(self.partition.getRelativeUrl()) self.tic() - self._simulateSoftwareInstance_tryToAllocatePartition() - try: + + with TemporaryAlarmScript(self.portal, 'SoftwareInstance_tryToAllocatePartition'): self.portal.portal_alarms.slapos_allocate_instance.activeSense() self.tic() - finally: - self._dropSoftwareInstance_tryToAllocatePartition() + self.assertNotEqual( 'Visited by SoftwareInstance_tryToAllocatePartition', self.software_instance.workflow_history['edit_workflow'][-1]['comment']) + ################################################## + # SoftwareInstance_tryToAllocatePartition + ################################################## @simulate('Person_isAllowedToAllocate', '*args, **kwargs', 'return True') def test_allocation_computer_guid(self): self._makeTree(self.project) @@ -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, 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) - self.assertEqual(self.compute_node.getAllocationScope(), "open") - self.assertEqual(self.compute_node.getCapacityScope(), "open") - self.compute_node.edit(**{base_category: compute_node_category}) - self.assertEqual(self.compute_node.getAllocationScope(), "open") - self.assertEqual(self.compute_node.getCapacityScope(), "open") + partition = compute_node.newContent( + portal_type='Compute Partition', + reference='reference%s' % self.generateNewId() + ) + partition.validate() + partition.markFree() - self._installSoftware(self.compute_node, - self.software_instance.getUrlString()) + self.assertEqual(compute_node.getAllocationScope(), "open") + 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')) # Another category - self.software_instance.setSlaXml("""<?xml version='1.0' encoding='utf-8'?> + software_instance.setSlaXml("""<?xml version='1.0' encoding='utf-8'?> <instance> <parameter id='%s'>%s</parameter> </instance>""" % (base_category, other_category)) - self.software_instance.SoftwareInstance_tryToAllocatePartition() + software_instance.SoftwareInstance_tryToAllocatePartition() self.assertEqual(None, - self.software_instance.getAggregate(portal_type='Compute Partition')) + software_instance.getAggregate(portal_type='Compute Partition')) # 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> <parameter id='%s'>foo</parameter> </instance>""" % (base_category)) - self.software_instance.SoftwareInstance_tryToAllocatePartition() + software_instance.SoftwareInstance_tryToAllocatePartition() self.assertEqual(None, - self.software_instance.getAggregate(portal_type='Compute Partition')) + software_instance.getAggregate(portal_type='Compute Partition')) # 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> <parameter id='%s'>%s</parameter> </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: - raise ValueError(self.software_instance) - self.assertEqual(self.partition.getRelativeUrl(), - self.software_instance.getAggregate(portal_type='Compute Partition')) + self.assertEqual( + compute_node.contentValues(portal_type='Compute Partition')[0].getRelativeUrl(), + software_instance.getAggregate(portal_type='Compute Partition'), + software_instance.getRelativeUrl() + ) @simulate('Person_isAllowedToAllocate', '*args, **kwargs', 'return True') def test_allocation_group_sla(self): diff --git a/master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudUpgrader.py b/master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudUpgrader.py index 1f85dfb20..eb08b1eaf 100644 --- a/master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudUpgrader.py +++ b/master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudUpgrader.py @@ -157,13 +157,15 @@ class TestSlapOSCloudUpgrader(SlapOSTestCaseMixin): computer_module = self.portal.getDefaultModule('Computer') computer_nothing_to_migrate = computer_module.newContent( - portal_type='Computer' + portal_type='Computer', + title='not to migrate' ) computer_to_migrate = computer_module.newContent( portal_type='Computer', quantity=99, - bar='foo3' + bar='foo3', + title='to migrate' ) # Create fake workflow history -- 2.30.9