Commit 4337b2fa authored by Gabriel Monnerat's avatar Gabriel Monnerat

merge 'master' into slave_instance

parents dc812047 1eddcede
......@@ -74,7 +74,13 @@ graph = {}\n
# Get root software instance and create initial graph\n
predecessor_software_instance = software_instance\n
while (predecessor_software_instance is not None):\n
graph[predecessor_software_instance.getUid()] = predecessor_software_instance.getPredecessorUidList()\n
predecessor_software_instance_pred_uid_list = predecessor_software_instance.getPredecessorUidList()\n
graph[predecessor_software_instance.getUid()] = predecessor_software_instance_pred_uid_list\n
# as this walking is not fetching all instances fill predecessors into graph, in order to have\n
# "nearly" complete representation\n
for uid in predecessor_software_instance_pred_uid_list:\n
if uid not in graph:\n
graph[uid] = []\n
root_software_instance = predecessor_software_instance\n
predecessor_software_instance = predecessor_software_instance.getPredecessorRelatedValue(\n
portal_type="Software Instance")\n
......@@ -160,9 +166,9 @@ if not request_software_instance.getUid() in graph:\n
# update graph to reflect requested operation\n
graph[software_instance.getUid()] = software_instance.getPredecessorUidList() + [request_software_instance.getUid()]\n
\n
# check if all elements are still connected\n
software_instance.checkNotCyclic(graph)\n
# check if all elements are still connected and if there is no cycle\n
software_instance.checkConnected(graph, root_software_instance.getUid())\n
software_instance.checkNotCyclic(graph)\n
\n
software_instance.edit(\n
predecessor_list=predecessor_list,\n
......
......@@ -3149,6 +3149,9 @@ class TestVifibSlapWebService(testVifibMixin):
def stepCheckSoftwareInstanceAndRelatedComputerPartition(self,
sequence, **kw):
self.stepCheckSoftwareInstanceAndRelatedComputerPartitionNoPackingListCheck(sequence, **kw)
software_instance_uid = sequence['software_instance_uid']
software_instance = self.portal.portal_catalog.getResultValue(
uid=software_instance_uid)
self._checkSoftwareInstanceAndRelatedPartition(software_instance)
def stepCheckSoftwareInstanceAndRelatedComputerPartitionNoPackingListCheck(self,
......@@ -9220,7 +9223,6 @@ class TestVifibSlapWebService(testVifibMixin):
sequence, **kw):
software_instance = self.portal.portal_catalog.getResultValue(
uid = sequence['software_instance_uid'])
requested_reference = sequence['requested_reference']
from erp5.document.SoftwareInstance import DisconnectedSoftwareTree
self.assertRaises(DisconnectedSoftwareTree,
software_instance.requestSoftwareInstance,
......@@ -9370,7 +9372,6 @@ class TestVifibSlapWebService(testVifibMixin):
sequence, **kw):
software_instance = self.portal.portal_catalog.getResultValue(
uid = sequence['software_instance_uid'])
requested_reference = sequence['requested_reference']
from erp5.document.SoftwareInstance import CyclicSoftwareTree
self.assertRaises(CyclicSoftwareTree,
software_instance.requestSoftwareInstance,
......@@ -9520,7 +9521,6 @@ class TestVifibSlapWebService(testVifibMixin):
sequence, **kw):
software_instance = self.portal.portal_catalog.getResultValue(
uid = sequence['software_instance_uid'])
requested_reference = sequence['requested_reference']
self.assertRaises(ValueError,
software_instance.requestSoftwareInstance,
software_release=sequence['software_release_uri'],
......@@ -9764,7 +9764,7 @@ class TestVifibSlapWebService(testVifibMixin):
from erp5.document.SoftwareInstance import CyclicSoftwareTree
self.assertRaises(CyclicSoftwareTree, self.checkNotCyclic, graph)
def test_si_tree_simple_list_cyclic(self):
def test_si_tree_simple_list_cyclic_non_root(self):
"""Graph of cyclic list is cyclic
B->C->D->A-\
......@@ -9862,7 +9862,7 @@ class TestVifibSlapWebService(testVifibMixin):
def stepRequestCredentialFromWebSite(self, sequence, **kw):
sequence['web_user'] = '%s.%s' % (self.id(), random())
result = self.portal.ERP5Site_newCredentialRequest(\
self.portal.ERP5Site_newCredentialRequest(\
first_name='Homer',
last_name='Simpson',
reference=sequence['web_user'],
......
......@@ -35,6 +35,7 @@ if sys.version_info < (2, 6):
import socket
import subprocess
import traceback
import time
#from time import strftime
from SlapObject import Software, Partition, WrongPermissionError, \
......@@ -105,6 +106,9 @@ def parseArgumentTupleAndReturnSlapgridObject(*argument_tuple):
help="Enables console output and live output from subcommands.")
parser.add_argument("-v", "--verbose", action="store_true", default=False,
help="Be verbose.")
parser.add_argument("--promise-timeout",
type=int, default=3,
help="Promise timeout in seconds.")
parser.add_argument("configuration_file", nargs=1, type=argparse.FileType(),
help="SlapOS configuration file.")
......@@ -198,7 +202,8 @@ def parseArgumentTupleAndReturnSlapgridObject(*argument_tuple):
master_ca_file=master_ca_file,
certificate_repository_path=certificate_repository_path,
console=option_dict['console'],
buildout=option_dict.get('buildout')),
buildout=option_dict.get('buildout'),
promise_timeout=option_dict['promise_timeout']),
option_dict])
......@@ -267,7 +272,8 @@ class Slapgrid(object):
cert_file=None,
master_ca_file=None,
certificate_repository_path=None,
console=False):
console=False,
promise_timeout=3):
"""Makes easy initialisation of class parameters"""
# Parses arguments
self.software_root = os.path.abspath(software_root)
......@@ -294,6 +300,7 @@ class Slapgrid(object):
os.path.join(self.instance_etc_directory, 'supervisord.conf.d')
self.console = console
self.buildout = buildout
self.promise_timeout = promise_timeout
def checkEnvironmentAndCreateStructure(self):
"""Checks for software_root and instance_root existence, then creates
......@@ -452,6 +459,53 @@ class Slapgrid(object):
exception = traceback.format_exc()
logger.error(exception)
computer_partition.error(exception)
# Promises
instance_path = os.path.join(self.instance_root,
computer_partition.getId())
uid, gid = None, None
stat_info = os.stat(instance_path)
#stat sys call to get statistics informations
uid = stat_info.st_uid
gid = stat_info.st_gid
# Get the list of promises
promise_dir = os.path.join(instance_path, 'etc', 'promise')
if os.path.exists(promise_dir) and os.path.isdir(promise_dir):
cwd = instance_path
promises_list = os.listdir(promise_dir)
# Check whether every promise is kept
for promise in promises_list:
command = os.path.join(promise_dir, promise)
kw = dict()
if not self.console:
kw.update(stdout=subprocess.PIPE, stderr=subprocess.PIPE)
process_handler = SlapPopen(command,
preexec_fn=lambda: dropPrivileges(uid, gid),
cwd=cwd,
env=None, **kw)
time.sleep(self.promise_timeout)
promise = os.path.basename(command)
if process_handler.poll() is None:
process_handler.kill()
computer_partition.error("The promise %r timed out" % promise)
elif process_handler.poll() != 0:
stderr = process_handler.communicate()[1]
if stderr is None:
stderr = 'No error output from %r.' % promise
computer_partition.error(stderr)
logger.info("Finished computer partitions...")
return clean_run
......
......@@ -3,8 +3,6 @@
"""Mocked httplib
"""
from urlparse import urlparse
__all__ = []
def log(message):
......@@ -21,13 +19,13 @@ class HTTPConnection(object):
HTTPConnection._callback. This method received the instance, the path,
method and request body as parameter, and it has to return a tuple with
headers dictionary and body response string.
@param self object instance reference
@param URL the parsed URL
@param method the http method
@param body the request body
@param headers the request headers
@return tuple containing status integer, headers dictionary and body
response"""
return (0, {}, '', )
......@@ -83,7 +81,6 @@ class HTTPSConnection(HTTPConnection):
source_address=None):
super().__init__(self, host, port, strict, timeout,
source_address)
pass
class HTTPResponse(object):
......
......@@ -79,12 +79,51 @@ class MasterMixin(BasicMixin):
setattr(httplib, name, original_value)
del self.saved_httplib
def _mock_sleep(self):
self.fake_waiting_time = None
self.real_sleep = time.sleep
def mocked_sleep(secs):
if self.fake_waiting_time is not None:
secs = self.fake_waiting_time
self.real_sleep(secs)
time.sleep = mocked_sleep
def _unmock_sleep(self):
time.sleep = self.real_sleep
def _create_instance(self, name=0):
if not os.path.isdir(self.instance_root):
os.mkdir(self.instance_root)
partition_path = os.path.join(self.instance_root, str(name))
os.mkdir(partition_path, 0750)
return partition_path
def _bootstrap(self):
os.mkdir(self.software_root)
software_hash = slapos.grid.utils.getSoftwareUrlHash('http://sr/')
srdir = os.path.join(self.software_root, software_hash)
os.mkdir(srdir)
open(os.path.join(srdir, 'template.cfg'), 'w').write(
"""[buildout]""")
srbindir = os.path.join(srdir, 'bin')
os.mkdir(srbindir)
open(os.path.join(srbindir, 'buildout'), 'w').write("""#!/bin/sh
touch worked""")
os.chmod(os.path.join(srbindir, 'buildout'), 0755)
return software_hash
def setUp(self):
self._patchHttplib()
self._mock_sleep()
BasicMixin.setUp(self)
def tearDown(self):
self._unpatchHttplib()
self._unmock_sleep()
BasicMixin.tearDown(self)
class TestSlapgridCPWithMaster(MasterMixin, unittest.TestCase):
......@@ -113,9 +152,9 @@ class TestSlapgridCPWithMaster(MasterMixin, unittest.TestCase):
def test_one_partition(self):
def server_response(self, path, method, body, header):
parsed_url = urlparse.urlparse('/' + path)
parsed_url = urlparse.urlparse(path.lstrip('/'))
parsed_qs = urlparse.parse_qs(parsed_url.query)
if parsed_url.path == '/getComputerInformation' and \
if parsed_url.path == 'getComputerInformation' and \
'computer_id' in parsed_qs:
slap_computer = slapos.slap.Computer(parsed_qs['computer_id'])
slap_computer._software_release_list = []
......@@ -158,9 +197,9 @@ touch worked""")
def test_one_partition_started(self):
def server_response(self, path, method, body, header):
parsed_url = urlparse.urlparse('/' + path)
parsed_url = urlparse.urlparse(path.lstrip('/'))
parsed_qs = urlparse.parse_qs(parsed_url.query)
if parsed_url.path == '/getComputerInformation' and \
if parsed_url.path == 'getComputerInformation' and \
'computer_id' in parsed_qs:
slap_computer = slapos.slap.Computer(parsed_qs['computer_id'])
slap_computer._software_release_list = []
......@@ -215,9 +254,9 @@ chmod 755 etc/run/wrapper
def test_one_partition_started_stopped(self):
def server_response(self, path, method, body, header):
parsed_url = urlparse.urlparse('/' + path)
parsed_url = urlparse.urlparse(path.lstrip('/'))
parsed_qs = urlparse.parse_qs(parsed_url.query)
if parsed_url.path == '/getComputerInformation' and \
if parsed_url.path == 'getComputerInformation' and \
'computer_id' in parsed_qs:
slap_computer = slapos.slap.Computer(parsed_qs['computer_id'])
slap_computer._software_release_list = []
......@@ -282,9 +321,9 @@ chmod 755 etc/run/wrapper
[software_hash])
def server_response(self, path, method, body, header):
parsed_url = urlparse.urlparse('/' + path)
parsed_url = urlparse.urlparse(path.lstrip('/'))
parsed_qs = urlparse.parse_qs(parsed_url.query)
if parsed_url.path == '/getComputerInformation' and \
if parsed_url.path == 'getComputerInformation' and \
'computer_id' in parsed_qs:
slap_computer = slapos.slap.Computer(parsed_qs['computer_id'])
slap_computer._software_release_list = []
......@@ -318,9 +357,9 @@ chmod 755 etc/run/wrapper
def test_one_partition_stopped_started(self):
def server_response(self, path, method, body, header):
parsed_url = urlparse.urlparse('/' + path)
parsed_url = urlparse.urlparse(path.lstrip('/'))
parsed_qs = urlparse.parse_qs(parsed_url.query)
if parsed_url.path == '/getComputerInformation' and \
if parsed_url.path == 'getComputerInformation' and \
'computer_id' in parsed_qs:
slap_computer = slapos.slap.Computer(parsed_qs['computer_id'])
slap_computer._software_release_list = []
......@@ -366,9 +405,9 @@ chmod 755 etc/run/wrapper
[software_hash])
def server_response(self, path, method, body, header):
parsed_url = urlparse.urlparse('/' + path)
parsed_url = urlparse.urlparse(path.lstrip('/'))
parsed_qs = urlparse.parse_qs(parsed_url.query)
if parsed_url.path == '/getComputerInformation' and \
if parsed_url.path == 'getComputerInformation' and \
'computer_id' in parsed_qs:
slap_computer = slapos.slap.Computer(parsed_qs['computer_id'])
slap_computer._software_release_list = []
......@@ -401,3 +440,411 @@ chmod 755 etc/run/wrapper
break
time.sleep(0.2)
self.assertTrue('Working' in open(wrapper_log, 'r').read())
class TestSlapgridCPWithMasterPromise(MasterMixin, unittest.TestCase):
def test_one_failing_promise(self):
def server_response(self_httplib, path, method, body, header):
parsed_url = urlparse.urlparse(path.lstrip('/'))
if method == 'GET':
parsed_qs = urlparse.parse_qs(parsed_url.query)
else:
parsed_qs = urlparse.parse_qs(body)
if parsed_url.path == 'getComputerInformation' and \
'computer_id' in parsed_qs:
slap_computer = slapos.slap.Computer(parsed_qs['computer_id'][0])
slap_computer._software_release_list = []
partition = slapos.slap.ComputerPartition(parsed_qs['computer_id'][0],
'0')
partition._need_modification = True
sr = slapos.slap.SoftwareRelease()
sr._software_release = 'http://sr/'
partition._software_release_document = sr
partition._requested_state = 'stopped'
slap_computer._computer_partition_list = [partition]
return (200, {}, xml_marshaller.xml_marshaller.dumps(slap_computer))
if parsed_url.path == 'softwareInstanceError' and \
method == 'POST' and 'computer_partition_id' in parsed_qs:
self.error = True
self.assertEqual(parsed_qs['computer_partition_id'][0], '0')
return (200, {}, '')
else:
return (404, {}, '')
httplib.HTTPConnection._callback = server_response
self.fake_waiting_time = 0.2
self.error = False
instance_path = self._create_instance('0')
software_hash = self._bootstrap()
promise_path = os.path.join(instance_path, 'etc', 'promise')
os.makedirs(promise_path)
fail = os.path.join(promise_path, 'fail')
worked_file = os.path.join(instance_path, 'fail_worked')
with open(fail, 'w') as f:
f.write("""#!/usr/bin/env sh
touch "%(worked_file)s"
exit 127""" % {'worked_file': worked_file})
os.chmod(fail, 0777)
self.assertTrue(self.grid.processComputerPartitionList())
self.assertTrue(os.path.isfile(worked_file))
self.assertTrue(self.error)
def test_one_succeeding_promise(self):
def server_response(self_httplib, path, method, body, header):
parsed_url = urlparse.urlparse(path.lstrip('/'))
if method == 'GET':
parsed_qs = urlparse.parse_qs(parsed_url.query)
else:
parsed_qs = urlparse.parse_qs(body)
if parsed_url.path == 'getComputerInformation' and \
'computer_id' in parsed_qs:
slap_computer = slapos.slap.Computer(parsed_qs['computer_id'][0])
slap_computer._software_release_list = []
partition = slapos.slap.ComputerPartition(parsed_qs['computer_id'][0],
'0')
partition._need_modification = True
sr = slapos.slap.SoftwareRelease()
sr._software_release = 'http://sr/'
partition._software_release_document = sr
partition._requested_state = 'stopped'
slap_computer._computer_partition_list = [partition]
return (200, {}, xml_marshaller.xml_marshaller.dumps(slap_computer))
if parsed_url.path == 'softwareInstanceError' and \
method == 'POST' and 'computer_partition_id' in parsed_qs:
self.error = True
raise AssertionError('ComputerPartition.error was raised')
return (200, {}, '')
else:
return (404, {}, '')
httplib.HTTPConnection._callback = server_response
self.fake_waiting_time = 0.2
self.error = False
instance_path = self._create_instance('0')
software_hash = self._bootstrap()
promise_path = os.path.join(instance_path, 'etc', 'promise')
os.makedirs(promise_path)
succeed = os.path.join(promise_path, 'succeed')
worked_file = os.path.join(instance_path, 'succeed_worked')
with open(succeed, 'w') as f:
f.write("""#!/usr/bin/env sh
touch "%(worked_file)s"
exit 0""" % {'worked_file': worked_file})
os.chmod(succeed, 0777)
self.assertTrue(self.grid.processComputerPartitionList())
self.assertTrue(os.path.isfile(worked_file))
self.assertFalse(self.error)
def test_stderr_has_been_sent(self):
def server_response(self_httplib, path, method, body, header):
parsed_url = urlparse.urlparse(path.lstrip('/'))
if method == 'GET':
parsed_qs = urlparse.parse_qs(parsed_url.query)
else:
parsed_qs = urlparse.parse_qs(body)
if parsed_url.path == 'getComputerInformation' and \
'computer_id' in parsed_qs:
slap_computer = slapos.slap.Computer(parsed_qs['computer_id'][0])
slap_computer._software_release_list = []
partition = slapos.slap.ComputerPartition(parsed_qs['computer_id'][0],
'0')
partition._need_modification = True
sr = slapos.slap.SoftwareRelease()
sr._software_release = 'http://sr/'
partition._software_release_document = sr
partition._requested_state = 'stopped'
slap_computer._computer_partition_list = [partition]
return (200, {}, xml_marshaller.xml_marshaller.dumps(slap_computer))
if parsed_url.path == 'softwareInstanceError' and \
method == 'POST' and 'computer_partition_id' in parsed_qs:
self.error = True
self.assertEqual(parsed_qs['computer_partition_id'][0], '0')
# XXX: Hardcoded dropPrivileges line ignore
self.error_log = '\n'.join([line for line in parsed_qs['error_log'][0].splitlines()
if 'dropPrivileges' not in line])
# end XXX
return (200, {}, '')
else:
return (404, {}, '')
httplib.HTTPConnection._callback = server_response
self.fake_waiting_time = 0.5
self.error = False
instance_path = self._create_instance('0')
software_hash = self._bootstrap()
promise_path = os.path.join(instance_path, 'etc', 'promise')
os.makedirs(promise_path)
succeed = os.path.join(promise_path, 'stderr_writer')
worked_file = os.path.join(instance_path, 'stderr_worked')
with open(succeed, 'w') as f:
f.write("""#!/usr/bin/env sh
touch "%(worked_file)s"
echo -n Error 1>&2
exit 127""" % {'worked_file': worked_file})
os.chmod(succeed, 0777)
self.assertTrue(self.grid.processComputerPartitionList())
self.assertTrue(os.path.isfile(worked_file))
self.assertEqual(self.error_log, 'Error')
self.assertTrue(self.error)
def test_timeout_works(self):
def server_response(self_httplib, path, method, body, header):
parsed_url = urlparse.urlparse(path.lstrip('/'))
if method == 'GET':
parsed_qs = urlparse.parse_qs(parsed_url.query)
else:
parsed_qs = urlparse.parse_qs(body)
if parsed_url.path == 'getComputerInformation' and \
'computer_id' in parsed_qs:
slap_computer = slapos.slap.Computer(parsed_qs['computer_id'][0])
slap_computer._software_release_list = []
partition = slapos.slap.ComputerPartition(parsed_qs['computer_id'][0],
'0')
partition._need_modification = True
sr = slapos.slap.SoftwareRelease()
sr._software_release = 'http://sr/'
partition._software_release_document = sr
partition._requested_state = 'stopped'
slap_computer._computer_partition_list = [partition]
return (200, {}, xml_marshaller.xml_marshaller.dumps(slap_computer))
if parsed_url.path == 'softwareInstanceError' and \
method == 'POST' and 'computer_partition_id' in parsed_qs:
self.error = True
self.assertEqual(parsed_qs['computer_partition_id'][0], '0')
# XXX: Hardcoded dropPrivileges line ignore
error_log = '\n'.join([line for line in parsed_qs['error_log'][0].splitlines()
if 'dropPrivileges' not in line])
# end XXX
self.assertEqual(error_log, 'The promise %r timed out' % 'timed_out_promise')
return (200, {}, '')
else:
return (404, {}, '')
httplib.HTTPConnection._callback = server_response
self.fake_waiting_time = 0.2
self.error = False
instance_path = self._create_instance('0')
software_hash = self._bootstrap()
promise_path = os.path.join(instance_path, 'etc', 'promise')
os.makedirs(promise_path)
succeed = os.path.join(promise_path, 'timed_out_promise')
worked_file = os.path.join(instance_path, 'timed_out_worked')
with open(succeed, 'w') as f:
f.write("""#!/usr/bin/env sh
touch "%(worked_file)s"
sleep 5
exit 0""" % {'worked_file': worked_file})
os.chmod(succeed, 0777)
self.assertTrue(self.grid.processComputerPartitionList())
self.assertTrue(os.path.isfile(worked_file))
self.assertTrue(self.error)
def test_two_succeeding_promises(self):
def server_response(self_httplib, path, method, body, header):
parsed_url = urlparse.urlparse(path.lstrip('/'))
if method == 'GET':
parsed_qs = urlparse.parse_qs(parsed_url.query)
else:
parsed_qs = urlparse.parse_qs(body)
if parsed_url.path == 'getComputerInformation' and \
'computer_id' in parsed_qs:
slap_computer = slapos.slap.Computer(parsed_qs['computer_id'][0])
slap_computer._software_release_list = []
partition = slapos.slap.ComputerPartition(parsed_qs['computer_id'][0],
'0')
partition._need_modification = True
sr = slapos.slap.SoftwareRelease()
sr._software_release = 'http://sr/'
partition._software_release_document = sr
partition._requested_state = 'stopped'
slap_computer._computer_partition_list = [partition]
return (200, {}, xml_marshaller.xml_marshaller.dumps(slap_computer))
if parsed_url.path == 'softwareInstanceError' and \
method == 'POST' and 'computer_partition_id' in parsed_qs:
self.error = True
raise AssertionError('ComputerPartition.error was raised')
return (200, {}, '')
else:
return (404, {}, '')
httplib.HTTPConnection._callback = server_response
self.fake_waiting_time = 0.2
self.error = False
instance_path = self._create_instance('0')
software_hash = self._bootstrap()
promise_path = os.path.join(instance_path, 'etc', 'promise')
os.makedirs(promise_path)
succeed = os.path.join(promise_path, 'succeed')
worked_file = os.path.join(instance_path, 'succeed_worked')
with open(succeed, 'w') as f:
f.write("""#!/usr/bin/env sh
touch "%(worked_file)s"
exit 0""" % {'worked_file': worked_file})
os.chmod(succeed, 0777)
succeed_2 = os.path.join(promise_path, 'succeed_2')
worked_file_2 = os.path.join(instance_path, 'succeed_2_worked')
with open(succeed_2, 'w') as f:
f.write("""#!/usr/bin/env sh
touch "%(worked_file)s"
exit 0""" % {'worked_file': worked_file_2})
os.chmod(succeed_2, 0777)
self.assertTrue(self.grid.processComputerPartitionList())
self.assertTrue(os.path.isfile(worked_file))
self.assertTrue(os.path.isfile(worked_file_2))
self.assertFalse(self.error)
def test_one_succeeding_one_failing_promises(self):
def server_response(self_httplib, path, method, body, header):
parsed_url = urlparse.urlparse(path.lstrip('/'))
if method == 'GET':
parsed_qs = urlparse.parse_qs(parsed_url.query)
else:
parsed_qs = urlparse.parse_qs(body)
if parsed_url.path == 'getComputerInformation' and \
'computer_id' in parsed_qs:
slap_computer = slapos.slap.Computer(parsed_qs['computer_id'][0])
slap_computer._software_release_list = []
partition = slapos.slap.ComputerPartition(parsed_qs['computer_id'][0],
'0')
partition._need_modification = True
sr = slapos.slap.SoftwareRelease()
sr._software_release = 'http://sr/'
partition._software_release_document = sr
partition._requested_state = 'stopped'
slap_computer._computer_partition_list = [partition]
return (200, {}, xml_marshaller.xml_marshaller.dumps(slap_computer))
if parsed_url.path == 'softwareInstanceError' and \
method == 'POST' and 'computer_partition_id' in parsed_qs:
self.error += 1
self.assertEqual(parsed_qs['computer_partition_id'][0], '0')
return (200, {}, '')
else:
return (404, {}, '')
httplib.HTTPConnection._callback = server_response
self.fake_waiting_time = 0.2
self.error = 0
instance_path = self._create_instance('0')
software_hash = self._bootstrap()
promise_path = os.path.join(instance_path, 'etc', 'promise')
os.makedirs(promise_path)
promises_files = []
for i in range(2):
promise = os.path.join(promise_path, 'promise_%d')
promises_files.append(promise)
worked_file = os.path.join(instance_path, 'promise_worked_%d')
lockfile = os.path.join(instance_path, 'lock')
with open(promise, 'w') as f:
f.write("""#!/usr/bin/env sh
touch "%(worked_file)s"
[[ ! -f "%(lockfile)s" ]] || { touch "%(lockfile)s" ; exit 127 }
exit 0""" % {'worked_file': worked_file, 'lockfile': lockfile})
os.chmod(promise, 0777)
self.assertTrue(self.grid.processComputerPartitionList())
for file_ in promises_files:
self.assertTrue(os.path.isfile(file_))
self.assertEquals(self.error, 1)
def test_one_succeeding_one_timing_out_promises(self):
def server_response(self_httplib, path, method, body, header):
parsed_url = urlparse.urlparse(path.lstrip('/'))
if method == 'GET':
parsed_qs = urlparse.parse_qs(parsed_url.query)
else:
parsed_qs = urlparse.parse_qs(body)
if parsed_url.path == 'getComputerInformation' and \
'computer_id' in parsed_qs:
slap_computer = slapos.slap.Computer(parsed_qs['computer_id'][0])
slap_computer._software_release_list = []
partition = slapos.slap.ComputerPartition(parsed_qs['computer_id'][0],
'0')
partition._need_modification = True
sr = slapos.slap.SoftwareRelease()
sr._software_release = 'http://sr/'
partition._software_release_document = sr
partition._requested_state = 'stopped'
slap_computer._computer_partition_list = [partition]
return (200, {}, xml_marshaller.xml_marshaller.dumps(slap_computer))
if parsed_url.path == 'softwareInstanceError' and \
method == 'POST' and 'computer_partition_id' in parsed_qs:
self.error += 1
self.assertEqual(parsed_qs['computer_partition_id'][0], '0')
return (200, {}, '')
else:
return (404, {}, '')
httplib.HTTPConnection._callback = server_response
self.fake_waiting_time = 0.2
self.error = 0
instance_path = self._create_instance('0')
software_hash = self._bootstrap()
promise_path = os.path.join(instance_path, 'etc', 'promise')
os.makedirs(promise_path)
promises_files = []
for i in range(2):
promise = os.path.join(promise_path, 'promise_%d')
promises_files.append(promise)
worked_file = os.path.join(instance_path, 'promise_worked_%d')
lockfile = os.path.join(instance_path, 'lock')
with open(promise, 'w') as f:
f.write("""#!/usr/bin/env sh
touch "%(worked_file)s"
[[ ! -f "%(lockfile)s" ]] || { touch "%(lockfile)s" ; sleep 5 }
exit 0""" % {'worked_file': worked_file, 'lockfile': lockfile})
os.chmod(promise, 0777)
self.assertTrue(self.grid.processComputerPartitionList())
for file_ in promises_files:
self.assertTrue(os.path.isfile(file_))
self.assertEquals(self.error, 1)
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