Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
slapos.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Paul Graydon
slapos.core
Commits
20a0f457
Commit
20a0f457
authored
Dec 31, 2023
by
Rafael Monnerat
Browse files
Options
Browse Files
Download
Plain Diff
Disable Disconnection of instance on the graph
See merge request
nexedi/slapos.core!591
parents
c988e4a8
2ebb32ba
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
123 additions
and
521 deletions
+123
-521
master/bt5/slapos_cloud/PathTemplateItem/portal_alarms/slapos_garbage_collect_destroy_unlinked_instance.xml
...arms/slapos_garbage_collect_destroy_unlinked_instance.xml
+0
-103
master/bt5/slapos_cloud/SkinTemplateItem/portal_skins/slapos_cloud/Alarm_garbageCollectDestroyUnlinkedInstance.py
...apos_cloud/Alarm_garbageCollectDestroyUnlinkedInstance.py
+0
-13
master/bt5/slapos_cloud/SkinTemplateItem/portal_skins/slapos_cloud/Alarm_garbageCollectDestroyUnlinkedInstance.xml
...pos_cloud/Alarm_garbageCollectDestroyUnlinkedInstance.xml
+0
-62
master/bt5/slapos_cloud/SkinTemplateItem/portal_skins/slapos_cloud/SoftwareInstance_tryToGarbageUnlinkedInstance.py
...os_cloud/SoftwareInstance_tryToGarbageUnlinkedInstance.py
+0
-58
master/bt5/slapos_cloud/SkinTemplateItem/portal_skins/slapos_cloud/SoftwareInstance_tryToGarbageUnlinkedInstance.xml
...s_cloud/SoftwareInstance_tryToGarbageUnlinkedInstance.xml
+0
-62
master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudAlarm.py
...eItem/portal_components/test.erp5.testSlapOSCloudAlarm.py
+0
-222
master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudInstanceSlapInterfaceWorkflow.py
...test.erp5.testSlapOSCloudInstanceSlapInterfaceWorkflow.py
+123
-0
master/bt5/slapos_cloud/bt/template_path_list
master/bt5/slapos_cloud/bt/template_path_list
+0
-1
No files found.
master/bt5/slapos_cloud/PathTemplateItem/portal_alarms/slapos_garbage_collect_destroy_unlinked_instance.xml
deleted
100644 → 0
View file @
c988e4a8
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Alarm"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
active_sense_method_id
</string>
</key>
<value>
<string>
Alarm_garbageCollectDestroyUnlinkedInstance
</string>
</value>
</item>
<item>
<key>
<string>
automatic_solve
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
enabled
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
slapos_garbage_collect_destroy_unlinked_instance
</string>
</value>
</item>
<item>
<key>
<string>
periodicity_hour
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
periodicity_hour_frequency
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
<item>
<key>
<string>
periodicity_minute
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
periodicity_minute_frequency
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
periodicity_month
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
periodicity_month_day
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
periodicity_start_date
</string>
</key>
<value>
<object>
<klass>
<global
name=
"_reconstructor"
module=
"copy_reg"
/>
</klass>
<tuple>
<global
name=
"DateTime"
module=
"DateTime.DateTime"
/>
<global
name=
"object"
module=
"__builtin__"
/>
<none/>
</tuple>
<state>
<tuple>
<float>
15638400.0
</float>
<string>
GMT
</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
periodicity_week
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Alarm
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Garbage Collect Unlinked Instances
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_cloud/SkinTemplateItem/portal_skins/slapos_cloud/Alarm_garbageCollectDestroyUnlinkedInstance.py
deleted
100644 → 0
View file @
c988e4a8
portal
=
context
.
getPortalObject
()
from
Products.ZSQLCatalog.SQLCatalog
import
SimpleQuery
portal
.
portal_catalog
.
searchAndActivate
(
portal_type
=
[
"Software Instance"
,
"Slave Instance"
],
validation_state
=
"validated"
,
specialise_validation_state
=
"validated"
,
successor_related_uid
=
SimpleQuery
(
successor_related_uid
=
None
,
comparison_operator
=
'is'
),
method_id
=
'SoftwareInstance_tryToGarbageUnlinkedInstance'
,
activate_kw
=
{
'tag'
:
tag
}
)
context
.
activate
(
after_tag
=
tag
).
getId
()
master/bt5/slapos_cloud/SkinTemplateItem/portal_skins/slapos_cloud/Alarm_garbageCollectDestroyUnlinkedInstance.xml
deleted
100644 → 0
View file @
c988e4a8
<?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>
tag, fixit, params
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
Alarm_garbageCollectDestroyUnlinkedInstance
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_cloud/SkinTemplateItem/portal_skins/slapos_cloud/SoftwareInstance_tryToGarbageUnlinkedInstance.py
deleted
100644 → 0
View file @
c988e4a8
from
zExceptions
import
Unauthorized
from
DateTime
import
DateTime
from
erp5.component.module.DateUtils
import
addToDate
if
REQUEST
is
not
None
:
raise
Unauthorized
instance
=
context
def
checkInstanceTree
(
instance_list
):
"""
Check if successor link is really removed to this instance
"""
sub_instance_list
=
[]
if
instance_list
==
[]:
return
for
item
in
instance_list
:
if
item
.
getUid
()
==
instance
.
getUid
():
return
item
sub_instance_list
.
extend
(
item
.
getSuccessorValueList
())
return
checkInstanceTree
(
sub_instance_list
)
if
instance
.
getSlapState
()
==
"destroy_requested"
:
return
instance_tree
=
instance
.
getSpecialiseValue
()
if
instance_tree
is
None
or
\
instance_tree
.
getSlapState
()
==
"destroy_requested"
:
return
root_instance
=
instance_tree
.
getSuccessorValue
()
if
root_instance
is
None
:
# Refuse to destroy root instance
raise
ValueError
(
"Instance Tree %s has no root instance, this should "
\
"not happen!!"
%
instance_tree
.
getRelativeUrl
())
# If instance modificationDate is too recent, skip
# Delay destroy of unlinked instances
if
instance
.
getModificationDate
()
-
addToDate
(
DateTime
(),
{
'minute'
:
-
1
*
delay_time
})
>
0
:
return
if
checkInstanceTree
([
root_instance
])
is
None
:
# This unlinked instance to parent should be removed
is_slave
=
False
if
instance
.
getPortalType
()
==
'Slave Instance'
:
is_slave
=
True
promise_kw
=
{
'instance_xml'
:
instance
.
getTextContent
(),
'software_type'
:
instance
.
getSourceReference
(),
'sla_xml'
:
instance
.
getSlaXml
(),
'software_release'
:
instance
.
getUrlString
(),
'shared'
:
is_slave
,
}
instance
.
requestDestroy
(
**
promise_kw
)
# Unlink all children of this instance
instance
.
edit
(
successor
=
""
,
comment
=
"Destroyed garbage collector!"
)
return
instance
.
getRelativeUrl
()
master/bt5/slapos_cloud/SkinTemplateItem/portal_skins/slapos_cloud/SoftwareInstance_tryToGarbageUnlinkedInstance.xml
deleted
100644 → 0
View file @
c988e4a8
<?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>
REQUEST=None, delay_time=50
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
SoftwareInstance_tryToGarbageUnlinkedInstance
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudAlarm.py
View file @
20a0f457
# Copyright (c) 2002-2012 Nexedi SA and Contributors. All Rights Reserved.
import
transaction
from
erp5.component.test.SlapOSTestCaseMixin
import
SlapOSTestCaseMixin
import
time
from
zExceptions
import
Unauthorized
from
DateTime
import
DateTime
from
erp5.component.module.DateUtils
import
addToDate
...
...
@@ -848,227 +847,6 @@ class TestSlapOSGarbageCollectNonAllocatedRootTreeAlarm(SlapOSTestCaseMixin):
)
class
TestSlapOSGarbageCollectUnlinkedInstanceAlarm
(
SlapOSTestCaseMixin
):
def
createInstance
(
self
):
instance_tree
=
self
.
portal
.
instance_tree_module
\
.
template_instance_tree
.
Base_createCloneDocument
(
batch_mode
=
1
)
instance_tree
.
validate
()
instance_tree
.
edit
(
title
=
self
.
generateNewSoftwareTitle
(),
reference
=
"TESTHS-%s"
%
self
.
generateNewId
(),
)
request_kw
=
dict
(
software_release
=
\
self
.
generateNewSoftwareReleaseUrl
(),
software_type
=
self
.
generateNewSoftwareType
(),
instance_xml
=
self
.
generateSafeXml
(),
sla_xml
=
self
.
generateSafeXml
(),
shared
=
False
,
software_title
=
instance_tree
.
getTitle
(),
state
=
'started'
)
instance_tree
.
requestStart
(
**
request_kw
)
instance_tree
.
requestInstance
(
**
request_kw
)
self
.
instance_tree
=
instance_tree
instance
=
instance_tree
.
getSuccessorValue
()
return
instance
def
createComputePartition
(
self
):
compute_node
=
self
.
portal
.
compute_node_module
\
.
template_compute_node
.
Base_createCloneDocument
(
batch_mode
=
1
)
compute_node
.
validate
()
compute_node
.
edit
(
title
=
self
.
generateNewSoftwareTitle
(),
reference
=
"TESTCOMP-%s"
%
self
.
generateNewId
(),
)
partition
=
compute_node
.
newContent
(
portal_type
=
"Compute Partition"
)
return
partition
def
doRequestInstance
(
self
,
instance
,
title
,
slave
=
False
):
instance_kw
=
dict
(
software_release
=
self
.
generateNewSoftwareReleaseUrl
(),
software_type
=
self
.
generateNewSoftwareType
(),
instance_xml
=
self
.
generateSafeXml
(),
sla_xml
=
self
.
generateSafeXml
(),
shared
=
slave
,
software_title
=
title
,
state
=
'started'
)
instance
.
requestInstance
(
**
instance_kw
)
self
.
tic
()
sub_instance
=
instance
.
getSuccessorValue
()
partition
=
self
.
createComputePartition
()
sub_instance
.
edit
(
aggregate_value
=
partition
)
self
.
tic
()
self
.
assertEqual
(
self
.
instance_tree
.
getRelativeUrl
(),
sub_instance
.
getSpecialise
())
return
sub_instance
def
test_SoftwareInstance_tryToGarbageUnlinkedInstance
(
self
):
instance
=
self
.
createInstance
()
partition
=
self
.
createComputePartition
()
instance
.
edit
(
aggregate_value
=
partition
)
self
.
tic
()
instance0
=
self
.
doRequestInstance
(
instance
,
'instance0'
)
self
.
assertEqual
(
instance0
.
getSuccessorRelatedTitle
(),
instance
.
getTitle
())
# Remove successor link
instance
.
edit
(
successor_list
=
[])
self
.
tic
()
self
.
assertEqual
(
instance0
.
getSuccessorRelatedTitle
(),
None
)
instance0
.
SoftwareInstance_tryToGarbageUnlinkedInstance
(
delay_time
=-
1
)
self
.
tic
()
self
.
assertEqual
(
instance0
.
getSlapState
(),
'destroy_requested'
)
def
test_SoftwareInstance_tryToGarbageUnlinkedInstance_hosting_destroyed
(
self
):
instance
=
self
.
createInstance
()
partition
=
self
.
createComputePartition
()
instance
.
edit
(
aggregate_value
=
partition
)
self
.
tic
()
instance0
=
self
.
doRequestInstance
(
instance
,
'instance0'
)
instance
.
edit
(
successor_list
=
[])
self
.
tic
()
self
.
instance_tree
.
archive
()
self
.
portal
.
portal_workflow
.
_jumpToStateFor
(
self
.
instance_tree
,
'destroy_requested'
)
self
.
portal
.
portal_workflow
.
_jumpToStateFor
(
instance
,
'destroy_requested'
)
self
.
tic
()
instance0
.
SoftwareInstance_tryToGarbageUnlinkedInstance
()
self
.
tic
()
# Will not be destroyed by this script
self
.
assertEqual
(
instance0
.
getSlapState
(),
'start_requested'
)
def
test_SoftwareInstance_tryToGarbageUnlinkedInstance_will_unlink_children
(
self
):
instance
=
self
.
createInstance
()
partition
=
self
.
createComputePartition
()
instance
.
edit
(
aggregate_value
=
partition
)
self
.
tic
()
instance0
=
self
.
doRequestInstance
(
instance
,
'instance0'
)
instance_instance0
=
self
.
doRequestInstance
(
instance0
,
'Subinstance0'
)
self
.
assertEqual
(
instance_instance0
.
getSuccessorRelatedTitle
(),
'instance0'
)
instance
.
edit
(
successor_list
=
[])
self
.
tic
()
self
.
assertEqual
(
instance0
.
getSuccessorRelatedTitle
(),
None
)
instance0
.
SoftwareInstance_tryToGarbageUnlinkedInstance
(
delay_time
=-
1
)
self
.
tic
()
self
.
assertEqual
(
instance0
.
getSlapState
(),
'destroy_requested'
)
self
.
assertEqual
(
instance_instance0
.
getSlapState
(),
'start_requested'
)
# Link of child removed
self
.
assertEqual
(
instance_instance0
.
getSuccessorRelatedTitle
(),
None
)
def
test_SoftwareInstance_tryToGarbageUnlinkedInstance_will_delay
(
self
):
instance
=
self
.
createInstance
()
partition
=
self
.
createComputePartition
()
instance
.
edit
(
aggregate_value
=
partition
)
self
.
tic
()
instance0
=
self
.
doRequestInstance
(
instance
,
'instance0'
)
instance_instance0
=
self
.
doRequestInstance
(
instance0
,
'Subinstance0'
)
self
.
assertEqual
(
instance_instance0
.
getSuccessorRelatedTitle
(),
'instance0'
)
instance
.
edit
(
successor_list
=
[])
self
.
tic
()
self
.
assertEqual
(
instance0
.
getSuccessorRelatedTitle
(),
None
)
instance0
.
SoftwareInstance_tryToGarbageUnlinkedInstance
()
self
.
tic
()
self
.
assertEqual
(
instance0
.
getSlapState
(),
'start_requested'
)
self
.
assertEqual
(
instance_instance0
.
getSlapState
(),
'start_requested'
)
# delay a bit
time
.
sleep
(
2
)
# run with delay of 3 seconds
instance0
.
SoftwareInstance_tryToGarbageUnlinkedInstance
(
delay_time
=
3
/
60.0
)
self
.
tic
()
self
.
assertEqual
(
instance0
.
getSlapState
(),
'destroy_requested'
)
self
.
assertEqual
(
instance_instance0
.
getSlapState
(),
'start_requested'
)
# Link of child removed
self
.
assertEqual
(
instance_instance0
.
getSuccessorRelatedTitle
(),
None
)
def
test_SoftwareInstance_tryToGarbageUnlinkedInstance_unlinked_root
(
self
):
instance
=
self
.
createInstance
()
partition
=
self
.
createComputePartition
()
instance
.
edit
(
aggregate_value
=
partition
)
self
.
tic
()
self
.
assertEqual
(
self
.
instance_tree
.
getTitle
(),
instance
.
getTitle
())
# Remove successor link
self
.
instance_tree
.
edit
(
successor_list
=
[])
self
.
tic
()
self
.
assertEqual
(
instance
.
getSuccessorRelatedTitle
(),
None
)
# will not destroy
self
.
assertRaises
(
ValueError
,
instance
.
SoftwareInstance_tryToGarbageUnlinkedInstance
,
delay_time
=-
10
)
self
.
tic
()
self
.
assertEqual
(
instance
.
getSlapState
(),
'start_requested'
)
def
test_SoftwareInstance_tryToGarbageUnlinkedInstance_not_unlinked
(
self
):
instance
=
self
.
createInstance
()
partition
=
self
.
createComputePartition
()
instance
.
edit
(
aggregate_value
=
partition
)
self
.
tic
()
instance0
=
self
.
doRequestInstance
(
instance
,
'instance0'
)
instance_instance0
=
self
.
doRequestInstance
(
instance0
,
'Subinstance0'
)
self
.
assertEqual
(
instance_instance0
.
getSuccessorRelatedTitle
(),
'instance0'
)
self
.
assertEqual
(
instance_instance0
.
getSlapState
(),
'start_requested'
)
# Try to remove without delete successor link
instance_instance0
.
SoftwareInstance_tryToGarbageUnlinkedInstance
(
delay_time
=-
1
)
self
.
tic
()
self
.
assertEqual
(
instance_instance0
.
getSlapState
(),
'start_requested'
)
def
test_alarm_search_inlinked_instance
(
self
):
instance
=
self
.
createInstance
()
partition
=
self
.
createComputePartition
()
instance
.
edit
(
aggregate_value
=
partition
)
self
.
tic
()
instance0
=
self
.
doRequestInstance
(
instance
,
'instance0'
)
self
.
assertEqual
(
instance
.
getSuccessorReference
(),
instance0
.
getReference
())
self
.
_test_alarm_not_visited
(
self
.
portal
.
portal_alarms
.
slapos_garbage_collect_destroy_unlinked_instance
,
instance0
,
'SoftwareInstance_tryToGarbageUnlinkedInstance'
)
# Remove successor link
instance
.
edit
(
successor_list
=
[])
self
.
_test_alarm
(
self
.
portal
.
portal_alarms
.
slapos_garbage_collect_destroy_unlinked_instance
,
instance0
,
'SoftwareInstance_tryToGarbageUnlinkedInstance'
)
def
test_alarm_search_inlinked_instance_slave
(
self
):
instance
=
self
.
createInstance
()
partition
=
self
.
createComputePartition
()
instance
.
edit
(
aggregate_value
=
partition
)
self
.
tic
()
slave_instance0
=
self
.
doRequestInstance
(
instance
,
'slaveInstance0'
,
True
)
self
.
assertEqual
(
instance
.
getSuccessorTitle
(),
'slaveInstance0'
)
self
.
_test_alarm_not_visited
(
self
.
portal
.
portal_alarms
.
slapos_garbage_collect_destroy_unlinked_instance
,
slave_instance0
,
'SoftwareInstance_tryToGarbageUnlinkedInstance'
)
instance
.
edit
(
successor_list
=
[])
self
.
_test_alarm
(
self
.
portal
.
portal_alarms
.
slapos_garbage_collect_destroy_unlinked_instance
,
slave_instance0
,
'SoftwareInstance_tryToGarbageUnlinkedInstance'
)
class
TestSlapOSInvalidateDestroyedInstance
(
SlapOSTestCaseMixin
):
def
createSoftwareInstance
(
self
):
...
...
master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudInstanceSlapInterfaceWorkflow.py
View file @
20a0f457
...
...
@@ -19,6 +19,8 @@
#
##############################################################################
from
erp5.component.test.SlapOSTestCaseMixin
import
SlapOSTestCaseMixin
from
erp5.component.document.SoftwareInstance
import
SoftwareInstance
,
\
DisconnectedSoftwareTree
,
CyclicSoftwareTree
import
transaction
from
time
import
sleep
from
zExceptions
import
Unauthorized
...
...
@@ -408,6 +410,127 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(SlapOSTestCaseMixin):
self
.
assertSameSet
(
B_instance
.
getSuccessorList
(),
[
C_instance
.
getRelativeUrl
()])
def
test_request_tree_disconnected
(
self
):
"""Checks tree change forced by request
For a tree like:
A
|
A
|
\
B C
Them force C to be disconnected:
A
|
A
|
B C
When A requests C the request should fail.
"""
request_kw
=
self
.
request_kw
.
copy
()
request_kw
[
'software_title'
]
=
self
.
generateNewSoftwareTitle
()
self
.
software_instance
.
requestInstance
(
**
request_kw
)
B_instance
=
self
.
software_instance
.
REQUEST
.
get
(
'request_instance'
)
request_kw
[
'software_title'
]
=
self
.
generateNewSoftwareTitle
()
self
.
software_instance
.
requestInstance
(
**
request_kw
)
C_instance
=
self
.
software_instance
.
REQUEST
.
get
(
'request_instance'
)
self
.
assertSameSet
(
self
.
software_instance
.
getSuccessorList
(),
[
B_instance
.
getRelativeUrl
(),
C_instance
.
getRelativeUrl
()])
self
.
tic
()
# in order to recalculate tree
self
.
software_instance
.
setSuccessorList
([
B_instance
.
getRelativeUrl
()])
self
.
tic
()
# in order to recalculate tree
self
.
assertRaises
(
DisconnectedSoftwareTree
,
self
.
software_instance
.
requestInstance
,
**
request_kw
)
# Just re-set sucessor fixes the problem
self
.
software_instance
.
setSuccessorList
([
B_instance
.
getRelativeUrl
(),
C_instance
.
getRelativeUrl
()])
self
.
tic
()
# in order to recalculate tree
self
.
software_instance
.
requestInstance
(
**
request_kw
)
C1_instance
=
self
.
software_instance
.
REQUEST
.
get
(
'request_instance'
)
self
.
assertEqual
(
C_instance
.
getRelativeUrl
(),
C1_instance
.
getRelativeUrl
())
def
test_request_check_cycle
(
self
):
"""Checks tree change forced by request
For a tree like:
A
|
A
|
B
|
C
|
D
Them force D to request A to be cycled (dupplicated successor related):
A
|
A
|
\
B D
|/
C
In normal conditions there is no raise because either DisconnectedSoftwareTree is raised before,
so we hot patch the checkConnected to ensure we get the proper raise
"""
request_kw
=
self
.
request_kw
.
copy
()
request_kw
[
'software_title'
]
=
self
.
generateNewSoftwareTitle
()
self
.
software_instance
.
requestInstance
(
**
request_kw
)
B_instance
=
self
.
software_instance
.
REQUEST
.
get
(
'request_instance'
)
request_kw
[
'software_title'
]
=
self
.
generateNewSoftwareTitle
()
B_instance
.
requestInstance
(
**
request_kw
)
C_instance
=
self
.
software_instance
.
REQUEST
.
get
(
'request_instance'
)
request_kw
[
'software_title'
]
=
self
.
generateNewSoftwareTitle
()
C_instance
.
requestInstance
(
**
request_kw
)
D_instance
=
self
.
software_instance
.
REQUEST
.
get
(
'request_instance'
)
self
.
assertSameSet
(
self
.
software_instance
.
getSuccessorList
(),
[
B_instance
.
getRelativeUrl
()])
self
.
assertSameSet
(
B_instance
.
getSuccessorList
(),
[
C_instance
.
getRelativeUrl
()])
self
.
assertSameSet
(
C_instance
.
getSuccessorList
(),
[
D_instance
.
getRelativeUrl
()])
self
.
tic
()
# in order to recalculate tree
def
checkConnected
(
self
,
graph
,
root
):
"Patch and return skip"
return
checkConnected_original
=
SoftwareInstance
.
checkConnected
try
:
SoftwareInstance
.
checkConnected
=
checkConnected
request_kw
[
'software_title'
]
=
B_instance
.
getTitle
()
self
.
assertRaises
(
CyclicSoftwareTree
,
D_instance
.
requestInstance
,
**
request_kw
)
finally
:
SoftwareInstance
.
checkConnected
=
checkConnected_original
def
test_request_tree_change_not_indexed
(
self
):
"""Checks tree change forced by request
...
...
master/bt5/slapos_cloud/bt/template_path_list
View file @
20a0f457
...
...
@@ -12,7 +12,6 @@ portal_alarms/slapos_allocate_instance
portal_alarms/slapos_assert_instance_tree_successor
portal_alarms/slapos_cloud_invalidate_destroyed_instance
portal_alarms/slapos_free_compute_partition
portal_alarms/slapos_garbage_collect_destroy_unlinked_instance
portal_alarms/slapos_garbage_collect_destroyed_root_tree
portal_alarms/slapos_garbage_collect_non_allocated_root_tree
portal_alarms/slapos_stop_collect_instance
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment