Commit ed984231 authored by Rafael Monnerat's avatar Rafael Monnerat

slapos_cloud: Protect supply against multiple calls on the same request

  This prevents +2 supplies on the request creates more them one software installation with same url on a compute  node.
parent fb3fd309
......@@ -181,6 +181,7 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
def supplySoftware(self, server, url, state='available'):
self.portal.portal_slap.supplySupply(url, server.getReference(), state)
self.tic()
self.cleanUpRequest()
software_installation = self.portal.portal_catalog.getResultValue(
portal_type='Software Installation',
......
......@@ -142,10 +142,9 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
_custom_additional_bt5_list = []
# Used by testSlapOSERP5GroupRoleSecurity.TestSlapOSGroupRoleSecurityCoverage for
# searh classes for assert overage
# search classes for assert overage
security_group_role_test_id_list = ['test.erp5.testSlapOSERP5GroupRoleSecurity']
def afterSetUp(self):
testSlapOSMixin.afterSetUp(self)
self.changeSkin('View')
......@@ -156,6 +155,14 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
"""Overwrite this function on project context to tweak production focus tests"""
pass
def cleanUpRequest(self):
""" set None some values that can cause problems in tests
"""
for key in self.portal.REQUEST.keys():
if key.endswith("_inProgress"):
# Reset values set on script_ComputeNode_requestSoftwareReleaseChange
self.portal.REQUEST.set(key, None)
def addAccountingManagerAssignment(self, person):
person.newContent(
portal_type='Assignment',
......@@ -290,7 +297,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
project_reference=project.getReference()
)
# As the software url does not match any service, and any trade condition
# As the software url does not match any service, and any trade condition
# no instance is automatically created.
# except if we fake Item_getSubscriptionStatus
with TemporaryAlarmScript(self.portal, 'Item_getSubscriptionStatus', "'subscribed'"):
......@@ -352,7 +359,6 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
self.portal.portal_workflow._jumpToStateFor(self.software_instance, 'start_requested')
self.software_instance.validate()
self.requested_software_instance.edit(
title=self.generateNewSoftwareTitle(),
reference="TESTSI-%s" % self.generateNewId(),
......
......@@ -20,7 +20,6 @@
##############################################################################
from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin
import transaction
from unittest import expectedFailure
from Products.ERP5Type.Errors import UnsupportedWorkflowMethod
from cryptography import x509
from cryptography.x509.oid import NameOID
......@@ -234,6 +233,7 @@ class TestSlapOSCoreComputeNodeSlapInterfaceWorkflow(SlapOSTestCaseMixin):
self.compute_node.requestSoftwareRelease(software_release_url=url,
state='available')
self.tic()
self.cleanUpRequest()
self.login()
software_installation = self.compute_node.getAggregateRelatedValue(
portal_type='Software Installation')
......@@ -267,7 +267,6 @@ class TestSlapOSCoreComputeNodeSlapInterfaceWorkflow(SlapOSTestCaseMixin):
state='available')
transaction.abort()
@expectedFailure
def test_requestSoftwareRelease_same_transaction(self):
self.person_user = self.makePerson(self.project)
self.addProjectProductionManagerAssignment(self.person_user, self.project)
......@@ -686,6 +685,7 @@ class TestSlapOSCoreComputeNodeSlapInterfaceWorkflowSupply(SlapOSTestCaseMixin):
software_installation.getReference())
self.tic()
self.cleanUpRequest()
self.compute_node.requestSoftwareRelease(state="available",
software_release_url=software_release)
......@@ -718,6 +718,7 @@ class TestSlapOSCoreComputeNodeSlapInterfaceWorkflowSupply(SlapOSTestCaseMixin):
software_installation.getReference())
self.tic()
self.cleanUpRequest()
self.compute_node.requestSoftwareRelease(state="destroyed",
software_release_url=software_release)
......@@ -759,6 +760,7 @@ class TestSlapOSCoreComputeNodeSlapInterfaceWorkflowSupply(SlapOSTestCaseMixin):
software_installation.getReference())
self.tic()
self.cleanUpRequest()
self.compute_node.requestSoftwareRelease(state="destroyed",
software_release_url=software_release)
......@@ -806,6 +808,7 @@ class TestSlapOSCoreComputeNodeSlapInterfaceWorkflowSupply(SlapOSTestCaseMixin):
software_installation.getReference())
self.tic()
self.cleanUpRequest()
self.compute_node.requestSoftwareRelease(state="destroyed",
software_release_url=software_release)
......
......@@ -14,7 +14,7 @@ except KeyError:
tag = "%s_%s_inProgress" % (compute_node.getUid(),
software_release_url)
if (portal.portal_activities.countMessageWithTag(tag) > 0):
if (portal.portal_activities.countMessageWithTag(tag) > 0 or compute_node.REQUEST.get(tag) == tag):
# 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)
......@@ -41,7 +41,7 @@ else:
if (state == "destroyed"):
# No need to create destroyed subscription.
return
software_installation_reference = "SOFTINSTALL-%s" % context.getPortalObject().portal_ids\
software_installation_reference = "SOFTINSTALL-%s" % portal.portal_ids\
.generateNewId(id_group='slap_software_installation_reference', id_generator='uid')
software_installation = portal.getDefaultModule(portal_type=software_installation_portal_type).newContent(
portal_type=software_installation_portal_type,
......@@ -51,6 +51,7 @@ else:
follow_up_value=compute_node.getFollowUpValue(),
activate_kw={'tag': tag}
)
compute_node.REQUEST.set(tag, tag)
# Change desired state
if (state == "available"):
......@@ -67,4 +68,4 @@ if validation_state == 'draft':
portal.portal_workflow.doActionFor(software_installation,
'validate_action')
context.REQUEST.set('software_installation_url', software_installation.getRelativeUrl())
compute_node.REQUEST.set('software_installation_url', software_installation.getRelativeUrl())
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