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
Léo-Paul Géneau
slapos.core
Commits
d63edd45
Commit
d63edd45
authored
Aug 09, 2022
by
Cédric Le Ninivin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
slapos: slapgrid tests work with slaptool for backward compatibility
parent
90a7f4a7
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
4314 additions
and
232 deletions
+4314
-232
slapos/grid/slapgrid.py
slapos/grid/slapgrid.py
+30
-28
slapos/tests/test_slapgrid.py
slapos/tests/test_slapgrid.py
+2
-204
slapos/tests/test_slapgrid_slaptool.py
slapos/tests/test_slapgrid_slaptool.py
+4282
-0
No files found.
slapos/grid/slapgrid.py
View file @
d63edd45
...
...
@@ -561,39 +561,41 @@ stderr_logfile_backups=1
launchSupervisord
(
instance_root
=
self
.
instance_root
,
logger
=
self
.
logger
)
def
getComputerPartitionList
(
self
):
if
self
.
computer_partition_list
is
None
:
if
not
self
.
api_backward_compatibility
:
if
not
self
.
api_backward_compatibility
:
if
self
.
computer_partition_list
is
None
:
self
.
computer_partition_list
=
self
.
slap
.
jio_api_connector
.
allDocs
({
"portal_type"
:
"Software Instance"
,
"compute_node_id"
:
self
.
computer_id
,
}).
get
(
"result_list"
,
[])
else
:
else
:
try
:
slap_partition_list
=
self
.
computer
.
getComputerPartitionList
()
except
socket
.
error
as
exc
:
self
.
logger
.
fatal
(
exc
)
raise
self
.
computer_partition_list
=
[]
for
partition
in
slap_partition_list
:
try
:
slap_partition_list
=
self
.
computer
.
getComputerPartitionList
()
except
socket
.
error
as
exc
:
self
.
logger
.
fatal
(
exc
)
raise
self
.
computer_partition_list
=
[]
for
partition
in
slap_partition_list
:
try
:
software_release_uri
=
partition
.
getSoftwareRelease
().
getURI
()
except
(
NotFoundError
,
TypeError
,
NameError
):
software_release_uri
=
None
self
.
computer_partition_list
.
append
({
"reference"
:
partition
.
_instance_guid
,
"portal_type"
:
"Software Instance"
,
"compute_partition_id"
:
partition
.
getId
(),
"state"
:
partition
.
getState
(),
"software_type"
:
partition
.
getInstanceParameterDict
().
get
(
'slap_software_type'
,
None
),
"parameters"
:
partition
.
getInstanceParameterDict
(),
"instance_processing_timestamp"
:
partition
.
getInstanceParameterDict
().
get
(
"timestamp"
),
"slap_partition"
:
partition
,
"access_status_message"
:
partition
.
getAccessStatus
(),
"software_release_uri"
:
software_release_uri
,
"sla_parameters"
:
getattr
(
partition
,
'_filter_dict'
,
{}),
})
software_release_uri
=
partition
.
getSoftwareRelease
().
getURI
()
except
(
NotFoundError
,
TypeError
,
NameError
):
software_release_uri
=
None
parameter_dict
=
partition
.
getInstanceParameterDict
()
self
.
computer_partition_list
.
append
({
"reference"
:
partition
.
_instance_guid
,
"portal_type"
:
"Software Instance"
,
"compute_partition_id"
:
partition
.
getId
(),
"state"
:
partition
.
getState
(),
"software_type"
:
parameter_dict
.
get
(
'slap_software_type'
,
None
),
"parameters"
:
parameter_dict
,
"processing_timestamp"
:
parameter_dict
.
get
(
"timestamp"
),
"slap_partition"
:
partition
,
"ip_list"
:
parameter_dict
[
"ip_list"
],
"full_ip_list"
:
parameter_dict
.
get
(
"full_ip_list"
,
[]),
"access_status_message"
:
partition
.
getAccessStatus
(),
"software_release_uri"
:
software_release_uri
,
"sla_parameters"
:
getattr
(
partition
,
'_filter_dict'
,
{}),
})
return
self
.
computer_partition_list
def
sendPartitionError
(
self
,
partition
,
error_message
,
logger
=
None
):
...
...
slapos/tests/test_slapgrid.py
View file @
d63edd45
...
...
@@ -381,30 +381,6 @@ class MasterMixin(BasicMixin):
self
.
_unmock_sleep
()
BasicMixin
.
tearDown
(
self
)
class
SlapToolMasterMixin
(
MasterMixin
):
def
setSlapgrid
(
self
,
develop
=
False
,
force_stop
=
False
):
if
getattr
(
self
,
'master_url'
,
None
)
is
None
:
self
.
master_url
=
'http://127.0.0.1:80/'
self
.
computer_id
=
'computer'
self
.
supervisord_socket
=
os
.
path
.
join
(
self
.
_tempdir
,
'sv.sock'
)
self
.
supervisord_configuration_path
=
os
.
path
.
join
(
self
.
_tempdir
,
'supervisord'
)
self
.
usage_report_periodicity
=
1
self
.
buildout
=
None
self
.
grid
=
slapgrid
.
Slapgrid
(
self
.
software_root
,
self
.
instance_root
,
self
.
master_url
,
self
.
computer_id
,
self
.
buildout
,
develop
=
develop
,
logger
=
logging
.
getLogger
(),
shared_part_list
=
self
.
shared_parts_root
,
force_stop
=
force_stop
,
)
self
.
grid
.
_manager_list
=
self
.
manager_list
self
.
use_jio_api
=
False
# monkey patch buildout bootstrap
class
ComputerForTest
(
object
):
"""
Class to set up environment for tests setting instance, software
...
...
@@ -603,77 +579,15 @@ class ComputerForTest(object):
"message"
:
"No document found with parameters: %s"
%
reference
,
"name"
:
"NotFound"
,
})
raise
ValueError
(
"Unexcepted call to API. URL:%s Content:%s"
%
(
url
.
path
,
req
.
body
))
if
(
url
.
path
==
'/getFullComputerInformation'
and
'computer_id'
in
qs
):
slap_computer
=
self
.
getComputer
(
qs
[
'computer_id'
][
0
])
return
{
'status_code'
:
200
,
'content'
:
dumps
(
slap_computer
)
}
elif
url
.
path
==
'/getHostingSubscriptionIpList'
:
ip_address_list
=
self
.
ip_address_list
return
{
'status_code'
:
200
,
'content'
:
dumps
(
ip_address_list
)
}
elif
url
.
path
==
'/getComputerPartitionCertificate'
:
return
{
'status_code'
:
200
,
'content'
:
dumps
({
'certificate'
:
'SLAPOS_cert'
,
'key'
:
'SLAPOS_key'
})
}
if
req
.
method
==
'POST'
and
'computer_partition_id'
in
qs
:
instance
=
self
.
instance_list
[
int
(
qs
[
'computer_partition_id'
][
0
])]
instance
.
sequence
.
append
(
url
.
path
)
instance
.
header_list
.
append
(
req
.
headers
)
if
url
.
path
==
'/startedComputerPartition'
:
instance
.
state
=
'started'
return
{
'status_code'
:
200
}
if
url
.
path
==
'/stoppedComputerPartition'
:
instance
.
state
=
'stopped'
return
{
'status_code'
:
200
}
if
url
.
path
==
'/destroyedComputerPartition'
:
instance
.
state
=
'destroyed'
return
{
'status_code'
:
200
}
if
url
.
path
==
'/softwareInstanceBang'
:
return
{
'status_code'
:
200
}
if
url
.
path
==
"/updateComputerPartitionRelatedInstanceList"
:
return
{
'status_code'
:
200
}
if
url
.
path
==
'/softwareInstanceError'
:
instance
.
error_log
=
'
\
n
'
.
join
(
[
line
for
line
in
qs
[
'error_log'
][
0
].
splitlines
()
if
'dropPrivileges'
not
in
line
]
)
instance
.
error
=
True
return
{
'status_code'
:
200
}
raise
ValueError
(
"Unexcepted call to API. URL:%s Content:%s"
%
(
url
.
path
,
req
.
body
))
elif
req
.
method
==
'POST'
and
'url'
in
qs
:
# XXX hardcoded to first software release!
software
=
self
.
software_list
[
0
]
software
.
sequence
.
append
(
url
.
path
)
if
url
.
path
==
'/availableSoftwareRelease'
:
return
{
'status_code'
:
200
}
if
url
.
path
==
'/buildingSoftwareRelease'
:
return
{
'status_code'
:
200
}
if
url
.
path
==
'/destroyedSoftwareRelease'
:
return
{
'status_code'
:
200
}
if
url
.
path
==
'/softwareReleaseError'
:
software
.
error_log
=
'
\
n
'
.
join
(
[
line
for
line
in
qs
[
'error_log'
][
0
].
splitlines
()
if
'dropPrivileges'
not
in
line
]
)
software
.
error
=
True
return
{
'status_code'
:
200
}
else
:
return
{
'status_code'
:
500
}
def
getTestSoftwareClass
(
self
):
return
SoftwareForTest
...
...
@@ -2240,76 +2154,6 @@ class TestSlapgridUsageReport(MasterMixin, unittest.TestCase):
six
.
assertCountEqual
(
self
,
os
.
listdir
(
self
.
software_root
),
[
instance
.
software
.
software_hash
])
self
.
assertEqual
(
computer
.
sequence
,
[
'/api/allDocs/'
])
class
TestSlapgridSoftwareReleaseSlapTool
(
SlapToolMasterMixin
,
unittest
.
TestCase
):
fake_waiting_time
=
0.05
def
test_one_software_buildout_fail_is_correctly_logged
(
self
):
"""
1. We set up a software using a corrupted buildout
2. It will fail, make sure that whole log is sent to master
"""
computer
=
self
.
getTestComputerClass
()(
self
.
software_root
,
self
.
instance_root
,
1
,
1
)
with
httmock
.
HTTMock
(
computer
.
request_handler
):
software
=
computer
.
software_list
[
0
]
line1
=
"Nerdy kitten: Can I haz a process crash?"
line2
=
"Cedric: Sure, here it is."
software
.
setBuildout
(
"""#!/bin/sh
echo %s; echo %s; exit 42"""
%
(
line1
,
line2
))
self
.
launchSlapgridSoftware
()
self
.
assertEqual
(
software
.
sequence
,
[
'/buildingSoftwareRelease'
,
'/softwareReleaseError'
])
# We don't care of actual formatting, we just want to have full log
self
.
assertIn
(
line1
,
software
.
error_log
)
self
.
assertIn
(
line2
,
software
.
error_log
)
self
.
assertIn
(
'Failed to run buildout'
,
software
.
error_log
)
def
test_software_install_generate_buildout_cfg_with_shared_part_list
(
self
):
computer
=
self
.
getTestComputerClass
()(
self
.
software_root
,
self
.
instance_root
,
1
,
1
)
with
httmock
.
HTTMock
(
computer
.
request_handler
):
software
=
computer
.
software_list
[
0
]
# examine the genrated buildout
software
.
setBuildout
(
"""#!/bin/sh
cat buildout.cfg; exit 1"""
)
self
.
launchSlapgridSoftware
()
self
.
assertIn
(
'shared-part-list = %s'
%
self
.
shared_parts_root
,
software
.
error_log
)
def
test_remove_software
(
self
):
computer
=
self
.
getTestComputerClass
()(
self
.
software_root
,
self
.
instance_root
,
1
,
1
)
with
httmock
.
HTTMock
(
computer
.
request_handler
):
software
=
computer
.
software_list
[
0
]
software
.
setBuildout
(
"""#!/bin/sh
mkdir directory
touch directory/file
"""
)
self
.
launchSlapgridSoftware
()
self
.
assertIn
(
'directory'
,
os
.
listdir
(
os
.
path
.
join
(
self
.
software_root
,
software
.
software_hash
)))
software
.
requested_state
=
'destroyed'
self
.
launchSlapgridSoftware
()
self
.
assertEqual
(
os
.
listdir
(
self
.
software_root
),
[])
def
test_remove_software_chmod
(
self
):
# This software is "hard" to remove, as permissions have been changed
computer
=
self
.
getTestComputerClass
()(
self
.
software_root
,
self
.
instance_root
,
1
,
1
)
with
httmock
.
HTTMock
(
computer
.
request_handler
):
software
=
computer
.
software_list
[
0
]
software
.
setBuildout
(
"""#!/bin/sh
mkdir directory
touch directory/file
chmod a-rxw directory/file
chmod a-rxw directory
"""
)
self
.
launchSlapgridSoftware
()
self
.
assertIn
(
'directory'
,
os
.
listdir
(
os
.
path
.
join
(
self
.
software_root
,
software
.
software_hash
)))
software
.
requested_state
=
'destroyed'
self
.
launchSlapgridSoftware
()
self
.
assertEqual
(
os
.
listdir
(
self
.
software_root
),
[])
class
TestSlapgridSoftwareRelease
(
MasterMixin
,
unittest
.
TestCase
):
fake_waiting_time
=
0.05
...
...
@@ -3383,52 +3227,6 @@ exit 1 # do not proceed trying to use this software
self.assertNotIn("
file
descriptors
:
leaked
", software.error_log)
self.assertIn("
file
descriptors
:
ok
", software.error_log)
class TestSlapgridNoFDLeakSlapTool(SlapToolMasterMixin, unittest.TestCase):
def test_no_fd_leak(self):
filev = []
try:
# open some file descriptors
for i in range(4):
f = open(os.devnull)
filev.append(f)
self.assertGreater(f.fileno(), 2)
# 'node software' with check that buildout does not see opened files
self._test_no_fd_leak()
finally:
for f in filev:
f.close()
def _test_no_fd_leak(self):
computer = ComputerForTest(self.software_root, self.instance_root, 1, 1)
with httmock.HTTMock(computer.request_handler):
software = computer.software_list[0]
software.setBuildout("""#!/bin/bash
fdleak() {
echo "
file
descriptors
:
leaked
:
" "
$
@
"
exit 1
}
# https://unix.stackexchange.com/a/206848
: >&3 && fdleak 3
: >&4 && fdleak 4
: >&5 && fdleak 5
: >&6 && fdleak 6
echo "
file
descriptors
:
ok
"
exit 1 # do not proceed trying to use this software
""")
self.launchSlapgridSoftware()
self.assertEqual(software.sequence,
['/buildingSoftwareRelease', '/softwareReleaseError'])
self.assertNotIn("
file
descriptors
:
leaked
", software.error_log)
self.assertIn("
file
descriptors
:
ok
", software.error_log)
class TestSlapgridWithPortRedirection(MasterMixin, unittest.TestCase):
def setUp(self):
...
...
slapos/tests/test_slapgrid_slaptool.py
0 → 100644
View file @
d63edd45
This source diff could not be displayed because it is too large. You can
view the blob
instead.
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