Commit d63edd45 authored by Cédric Le Ninivin's avatar Cédric Le Ninivin

slapos: slapgrid tests work with slaptool for backward compatibility

parent 90a7f4a7
......@@ -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):
......
......@@ -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):
......
This source diff could not be displayed because it is too large. You can view the blob instead.
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