From 3ee6542b5d5c5c460ead70c0c41e5885ac4a02fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Ninivin?= <cedric.leninivin@tiolive.com> Date: Fri, 21 Sep 2012 16:24:57 +0200 Subject: [PATCH] Added test on multi partitions --- slapos/tests/slapgrid.py | 271 ++++++++++++++++----------------------- 1 file changed, 114 insertions(+), 157 deletions(-) diff --git a/slapos/tests/slapgrid.py b/slapos/tests/slapgrid.py index 8c5452f61..7c475ad16 100644 --- a/slapos/tests/slapgrid.py +++ b/slapos/tests/slapgrid.py @@ -54,12 +54,12 @@ class BasicMixin: def setUp(self): self._tempdir = tempfile.mkdtemp() + self.software_root = os.path.join(self._tempdir, 'software') + self.instance_root = os.path.join(self._tempdir, 'instance') logging.basicConfig(level=logging.DEBUG) self.setSlapgrid() def setSlapgrid(self, develop=False): - self.software_root = os.path.join(self._tempdir, 'software') - self.instance_root = os.path.join(self._tempdir, 'instance') if getattr(self, 'master_url', None) is None: self.master_url = 'http://127.0.0.1:80/' self.computer_id = 'computer' @@ -219,34 +219,49 @@ touch worked""") class ComputerForTest: + """ + Class to set up environment for tests setting instance, software + and server response + """ def __init__(self, software_root, instance_root, instance_amount=1, software_amount=1): + """ + Will set up instances, software and sequence + """ + self.sequence = [] self.instance_amount = instance_amount self.software_amount = software_amount self.software_root = software_root self.instance_root = instance_root - self.sequence = [] self.setSoftwares() self.setInstances() + def setSoftwares(self): + """ + Will set requested amount of software + """ + self.software_list = range(0,self.software_amount) + for i in self.software_list: + name = str(i) + self.software_list[i] = SoftwareForTest(self.software_root, name=name) + def setInstances(self): + """ + Will set requested amount of instance giving them by default first software + """ self.instance_list = range(0, self.instance_amount) for i in self.instance_list: name = str(i) self.instance_list[i] = InstanceForTest(self.instance_root, name=name, software=self.software_list[0]) - def setSoftwares(self): - self.software_list = range(0,self.software_amount) - for i in self.software_list: - name = str(i) - self.software_list[i] = SoftwareForTest(self.software_root, name=name) - print self.software_list - def getComputer (self, computer_id): + """ + Will return current requested state of computer + """ slap_computer = slapos.slap.Computer(computer_id) slap_computer._software_release_list = [] slap_computer._computer_partition_list = [] @@ -256,6 +271,11 @@ class ComputerForTest: return slap_computer def getServerResponse(self): + """ + Define _callback. + Will register global sequence of message, sequence by partition + and error and error message by partition + """ def server_response(self_httplib, path, method, body, header): parsed_url = urlparse.urlparse(path.lstrip('/')) self.sequence.append(parsed_url.path) @@ -279,6 +299,9 @@ class ComputerForTest: instance.state = 'stopped' return (200, {}, '') if parsed_url.path == 'softwareInstanceError': + instance.error_log = '\n'.join([line for line \ + in parsed_qs['error_log'][0].splitlines() + if 'dropPrivileges' not in line]) instance.error = True return (200, {}, '') else: @@ -292,10 +315,11 @@ class InstanceForTest: """ def __init__(self, instance_root, name, software): self.instance_root = instance_root + self.software = software self.requested_state = 'stopped' - self.sate = None + self.state = None self.error = False - self.software = software + self.error_log = None self.sequence = [] self.name = name if not os.path.isdir(self.instance_root): @@ -305,6 +329,9 @@ class InstanceForTest: self.timestamp = None def getInstance (self, computer_id): + """ + Will return current requested state of instance + """ partition = slapos.slap.ComputerPartition(computer_id, self.name) partition._software_release_document = self.getSoftwareRelease() partition._requested_state = self.requested_state @@ -313,18 +340,28 @@ class InstanceForTest: return partition def getSoftwareRelease (self): + """ + Return software release for Instance + """ sr = slapos.slap.SoftwareRelease() sr._software_release = self.software.name return sr class SoftwareForTest: - + """ + Class to prepare and simulate software. + each instance has a sotfware attributed + """ def __init__(self, software_root, name=''): + """ + Will set file and variable for software + """ self.software_root = software_root + if not os.path.isdir(self.software_root): + os.mkdir(self.software_root) self.name = 'http://sr%s/' % name self.sequence = [] - os.mkdir(self.software_root) self.software_hash = \ slapos.grid.utils.getSoftwareUrlHash(self.name) self.srdir = os.path.join(self.software_root, self.software_hash) @@ -335,14 +372,23 @@ class SoftwareForTest: self.setBuildout() def setTemplateCfg (self,template = """[buildout]"""): + """ + Set template.cfg + """ open(os.path.join(self.srdir, 'template.cfg'), 'w').write(template) def setBuildout (self,buildout = """#!/bin/sh touch worked"""): + """ + Set a buildout exec in bin + """ open(os.path.join(self.srbindir, 'buildout'), 'w').write(buildout) os.chmod(os.path.join(self.srbindir, 'buildout'), 0755) def setPeriodicity(self,periodicity): + """ + Set a periodicity file + """ open(os.path.join(self.srdir, 'periodicity'), 'w').write( """%s""" % (periodicity)) @@ -503,22 +549,12 @@ touch worked""") def test_one_partition_started_stopped(self): - self.started = True - self.sequence = [] - httplib.HTTPConnection._callback = self._server_response('started') + computer = ComputerForTest(self.software_root,self.instance_root) + instance = computer.instance_list[0] + httplib.HTTPConnection._callback = computer.getServerResponse() - os.mkdir(self.software_root) - os.mkdir(self.instance_root) - partition_path = os.path.join(self.instance_root, '0') - os.mkdir(partition_path, 0750) - 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 + instance.requested_state = 'started' + instance.software.setBuildout("""#!/bin/sh touch worked && mkdir -p etc/run && ( @@ -536,13 +572,12 @@ HEREDOC )> etc/run/wrapper && chmod 755 etc/run/wrapper """ % dict(python = sys.executable)) - os.chmod(os.path.join(srbindir, 'buildout'), 0755) self.assertTrue(self.grid.processComputerPartitionList()) self.assertSortedListEqual(os.listdir(self.instance_root), ['0', 'etc', 'var']) - self.assertSortedListEqual(os.listdir(partition_path), ['.0_wrapper.log', + self.assertSortedListEqual(os.listdir(instance.partition_path), ['.0_wrapper.log', 'worked', 'buildout.cfg', 'etc']) - wrapper_log = os.path.join(partition_path, '.0_wrapper.log') + wrapper_log = os.path.join(instance.partition_path, '.0_wrapper.log') tries = 10 while tries > 0: tries -= 1 @@ -552,21 +587,18 @@ chmod 755 etc/run/wrapper os.path.getsize(wrapper_log) self.assertTrue('Working' in open(wrapper_log, 'r').read()) self.assertSortedListEqual(os.listdir(self.software_root), - [software_hash]) - self.assertEqual(self.sequence, + [instance.software.software_hash]) + self.assertEqual(computer.sequence, ['getFullComputerInformation', 'availableComputerPartition', 'startedComputerPartition']) - self.assertTrue(self.started) - - self.stopped = False - self.sequence = [] - self.setSlapgrid() - httplib.HTTPConnection._callback = self._server_response('stopped') + self.assertEqual(instance.state,'started') - self.assertTrue(self.grid.processComputerPartitionList()) + computer.sequence = [] + instance.requested_state = 'stopped' + self.assertTrue(self.launchSlapgrid()) self.assertSortedListEqual(os.listdir(self.instance_root), ['0', 'etc', 'var']) - self.assertSortedListEqual(os.listdir(partition_path), ['.0_wrapper.log', + self.assertSortedListEqual(os.listdir(instance.partition_path), ['.0_wrapper.log', '.0_wrapper.log.1', 'worked', 'buildout.cfg', 'etc']) tries = 10 expected_text = 'Signal handler called with signal 15' @@ -577,10 +609,10 @@ chmod 755 etc/run/wrapper break time.sleep(0.2) self.assertTrue(found) - self.assertEqual(self.sequence, + self.assertEqual(computer.sequence, ['getFullComputerInformation', 'availableComputerPartition', 'stoppedComputerPartition']) - self.assertTrue(self.stopped) + self.assertEqual(instance.state,'stopped') def test_one_partition_stopped_started(self): @@ -796,37 +828,46 @@ class TestSlapgridCPPartitionProcessing (MasterMixin, unittest.TestCase): If time between last processing of instance and now is superior to periodicity then instance should be proceed 1. We set a wanted maximum_periodicity in periodicity file in - in software release directory + in one software release directory and not the other one 2. We process computer partition and check if wanted_periodicity was used as maximum_periodicty 3. We wait for a time superior to wanted_periodicty - 4. We launch processComputerPartition and check that partition is - processed one more time + 4. We launch processComputerPartition and check that partition using + software with periodicity was runned and not the other 5. We check that modification time of .timestamp was modified """ - computer = ComputerForTest(self.software_root,self.instance_root) - instance = computer.instance_list[0] + computer = ComputerForTest(self.software_root,self.instance_root,20,20) + instance0 = computer.instance_list[0] timestamp = str(int(time.time()-5)) + instance0.timestamp = timestamp + for instance in computer.instance_list[1:]: + instance.software = \ + computer.software_list[computer.instance_list.index(instance)] + instance.timestamp = timestamp - instance.timestamp = timestamp wanted_periodicity = 3 - instance.software.setPeriodicity(wanted_periodicity) + instance0.software.setPeriodicity(wanted_periodicity) httplib.HTTPConnection._callback = computer.getServerResponse() self.launchSlapgrid() self.assertNotEqual(wanted_periodicity,self.grid.maximum_periodicity) last_runtime = os.path.getmtime( - os.path.join(instance.partition_path, '.timestamp')) + os.path.join(instance0.partition_path, '.timestamp')) time.sleep(wanted_periodicity + 1) + for instance in computer.instance_list[1:]: + self.assertEqual(instance.sequence, + ['availableComputerPartition', 'stoppedComputerPartition']) self.launchSlapgrid() - self.assertEqual(computer.sequence, - ['getFullComputerInformation', 'availableComputerPartition', - 'stoppedComputerPartition', 'getFullComputerInformation', + self.assertEqual(instance0.sequence, + ['availableComputerPartition', 'stoppedComputerPartition', 'availableComputerPartition', 'stoppedComputerPartition', ]) + for instance in computer.instance_list[1:]: + self.assertEqual(instance.sequence, + ['availableComputerPartition', 'stoppedComputerPartition']) self.assertGreater( - os.path.getmtime(os.path.join(instance.partition_path,'.timestamp')), + os.path.getmtime(os.path.join(instance0.partition_path,'.timestamp')), last_runtime) self.assertNotEqual(wanted_periodicity,self.grid.maximum_periodicity) @@ -1224,59 +1265,17 @@ exit 0""" % {'worked_file': worked_file}) self.assertTrue(self.started) def test_stderr_has_been_sent(self): + computer = ComputerForTest(self.software_root,self.instance_root) + instance = computer.instance_list[0] + httplib.HTTPConnection._callback = computer.getServerResponse() - 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 == 'getFullComputerInformation' 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') - sr = slapos.slap.SoftwareRelease() - sr._software_release = 'http://sr/' - partition._software_release_document = sr - partition._requested_state = 'started' - slap_computer._computer_partition_list = [partition] - return (200, {}, xml_marshaller.xml_marshaller.dumps(slap_computer)) - if parsed_url.path == 'availableComputerPartition' and \ - method == 'POST' and 'computer_partition_id' in parsed_qs: - return (200, {}, '') - if parsed_url.path == 'startedComputerPartition' and \ - method == 'POST' and 'computer_partition_id' in parsed_qs: - self.assertEqual(parsed_qs['computer_partition_id'][0], '0') - self.started = True - return (200, {}, '') - 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 + instance.requested_state = 'started' self.fake_waiting_time = 0.5 - self.error = False - self.started = False - instance_path = self._create_instance('0') - self._bootstrap() - - promise_path = os.path.join(instance_path, 'etc', 'promise') + promise_path = os.path.join(instance.partition_path, 'etc', 'promise') os.makedirs(promise_path) succeed = os.path.join(promise_path, 'stderr_writer') - worked_file = os.path.join(instance_path, 'stderr_worked') + worked_file = os.path.join(instance.partition_path, 'stderr_worked') with open(succeed, 'w') as f: f.write("""#!/usr/bin/env sh touch "%(worked_file)s" @@ -1286,65 +1285,23 @@ exit 127""" % {'worked_file': worked_file}) self.assertFalse(self.grid.processComputerPartitionList()) self.assertTrue(os.path.isfile(worked_file)) - self.assertEqual(self.error_log, 'Error') - self.assertTrue(self.error) - self.assertFalse(self.started) + self.assertEqual(instance.error_log, 'Error') + self.assertTrue(instance.error) + self.assertIsNone(instance.state) def test_timeout_works(self): + computer = ComputerForTest(self.software_root,self.instance_root) + instance = computer.instance_list[0] + httplib.HTTPConnection._callback = computer.getServerResponse() - 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 == 'getFullComputerInformation' 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') - sr = slapos.slap.SoftwareRelease() - sr._software_release = 'http://sr/' - partition._software_release_document = sr - partition._requested_state = 'started' - slap_computer._computer_partition_list = [partition] - return (200, {}, xml_marshaller.xml_marshaller.dumps(slap_computer)) - if parsed_url.path == 'availableComputerPartition' and \ - method == 'POST' and 'computer_partition_id' in parsed_qs: - return (200, {}, '') - if parsed_url.path == 'startedComputerPartition' and \ - method == 'POST' and 'computer_partition_id' in parsed_qs: - self.assertEqual(parsed_qs['computer_partition_id'][0], '0') - self.started = True - return (200, {}, '') - 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 + instance.requested_state = 'started' self.fake_waiting_time = 0.2 - self.error = False - self.started = False - instance_path = self._create_instance('0') - self._bootstrap() - - promise_path = os.path.join(instance_path, 'etc', 'promise') + promise_path = os.path.join(instance.partition_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') + worked_file = os.path.join(instance.partition_path, 'timed_out_worked') with open(succeed, 'w') as f: f.write("""#!/usr/bin/env sh touch "%(worked_file)s" @@ -1354,8 +1311,8 @@ exit 0""" % {'worked_file': worked_file}) self.assertFalse(self.grid.processComputerPartitionList()) self.assertTrue(os.path.isfile(worked_file)) - self.assertTrue(self.error) - self.assertFalse(self.started) + self.assertTrue(instance.error) + self.assertIsNone(instance.state) def test_two_succeeding_promises(self): -- 2.30.9