Commit 990ccf77 authored by Cédric Le Ninivin's avatar Cédric Le Ninivin Committed by Romain Courteaud

test_slapgrid_slaptool: Port latest changes

parent 456a7a79
##############################################################################
#
# coding: utf-8
# Copyright (c) 2010 Vifib SARL and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
......@@ -45,6 +45,7 @@ import json
import re
import grp
import hashlib
import errno
import mock
from mock import patch
......@@ -65,6 +66,11 @@ import slapos.grid.SlapObject
from slapos import manager as slapmanager
from slapos.util import dumps
from slapos import __path__ as slapos_path
from zope import __path__ as zope_path
PROMISE_PATHS = sorted(set(map(os.path.dirname, list(slapos_path) + list(zope_path))))
import httmock
......@@ -113,6 +119,10 @@ touch worked
"""
PROMISE_CONTENT_TEMPLATE = """
# coding: utf-8
import sys
sys.path[0:0] = %(paths)r
from zope.interface import implementer
from slapos.grid.promise import interface
from slapos.grid.promise import GenericPromise
......@@ -122,7 +132,7 @@ class RunPromise(GenericPromise):
def __init__(self, config):
super(RunPromise, self).__init__(config)
self.setPeriodicity(minute=%(periodicity)s)
self.setPeriodicity(minute=%(periodicity)r)
def sense(self):
%(content)s
......@@ -133,10 +143,10 @@ class RunPromise(GenericPromise):
self.logger.info("success")
def anomaly(self):
return self._anomaly(result_count=2, failure_amount=%(failure_amount)s)
return self._anomaly(result_count=2, failure_amount=%(failure_amount)r)
def test(self):
return self._test(result_count=1, failure_amount=%(failure_amount)s)
return self._test(result_count=1, failure_amount=%(failure_amount)r)
"""
class BasicMixin(object):
......@@ -150,6 +160,17 @@ class BasicMixin(object):
del os.environ['SLAPGRID_INSTANCE_ROOT']
logging.basicConfig(level=logging.DEBUG)
self.setSlapgrid()
self.setMock()
def getTestComputerClass(self):
return ComputerForTest
def setMock(self):
module = slapos.grid.SlapObject
func = 'getPythonExecutableFromSoftwarePath'
orig = getattr(module, func)
self.addCleanup(setattr, module, func, orig)
setattr(module, func, lambda software_path: None)
def setSlapgrid(self, develop=False, force_stop=False):
if getattr(self, 'master_url', None) is None:
......@@ -160,6 +181,9 @@ class BasicMixin(object):
'supervisord')
self.usage_report_periodicity = 1
self.buildout = None
self.certificate_repository_path = os.path.join(self._tempdir, 'partition_pki');
if not os.path.isdir(self.certificate_repository_path):
os.mkdir(self.certificate_repository_path)
self.grid = slapgrid.Slapgrid(self.software_root,
self.instance_root,
self.master_url,
......@@ -168,7 +192,8 @@ class BasicMixin(object):
develop=develop,
logger=logging.getLogger(),
shared_part_list=self.shared_parts_root,
force_stop=force_stop)
force_stop=force_stop,
certificate_repository_path=self.certificate_repository_path)
self.grid._manager_list = self.manager_list
# monkey patch buildout bootstrap
......@@ -287,7 +312,7 @@ class TestBasicSlapgridCP(BasicMixin, unittest.TestCase):
def test_environment_variable_HOME(self):
# When running instance, $HOME is set to the partition path
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
partition = computer.instance_list[0]
partition.requested_state = 'started'
partition.software.setBuildout('#!/bin/sh\n echo $HOME > env_HOME')
......@@ -298,7 +323,7 @@ class TestBasicSlapgridCP(BasicMixin, unittest.TestCase):
def test_no_user_site_packages(self):
# When running instance buildout, python's user site packages are ignored
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
partition = computer.instance_list[0]
partition.requested_state = 'started'
......@@ -409,6 +434,11 @@ class ComputerForTest(object):
'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)
......@@ -461,15 +491,21 @@ class ComputerForTest(object):
else:
return {'status_code': 500}
def getTestSoftwareClass(self):
return SoftwareForTest
def setSoftwares(self):
"""
Will set requested amount of software
"""
self.software_list = [
SoftwareForTest(self.software_root, name=str(i))
self.getTestSoftwareClass()(self.software_root, name=str(i))
for i in range(self.software_amount)
]
def getTestInstanceClass(self):
return InstanceForTest
def setInstances(self):
"""
Will set requested amount of instance giving them by default first software
......@@ -480,7 +516,7 @@ class ComputerForTest(object):
software = None
self.instance_list = [
InstanceForTest(self.instance_root, name=str(i), software=software)
self.getTestInstanceClass()(self.instance_root, name=str(i), software=software)
for i in range(self.instance_amount)
]
......@@ -527,7 +563,6 @@ class InstanceForTest(object):
Will return current requested state of instance
"""
partition = slapos.slap.ComputerPartition(computer_id, self.name)
partition._instance_guid = self.name
partition._software_release_document = self.getSoftwareRelease()
partition._requested_state = self.requested_state
if getattr(self, 'filter_dict', None):
......@@ -577,7 +612,8 @@ class InstanceForTest(object):
{'success': success,
'content': promise_content,
'failure_amount': failure_count,
'periodicity': periodicity}
'periodicity': periodicity,
'paths': PROMISE_PATHS}
with open(os.path.join(promise_dir, promise_name), 'w') as f:
f.write(_promise_content)
......@@ -600,7 +636,7 @@ class InstanceForTest(object):
class SoftwareForTest(object):
"""
Class to prepare and simulate software.
each instance has a sotfware attributed
each instance has a software attributed
"""
def __init__(self, software_root, name=''):
"""
......@@ -680,7 +716,7 @@ class DummyManager(object):
class TestSlapgridCPWithMaster(MasterMixin, unittest.TestCase):
def test_nothing_to_do(self):
computer = ComputerForTest(self.software_root, self.instance_root, 0, 0)
computer = self.getTestComputerClass()(self.software_root, self.instance_root, 0, 0)
with httmock.HTTMock(computer.request_handler):
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertInstanceDirectoryListEqual([])
......@@ -689,7 +725,7 @@ class TestSlapgridCPWithMaster(MasterMixin, unittest.TestCase):
self.assertEqual(stat.S_IMODE(st.st_mode), 0o755)
def test_one_partition(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
......@@ -700,14 +736,17 @@ class TestSlapgridCPWithMaster(MasterMixin, unittest.TestCase):
six.assertCountEqual(self, os.listdir(self.software_root), [instance.software.software_hash])
self.assertEqual(computer.sequence,
['/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/stoppedComputerPartition'])
self.assertEqual(open(os.path.join(self.certificate_repository_path, '0.crt')).read(), 'SLAPOS_cert')
self.assertEqual(open(os.path.join(self.certificate_repository_path, '0.key')).read(), 'SLAPOS_key')
def test_one_partition_instance_cfg(self):
"""
Check that slapgrid processes instance is profile is not named
"template.cfg" but "instance.cfg".
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
......@@ -718,13 +757,14 @@ class TestSlapgridCPWithMaster(MasterMixin, unittest.TestCase):
six.assertCountEqual(self, os.listdir(self.software_root), [instance.software.software_hash])
self.assertEqual(computer.sequence,
['/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/stoppedComputerPartition'])
def test_one_free_partition(self):
"""
Test if slapgrid cp does not process "free" partition
"""
computer = ComputerForTest(self.software_root,
computer = self.getTestComputerClass()(self.software_root,
self.instance_root,
software_amount=0)
with httmock.HTTMock(computer.request_handler):
......@@ -737,7 +777,7 @@ class TestSlapgridCPWithMaster(MasterMixin, unittest.TestCase):
self.assertEqual(partition.sequence, [])
def test_one_partition_started(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
partition = computer.instance_list[0]
partition.requested_state = 'started'
......@@ -752,11 +792,12 @@ class TestSlapgridCPWithMaster(MasterMixin, unittest.TestCase):
six.assertCountEqual(self, os.listdir(self.software_root), [partition.software.software_hash])
self.assertEqual(computer.sequence,
['/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/startedComputerPartition'])
self.assertEqual(partition.state, 'started')
def test_one_partition_started_fail(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
partition = computer.instance_list[0]
partition.requested_state = 'started'
......@@ -771,6 +812,7 @@ class TestSlapgridCPWithMaster(MasterMixin, unittest.TestCase):
six.assertCountEqual(self, os.listdir(self.software_root), [partition.software.software_hash])
self.assertEqual(computer.sequence,
['/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/startedComputerPartition'])
self.assertEqual(partition.state, 'started')
......@@ -786,12 +828,16 @@ exit 1
'.slapos-retention-lock-delay', '.slapgrid-0-error.log'])
self.assertEqual(computer.sequence,
['/getFullComputerInformation',
'/startedComputerPartition', '/getHateoasUrl', '/getJIOAPIUrl',
'/getFullComputerInformation', '/softwareInstanceError'])
'/getComputerPartitionCertificate',
'/startedComputerPartition',
'/getHateoasUrl',
'/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/softwareInstanceError'])
self.assertEqual(instance.state, 'started')
def test_one_partition_started_stopped(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
......@@ -826,6 +872,7 @@ chmod 755 etc/run/wrapper
six.assertCountEqual(self, os.listdir(self.software_root), [instance.software.software_hash])
self.assertEqual(computer.sequence,
['/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/startedComputerPartition'])
self.assertEqual(instance.state, 'started')
......@@ -838,7 +885,9 @@ chmod 755 etc/run/wrapper
'etc', 'software_release', 'worked', '.slapos-retention-lock-delay'])
self.assertLogContent(wrapper_log, 'Signal handler called with signal 15')
self.assertEqual(computer.sequence,
['/getHateoasUrl', '/getJIOAPIUrl', '/getFullComputerInformation',
['/getHateoasUrl',
'/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/stoppedComputerPartition'])
self.assertEqual(instance.state, 'stopped')
......@@ -848,7 +897,7 @@ chmod 755 etc/run/wrapper
processes will be stopped even if instance is broken (buildout fails
to run) but status is still started.
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
......@@ -884,6 +933,7 @@ chmod 755 etc/run/wrapper
[instance.software.software_hash])
self.assertEqual(computer.sequence,
['/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/startedComputerPartition'])
self.assertEqual(instance.state, 'started')
......@@ -900,12 +950,14 @@ exit 1
'.slapos-retention-lock-delay', '.slapgrid-0-error.log'])
self.assertLogContent(wrapper_log, 'Signal handler called with signal 15')
self.assertEqual(computer.sequence,
['/getHateoasUrl', '/getJIOAPIUrl', '/getFullComputerInformation',
['/getHateoasUrl',
'/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/softwareInstanceError'])
self.assertEqual(instance.state, 'started')
def test_one_partition_stopped_started(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'stopped'
......@@ -920,6 +972,7 @@ exit 1
[instance.software.software_hash])
self.assertEqual(computer.sequence,
['/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/stoppedComputerPartition'])
self.assertEqual('stopped', instance.state)
......@@ -936,7 +989,9 @@ exit 1
wrapper_log = os.path.join(instance.partition_path, '.0_wrapper.log')
self.assertLogContent(wrapper_log, 'Working')
self.assertEqual(computer.sequence,
['/getHateoasUrl', '/getJIOAPIUrl', '/getFullComputerInformation',
['/getHateoasUrl',
'/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/startedComputerPartition'])
self.assertEqual('started', instance.state)
......@@ -945,7 +1000,7 @@ exit 1
Test that an existing partition with "destroyed" status will only be
stopped by slapgrid-cp, not processed
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'destroyed'
......@@ -962,6 +1017,7 @@ exit 1
six.assertCountEqual(self, os.listdir(self.software_root), [instance.software.software_hash])
self.assertEqual(computer.sequence,
['/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/stoppedComputerPartition'])
self.assertEqual('stopped', instance.state)
......@@ -995,7 +1051,7 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest.TestCase):
4.Wait for it to fail
5.Wait for file generated by monkeypacthed bang to appear
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
partition = computer.instance_list[0]
partition.requested_state = 'started'
......@@ -1024,7 +1080,7 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest.TestCase):
4.Wait for it to fail
5.Check that file generated by monkeypacthed bang do not appear
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
partition = computer.instance_list[0]
partition.requested_state = 'started'
......@@ -1065,7 +1121,7 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest.TestCase):
Certificates used for the bang are also checked
(ie: watchdog id in process name)
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
certificate_repository_path = os.path.join(self._tempdir, 'partition_pki')
......@@ -1090,7 +1146,7 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest.TestCase):
Test that a process going to a mode not watched by watchdog
in supervisord is not banged if watched by watchdog
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
instance = computer.instance_list[0]
watchdog = Watchdog(
......@@ -1113,7 +1169,7 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest.TestCase):
is not banged if not watched by watchdog
(ie: no watchdog id in process name)
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
instance = computer.instance_list[0]
watchdog = Watchdog(
......@@ -1135,7 +1191,7 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest.TestCase):
existing), check that bang file is created and contains the timestamp of
.timestamp file.
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
certificate_repository_path = os.path.join(self._tempdir, 'partition_pki')
......@@ -1173,7 +1229,7 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest.TestCase):
Practically speaking, .timestamp file in the partition does not exsit.
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
certificate_repository_path = os.path.join(self._tempdir, 'partition_pki')
......@@ -1208,7 +1264,7 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest.TestCase):
* First bang is transmitted
* subsequent bangs are ignored until a deployment is successful.
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
certificate_repository_path = os.path.join(self._tempdir, 'partition_pki')
......@@ -1258,7 +1314,7 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest.TestCase):
* The process crashes again, watchdog calls bang
* The process crashes again, watchdog ignroes it
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
certificate_repository_path = os.path.join(self._tempdir, 'partition_pki')
......@@ -1335,7 +1391,7 @@ class TestSlapgridCPWithMasterWatchdog(MasterMixin, unittest.TestCase):
class TestSlapgridCPPartitionProcessing(MasterMixin, unittest.TestCase):
def test_partition_timestamp(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
timestamp = str(int(time.time()))
......@@ -1349,7 +1405,6 @@ class TestSlapgridCPPartitionProcessing(MasterMixin, unittest.TestCase):
six.assertCountEqual(self, os.listdir(self.software_root), [instance.software.software_hash])
timestamp_path = os.path.join(instance.partition_path, '.timestamp')
self.setSlapgrid()
self.grid.computer._synced = False
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
with open(timestamp_path) as f:
self.assertIn(timestamp, f.read())
......@@ -1357,7 +1412,7 @@ class TestSlapgridCPPartitionProcessing(MasterMixin, unittest.TestCase):
['/stoppedComputerPartition'])
def test_partition_timestamp_develop(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
timestamp = str(int(time.time()))
......@@ -1380,7 +1435,7 @@ class TestSlapgridCPPartitionProcessing(MasterMixin, unittest.TestCase):
'/stoppedComputerPartition'])
def test_partition_old_timestamp(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
timestamp = str(int(time.time()))
......@@ -1398,7 +1453,7 @@ class TestSlapgridCPPartitionProcessing(MasterMixin, unittest.TestCase):
[ '/stoppedComputerPartition'])
def test_partition_timestamp_new_timestamp(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
timestamp = str(int(time.time()))
......@@ -1414,16 +1469,19 @@ class TestSlapgridCPPartitionProcessing(MasterMixin, unittest.TestCase):
self.assertEqual(self.launchSlapgrid(), slapgrid.SLAPGRID_SUCCESS)
self.assertEqual(self.launchSlapgrid(), slapgrid.SLAPGRID_SUCCESS)
self.assertEqual(computer.sequence,
['/getHateoasUrl', '/getJIOAPIUrl',
['/getHateoasUrl',
'/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/stoppedComputerPartition',
'/getHateoasUrl', '/getJIOAPIUrl', '/getFullComputerInformation',
'/getHateoasUrl',
'/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/stoppedComputerPartition',
'/getHateoasUrl', '/getJIOAPIUrl',
'/getHateoasUrl',
'/getFullComputerInformation'])
def test_partition_timestamp_no_timestamp(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
timestamp = str(int(time.time()))
......@@ -1439,10 +1497,13 @@ class TestSlapgridCPPartitionProcessing(MasterMixin, unittest.TestCase):
instance.timestamp = None
self.launchSlapgrid()
self.assertEqual(computer.sequence,
['/getHateoasUrl', '/getJIOAPIUrl',
['/getHateoasUrl',
'/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/stoppedComputerPartition',
'/getHateoasUrl', '/getJIOAPIUrl', '/getFullComputerInformation',
'/getHateoasUrl',
'/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/stoppedComputerPartition'])
def test_partition_periodicity_remove_timestamp(self):
......@@ -1450,7 +1511,7 @@ class TestSlapgridCPPartitionProcessing(MasterMixin, unittest.TestCase):
Check that if periodicity forces run of buildout for a partition, it
removes the .timestamp file.
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
timestamp = str(int(time.time()))
......@@ -1488,7 +1549,7 @@ class TestSlapgridCPPartitionProcessing(MasterMixin, unittest.TestCase):
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, 20, 20)
computer = self.getTestComputerClass()(self.software_root, self.instance_root, 20, 20)
with httmock.HTTMock(computer.request_handler):
instance0 = computer.instance_list[0]
timestamp = str(int(time.time() - 5))
......@@ -1529,7 +1590,7 @@ class TestSlapgridCPPartitionProcessing(MasterMixin, unittest.TestCase):
Check that periodicity forces processing a partition even if it is not
started.
"""
computer = ComputerForTest(self.software_root, self.instance_root, 20, 20)
computer = self.getTestComputerClass()(self.software_root, self.instance_root, 20, 20)
with httmock.HTTMock(computer.request_handler):
instance0 = computer.instance_list[0]
timestamp = str(int(time.time() - 5))
......@@ -1568,7 +1629,7 @@ class TestSlapgridCPPartitionProcessing(MasterMixin, unittest.TestCase):
Check that periodicity forces processing a partition even if it is not
started.
"""
computer = ComputerForTest(self.software_root, self.instance_root, 20, 20)
computer = self.getTestComputerClass()(self.software_root, self.instance_root, 20, 20)
with httmock.HTTMock(computer.request_handler):
instance0 = computer.instance_list[0]
timestamp = str(int(time.time() - 5))
......@@ -1615,7 +1676,7 @@ class TestSlapgridCPPartitionProcessing(MasterMixin, unittest.TestCase):
4. We launch slapgrid anew and check that install as not been called again
"""
computer = ComputerForTest(self.software_root, self.instance_root, 1, 1)
computer = self.getTestComputerClass()(self.software_root, self.instance_root, 1, 1)
with httmock.HTTMock(computer.request_handler):
timestamp = str(int(time.time()))
instance = computer.instance_list[0]
......@@ -1638,7 +1699,7 @@ class TestSlapgridCPPartitionProcessing(MasterMixin, unittest.TestCase):
new setup and one time because of periodicity = 0)
"""
computer = ComputerForTest(self.software_root, self.instance_root, 1, 1)
computer = self.getTestComputerClass()(self.software_root, self.instance_root, 1, 1)
with httmock.HTTMock(computer.request_handler):
timestamp = str(int(time.time()))
instance = computer.instance_list[0]
......@@ -1654,7 +1715,7 @@ class TestSlapgridCPPartitionProcessing(MasterMixin, unittest.TestCase):
1. We set up two instance one using a corrupted buildout
2. One will fail but the other one will be processed correctly
"""
computer = ComputerForTest(self.software_root, self.instance_root, 2, 2)
computer = self.getTestComputerClass()(self.software_root, self.instance_root, 2, 2)
with httmock.HTTMock(computer.request_handler):
instance0 = computer.instance_list[0]
instance1 = computer.instance_list[1]
......@@ -1672,7 +1733,7 @@ exit 42""")
1. We set up two instance but remove software path of one
2. One will fail but the other one will be processed correctly
"""
computer = ComputerForTest(self.software_root, self.instance_root, 2, 2)
computer = self.getTestComputerClass()(self.software_root, self.instance_root, 2, 2)
with httmock.HTTMock(computer.request_handler):
instance0 = computer.instance_list[0]
instance1 = computer.instance_list[1]
......@@ -1689,7 +1750,7 @@ exit 42""")
1. We set up two instance but remove software bin path of one
2. One will fail but the other one will be processed correctly
"""
computer = ComputerForTest(self.software_root, self.instance_root, 2, 2)
computer = self.getTestComputerClass()(self.software_root, self.instance_root, 2, 2)
with httmock.HTTMock(computer.request_handler):
instance0 = computer.instance_list[0]
instance1 = computer.instance_list[1]
......@@ -1706,7 +1767,7 @@ exit 42""")
1. We set up two instances but remove path of one
2. One will fail but the other one will be processed correctly
"""
computer = ComputerForTest(self.software_root, self.instance_root, 2, 2)
computer = self.getTestComputerClass()(self.software_root, self.instance_root, 2, 2)
with httmock.HTTMock(computer.request_handler):
instance0 = computer.instance_list[0]
instance1 = computer.instance_list[1]
......@@ -1723,7 +1784,7 @@ exit 42""")
1. We set up an instance using a corrupted buildout
2. It will fail, make sure that whole log is sent to master
"""
computer = ComputerForTest(self.software_root, self.instance_root, 1, 1)
computer = self.getTestComputerClass()(self.software_root, self.instance_root, 1, 1)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
......@@ -1741,41 +1802,51 @@ echo %s; echo %s; exit 42""" % (line1, line2))
def test_processing_summary(self):
"""At the end of instance processing, a summary of partition with errors is displayed.
"""
computer = ComputerForTest(self.software_root, self.instance_root, 3, 3)
_, instance1, instance2 = computer.instance_list
computer = self.getTestComputerClass()(self.software_root, self.instance_root, 4, 4)
_, instance1, instance2, instance3 = computer.instance_list
# instance0 has no problem, it is not in summary
# instance 1 fails software
instance1 = computer.instance_list[1]
instance1.software = computer.software_list[1]
instance1.software.setBuildout("""#!/bin/sh
echo fake buildout error
exit 1""")
# instance 2 fails promises
instance2 = computer.instance_list[2]
# instance 2 fails old style promises
instance2.requested_state = 'started'
instance2.setPromise("failing_promise", """#!/bin/sh
echo fake promise error
echo héhé fake promise error
exit 1""")
# instance 3 fails promise plugin
instance3.requested_state = 'started'
instance3.setPluginPromise(
"failing_promise_plugin.py",
promise_content="""if 1:
return self.logger.error("héhé fake promise plugin error")
""",
)
with httmock.HTTMock(computer.request_handler), \
patch.object(self.grid.logger, 'info',) as dummyLogger:
self.launchSlapgrid()
# reconstruct the string like logger does
self.assertEqual(
dummyLogger.mock_calls[-4][1][0] % dummyLogger.mock_calls[-4][1][1:],
dummyLogger.mock_calls[-5][1][0] % dummyLogger.mock_calls[-5][1][1:],
'Error while processing the following partitions:')
self.assertRegexpMatches(
dummyLogger.mock_calls[-3][1][0] % dummyLogger.mock_calls[-3][1][1:],
dummyLogger.mock_calls[-4][1][0] % dummyLogger.mock_calls[-4][1][1:],
r" 1\[\(not ready\)\]: Failed to run buildout profile in directory '.*/instance/1':\nfake buildout error\n\n")
self.assertEqual(
dummyLogger.mock_calls[-2][1][0] % dummyLogger.mock_calls[-2][1][1:],
dummyLogger.mock_calls[-3][1][0] % dummyLogger.mock_calls[-3][1][1:],
'Error with promises for the following partitions:')
self.assertEqual(
dummyLogger.mock_calls[-2][1][0] % dummyLogger.mock_calls[-2][1][1:],
" 2[(not ready)]: Promise 'failing_promise' failed with output: héhé fake promise error")
self.assertEqual(
dummyLogger.mock_calls[-1][1][0] % dummyLogger.mock_calls[-1][1][1:],
" 2[(not ready)]: Promise 'failing_promise' failed with output: fake promise error")
" 3[(not ready)]: Promise 'failing_promise_plugin.py' failed with output: héhé fake promise plugin error")
def test_partition_force_stop(self):
"""
......@@ -1785,7 +1856,7 @@ echo %s; echo %s; exit 42""" % (line1, line2))
- services should be stopped
- no report should be sent to master
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -1817,7 +1888,7 @@ class TestSlapgridUsageReport(MasterMixin, unittest.TestCase):
"""
Test than an instance in "destroyed" state is correctly destroyed
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -1832,14 +1903,13 @@ class TestSlapgridUsageReport(MasterMixin, unittest.TestCase):
six.assertCountEqual(self, os.listdir(self.software_root), [instance.software.software_hash])
self.assertEqual(computer.sequence,
['/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/startedComputerPartition'])
self.assertEqual(instance.state, 'started')
# Then destroy the instance
computer.sequence = []
instance.requested_state = 'destroyed'
self.grid.computer._synced = False
self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS)
# Assert partition directory is empty
self.assertInstanceDirectoryListEqual(['0'])
......@@ -1852,6 +1922,7 @@ class TestSlapgridUsageReport(MasterMixin, unittest.TestCase):
self.assertEqual(computer.sequence,
['/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/stoppedComputerPartition',
'/destroyedComputerPartition'])
self.assertEqual(instance.state, 'destroyed')
......@@ -1865,13 +1936,12 @@ class TestSlapgridUsageReport(MasterMixin, unittest.TestCase):
1. Simulate computer containing one "destroyed" partition but with valid SR
2. See if it destroyed
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
computer.sequence = []
instance.requested_state = 'destroyed'
self.grid.computer._synced = False
self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS)
# Assert partition directory is empty
self.assertInstanceDirectoryListEqual(['0'])
......@@ -1884,13 +1954,16 @@ class TestSlapgridUsageReport(MasterMixin, unittest.TestCase):
self.assertEqual(
computer.sequence,
['/getFullComputerInformation', '/stoppedComputerPartition', '/destroyedComputerPartition'])
['/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/stoppedComputerPartition',
'/destroyedComputerPartition'])
def test_slapgrid_not_destroy_bad_instance(self):
"""
Checks that slapgrid-ur don't destroy instance not to be destroyed.
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -1905,13 +1978,12 @@ class TestSlapgridUsageReport(MasterMixin, unittest.TestCase):
six.assertCountEqual(self, os.listdir(self.software_root), [instance.software.software_hash])
self.assertEqual(computer.sequence,
['/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/startedComputerPartition'])
self.assertEqual('started', instance.state)
# Then run usage report and see if it is still working
computer.sequence = []
self.grid.computer._synced = False
self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS)
# registerComputerPartition will create one more file:
from slapos.slap.slap import COMPUTER_PARTITION_REQUEST_LIST_TEMPLATE_FILENAME
......@@ -1939,7 +2011,7 @@ class TestSlapgridUsageReport(MasterMixin, unittest.TestCase):
Test than a free instance (so in "destroyed" state, but empty, without
software_release URI) is ignored by slapgrid-cp.
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.software.name = None
......@@ -1958,14 +2030,13 @@ class TestSlapgridUsageReport(MasterMixin, unittest.TestCase):
Test than a free instance (so in "destroyed" state, but empty, without
software_release URI) is ignored by slapgrid-ur.
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.software.name = None
computer.sequence = []
instance.requested_state = 'destroyed'
self.grid.computer._synced = False
self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS)
# Assert partition directory is empty
self.assertInstanceDirectoryListEqual(['0'])
......@@ -1982,7 +2053,7 @@ class TestSlapgridSoftwareRelease(MasterMixin, unittest.TestCase):
1. We set up a software using a corrupted buildout
2. It will fail, make sure that whole log is sent to master
"""
computer = ComputerForTest(self.software_root, self.instance_root, 1, 1)
computer = self.getTestComputerClass()(self.software_root, self.instance_root, 1, 1)
with httmock.HTTMock(computer.request_handler):
software = computer.software_list[0]
......@@ -1999,7 +2070,7 @@ echo %s; echo %s; exit 42""" % (line1, line2))
self.assertIn('Failed to run buildout', software.error_log)
def test_software_install_generate_buildout_cfg_with_shared_part_list(self):
computer = ComputerForTest(self.software_root, self.instance_root, 1, 1)
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
......@@ -2009,7 +2080,7 @@ echo %s; echo %s; exit 42""" % (line1, line2))
self.assertIn('shared-part-list = %s' % self.shared_parts_root, software.error_log)
def test_remove_software(self):
computer = ComputerForTest(self.software_root, self.instance_root, 1, 1)
computer = self.getTestComputerClass()(self.software_root, self.instance_root, 1, 1)
with httmock.HTTMock(computer.request_handler):
software = computer.software_list[0]
......@@ -2026,7 +2097,7 @@ touch directory/file
def test_remove_software_chmod(self):
# This software is "hard" to remove, as permissions have been changed
computer = ComputerForTest(self.software_root, self.instance_root, 1, 1)
computer = self.getTestComputerClass()(self.software_root, self.instance_root, 1, 1)
with httmock.HTTMock(computer.request_handler):
software = computer.software_list[0]
......@@ -2088,7 +2159,7 @@ buildout = /path/to/buildout/binary
class TestSlapgridCPWithMasterPromise(MasterMixin, unittest.TestCase):
def test_one_failing_promise(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -2105,7 +2176,7 @@ class TestSlapgridCPWithMasterPromise(MasterMixin, unittest.TestCase):
self.assertNotEqual('started', instance.state)
def test_one_succeeding_promise(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -2122,7 +2193,7 @@ class TestSlapgridCPWithMasterPromise(MasterMixin, unittest.TestCase):
self.assertEqual(instance.state, 'started')
def test_stderr_has_been_sent(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
......@@ -2150,7 +2221,7 @@ class TestSlapgridCPWithMasterPromise(MasterMixin, unittest.TestCase):
self.assertIsNone(instance.state)
def test_timeout_works(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -2174,7 +2245,7 @@ class TestSlapgridCPWithMasterPromise(MasterMixin, unittest.TestCase):
self.assertIsNone(instance.state)
def test_two_succeeding_promises(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -2195,7 +2266,7 @@ class TestSlapgridCPWithMasterPromise(MasterMixin, unittest.TestCase):
self.assertEqual(instance.state, 'started')
def test_one_succeeding_one_failing_promises(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -2223,7 +2294,7 @@ class TestSlapgridCPWithMasterPromise(MasterMixin, unittest.TestCase):
self.assertNotEqual('started', instance.state)
def test_one_succeeding_one_timing_out_promises(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -2252,7 +2323,7 @@ class TestSlapgridCPWithMasterPromise(MasterMixin, unittest.TestCase):
self.assertNotEqual(instance.state, 'started')
def test_promise_run_if_partition_started_fail(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -2272,14 +2343,13 @@ exit 1
touch "%s"
exit 127""" % promise_file)
instance.setPromise('promise_script', promise)
self.grid.computer._synced = False
self.assertEqual(self.grid.processComputerPartitionList(),
slapos.grid.slapgrid.SLAPGRID_FAIL)
self.assertTrue(os.path.isfile(promise_file))
self.assertTrue(instance.error)
def test_promise_notrun_if_partition_stopped_fail(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'stopped'
......@@ -2299,19 +2369,19 @@ exit 1
touch "%s"
exit 127""" % promise_file)
instance.setPromise('promise_script', promise)
self.grid.computer._synced = False
self.assertEqual(self.grid.processComputerPartitionList(),
slapos.grid.slapgrid.SLAPGRID_FAIL)
self.assertFalse(os.path.exists(promise_file))
self.assertTrue(instance.error)
class TestSlapgridDestructionLock(MasterMixin, unittest.TestCase):
def test_retention_lock(self):
"""
Higher level test about actual retention (or no-retention) of instance
if specifying a retention lock delay.
"""
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -2327,7 +2397,6 @@ class TestSlapgridDestructionLock(MasterMixin, unittest.TestCase):
)))
instance.requested_state = 'destroyed'
self.grid.computer._synced = False
self.grid.agregateAndSendUsage()
self.assertTrue(os.path.exists(dummy_instance_file_path))
self.assertTrue(os.path.exists(os.path.join(
......@@ -2335,12 +2404,10 @@ class TestSlapgridDestructionLock(MasterMixin, unittest.TestCase):
slapos.grid.SlapObject.Partition.retention_lock_date_filename
)))
self.grid.computer._synced = False
self.grid.agregateAndSendUsage()
self.assertTrue(os.path.exists(dummy_instance_file_path))
time.sleep(1)
self.grid.computer._synced = False
self.grid.agregateAndSendUsage()
self.assertFalse(os.path.exists(dummy_instance_file_path))
......@@ -2467,7 +2534,7 @@ exit 1
self.assertIn(rule, cmd_list)
def test_getFirewallRules(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
self.setFirewallConfig()
self.ip_address_list = computer.ip_address_list
ip = computer.instance_list[0].full_ip_list[0][1]
......@@ -2487,7 +2554,7 @@ exit 1
def test_checkAddFirewallRules(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
self.setFirewallConfig()
# For simulate query rule success
self.grid.firewall_conf['firewall_cmd'] = self.firewall_cmd_add
......@@ -2531,7 +2598,7 @@ exit 1
self.checkRuleFromIpSource(ip, [], rules_list)
def test_partition_no_firewall(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
self.assertEqual(self.grid.processComputerPartitionList(),
......@@ -2542,7 +2609,7 @@ exit 1
)))
def test_partition_firewall_restrict(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
self.setFirewallConfig()
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
......@@ -2563,7 +2630,7 @@ exit 1
self.checkRuleFromIpSource(ip, [], rules_list)
def test_partition_firewall(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
self.setFirewallConfig()
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
......@@ -2586,7 +2653,7 @@ exit 1
@unittest.skip('Always fail: instance.filter_dict can\'t change')
def test_partition_firewall_restricted_access_change(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
self.setFirewallConfig()
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
......@@ -2612,7 +2679,6 @@ exit 1
self.grid.firewall_conf['firewall_cmd'] = self.firewall_cmd_remove
instance.setFilterParameter({'fw_restricted_access': 'on',
'fw_authorized_sources': ''})
self.grid.computer._synced = False
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
with open(rules_path, 'r') as frules:
......@@ -2621,7 +2687,7 @@ exit 1
self.checkRuleFromIpSource(ip, [], rules_list)
def test_partition_firewall_ipsource_accept(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
self.setFirewallConfig()
source_ip = ['10.0.8.10', '10.0.8.11']
self.grid.firewall_conf['authorized_sources'] = [source_ip[0]]
......@@ -2655,7 +2721,7 @@ exit 1
self.checkRuleFromIpSource(ip, source_ip, rules_list)
def test_partition_firewall_ipsource_reject(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
self.setFirewallConfig()
source_ip = '10.0.8.10'
......@@ -2684,7 +2750,7 @@ exit 1
self.checkRuleFromIpSourceReject(ip, source_ip.split(' '), rules_list)
def test_partition_firewall_ip_change(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
self.setFirewallConfig()
source_ip = ['10.0.8.10', '10.0.8.11']
self.grid.firewall_conf['authorized_sources'] = [source_ip[0]]
......@@ -2717,7 +2783,6 @@ exit 1
self.grid.firewall_conf['firewall_cmd'] = self.firewall_cmd_remove
self.grid.firewall_conf['authorized_sources'] = []
computer.ip_address_list.append(('route_interface1', '10.10.8.4'))
self.grid.computer._synced = False
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.ip_address_list = computer.ip_address_list
......@@ -2728,7 +2793,7 @@ exit 1
class TestSlapgridCPWithTransaction(MasterMixin, unittest.TestCase):
def test_one_partition(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
partition = os.path.join(self.instance_root, '0')
......@@ -2768,7 +2833,7 @@ exit 0
count += 1
def test_partition_destroy_with_pre_remove_service(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
partition = computer.instance_list[0]
pre_delete_dir = os.path.join(partition.partition_path, 'etc/prerm')
......@@ -2786,13 +2851,13 @@ exit 0
'etc', 'software_release', 'worked', '.slapos-retention-lock-delay'])
self.assertEqual(computer.sequence,
['/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/startedComputerPartition'])
self.assertEqual(partition.state, 'started')
manager_list = slapmanager.from_config({'manager_list': 'prerm'})
self.grid._manager_list = manager_list
partition.requested_state = 'destroyed'
self.grid.computer._synced = False
self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS)
# Assert partition directory is not destroyed (pre-delete is running)
self.assertInstanceDirectoryListEqual(['0'])
......@@ -2807,14 +2872,13 @@ exit 0
# wait until the pre-delete script is finished
self._wait_prerm_script_finished(partition.partition_path)
self.grid.computer._synced = False
self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS)
# Assert partition directory is empty
self.assertInstanceDirectoryListEqual(['0'])
six.assertCountEqual(self, os.listdir(partition.partition_path), [])
def test_partition_destroy_pre_remove_with_retention_lock(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
partition = computer.instance_list[0]
pre_delete_dir = os.path.join(partition.partition_path, 'etc/prerm')
......@@ -2838,7 +2902,6 @@ exit 0
self.grid._manager_list = manager_list
partition.requested_state = 'destroyed'
self.grid.computer._synced = False
self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS)
# Assert partition directory is not destroyed (retention-delay-lock)
six.assertCountEqual(self, os.listdir(partition.partition_path),
......@@ -2852,7 +2915,6 @@ exit 0
)))
time.sleep(1)
self.grid.computer._synced = False
self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS)
# Assert partition directory is not destroyed (pre-delete is running)
......@@ -2865,13 +2927,12 @@ exit 0
# wait until the pre-delete script is finished
self._wait_prerm_script_finished(partition.partition_path)
self.grid.computer._synced = False
self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS)
# Assert partition directory is empty
six.assertCountEqual(self, os.listdir(partition.partition_path), [])
def test_partition_destroy_pre_remove_script_not_stopped(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
partition = computer.instance_list[0]
pre_delete_dir = os.path.join(partition.partition_path, 'etc/prerm')
......@@ -2887,7 +2948,6 @@ exit 0
self.grid._manager_list = manager_list
partition.requested_state = 'destroyed'
self.grid.computer._synced = False
self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS)
# Assert partition directory is not destroyed (pre-delete is running)
six.assertCountEqual(self, os.listdir(partition.partition_path),
......@@ -2901,14 +2961,13 @@ exit 0
# the script is well finished...
self.assertTrue("finished prerm script." in f.read())
self.grid.computer._synced = False
self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS)
# Assert partition directory is empty
self.assertInstanceDirectoryListEqual(['0'])
six.assertCountEqual(self, os.listdir(partition.partition_path), [])
def test_partition_destroy_pre_remove_script_run_as_partition_user(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
partition = computer.instance_list[0]
pre_delete_dir = os.path.join(partition.partition_path, 'etc/prerm')
......@@ -2924,7 +2983,6 @@ exit 0
self.grid._manager_list = manager_list
partition.requested_state = 'destroyed'
self.grid.computer._synced = False
self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS)
# Assert partition directory is not destroyed (pre-delete is running)
six.assertCountEqual(self, os.listdir(partition.partition_path),
......@@ -2955,7 +3013,6 @@ exit 0
# wait until the pre-delete script is finished
self._wait_prerm_script_finished(partition.partition_path)
self.grid.computer._synced = False
self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS)
# Assert partition directory is empty
self.assertInstanceDirectoryListEqual(['0'])
......@@ -2983,7 +3040,7 @@ class TestSlapgridNoFDLeak(MasterMixin, unittest.TestCase):
f.close()
def _test_no_fd_leak(self):
computer = ComputerForTest(self.software_root, self.instance_root, 1, 1)
computer = self.getTestComputerClass()(self.software_root, self.instance_root, 1, 1)
with httmock.HTTMock(computer.request_handler):
software = computer.software_list[0]
......@@ -3017,7 +3074,7 @@ class TestSlapgridWithPortRedirection(MasterMixin, unittest.TestCase):
manager_list = slapmanager.from_config({'manager_list': 'portredir'})
self.grid._manager_list = manager_list
self.computer = ComputerForTest(self.software_root, self.instance_root)
self.computer = self.getTestComputerClass()(self.software_root, self.instance_root)
self.partition = self.computer.instance_list[0]
self.instance_supervisord_config_path = os.path.join(
self.instance_root, 'etc/supervisord.conf.d/0.conf')
......@@ -3042,6 +3099,7 @@ class TestSlapgridWithPortRedirection(MasterMixin, unittest.TestCase):
self.assertEqual(self.computer.sequence,
['/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/startedComputerPartition'])
self.assertEqual(self.partition.state, 'started')
......@@ -3117,7 +3175,10 @@ class TestSlapgridWithPortRedirection(MasterMixin, unittest.TestCase):
self.assertEqual(self.computer.sequence,
['/getFullComputerInformation',
'/startedComputerPartition', '/startedComputerPartition'])
'/getComputerPartitionCertificate',
'/startedComputerPartition',
'/getComputerPartitionCertificate',
'/startedComputerPartition'])
self.assertEqual(self.partition.state, 'started')
# Check the socat command
......@@ -3241,7 +3302,7 @@ class TestSlapgridWithDevPermLsblk(MasterMixin, unittest.TestCase):
manager_list = slapmanager.from_config(self.config)
self.grid._manager_list = manager_list
self.computer = ComputerForTest(self.software_root, self.instance_root)
self.computer = self.getTestComputerClass()(self.software_root, self.instance_root)
self.partition = self.computer.instance_list[0]
self.instance_supervisord_config_path = os.path.join(
self.instance_root, 'etc/supervisord.conf.d/0.conf')
......@@ -3438,7 +3499,7 @@ class TestSlapgridWithDevPermManagerDevPermAllowLsblk(TestSlapgridWithDevPermLsb
class TestSlapgridWithWhitelistfirewall(MasterMixin, unittest.TestCase):
config = {
'manager_list': 'whitelistfirewall',
'firewall':{
'firewall': {
'firewall_cmd': 'firewall_cmd',
}
}
......@@ -3449,7 +3510,7 @@ class TestSlapgridWithWhitelistfirewall(MasterMixin, unittest.TestCase):
manager_list = slapmanager.from_config(self.config)
self.grid._manager_list = manager_list
self.computer = ComputerForTest(self.software_root, self.instance_root)
self.computer = self.getTestComputerClass()(self.software_root, self.instance_root)
self.partition = self.computer.instance_list[0]
self.whitelist_firewall_filename = os.path.join(
......@@ -3521,7 +3582,6 @@ class TestSlapgridWithWhitelistfirewall(MasterMixin, unittest.TestCase):
self.partition.requested_state = 'started'
self.partition.software.setBuildout(WRAPPER_CONTENT)
self.grid.computer._synced = False
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertEqual(
......@@ -3540,7 +3600,6 @@ class TestSlapgridWithWhitelistfirewall(MasterMixin, unittest.TestCase):
self.partition.requested_state = 'started'
self.partition.software.setBuildout(WRAPPER_CONTENT)
self.grid.computer._synced = False
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertEqual(
......@@ -3565,7 +3624,6 @@ class TestSlapgridWithWhitelistfirewall(MasterMixin, unittest.TestCase):
self.partition.requested_state = 'started'
self.partition.software.setBuildout(WRAPPER_CONTENT)
self.grid.computer._synced = False
self.assertEqual(self.grid.processComputerPartitionList(), slapgrid.SLAPGRID_SUCCESS)
self.assertEqual(
......@@ -3650,7 +3708,6 @@ class TestSlapgridWithWhitelistfirewall(MasterMixin, unittest.TestCase):
self.partition.requested_state = 'destroyed'
self.partition.software.setBuildout(WRAPPER_CONTENT)
self.grid.computer._synced = False
self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS)
self.assertEqual(
......@@ -3673,7 +3730,6 @@ class TestSlapgridWithWhitelistfirewall(MasterMixin, unittest.TestCase):
self.partition.requested_state = 'destroyed'
self.partition.software.setBuildout(WRAPPER_CONTENT)
self.grid.computer._synced = False
self.assertEqual(self.grid.agregateAndSendUsage(), slapgrid.SLAPGRID_SUCCESS)
self.assertEqual(
......@@ -3694,7 +3750,7 @@ class TestSlapgridManagerLifecycle(MasterMixin, unittest.TestCase):
self.manager_list = [self.manager]
self.setSlapgrid()
self.computer = ComputerForTest(self.software_root, self.instance_root)
self.computer = self.getTestComputerClass()(self.software_root, self.instance_root)
def _mock_requests(self):
return httmock.HTTMock(self.computer.request_handler)
......@@ -3709,6 +3765,7 @@ class TestSlapgridManagerLifecycle(MasterMixin, unittest.TestCase):
self.assertEqual(self.computer.sequence,
['/getFullComputerInformation',
'/getComputerPartitionCertificate',
'/startedComputerPartition'])
self.assertEqual(partition.state, 'started')
......@@ -3762,7 +3819,7 @@ class TestSlapgridPromiseWithMaster(MasterMixin, unittest.TestCase):
fake_waiting_time = 0.05
def test_one_failing_promise(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -3777,7 +3834,7 @@ class TestSlapgridPromiseWithMaster(MasterMixin, unittest.TestCase):
self.assertTrue(os.path.isfile(worked_file))
def test_one_failing_plugin_promise(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -3795,7 +3852,7 @@ class TestSlapgridPromiseWithMaster(MasterMixin, unittest.TestCase):
self.assertEqual('failed', result["result"]["message"])
def test_one_succeeding_promise(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -3809,7 +3866,7 @@ class TestSlapgridPromiseWithMaster(MasterMixin, unittest.TestCase):
self.assertTrue(os.path.isfile(worked_file))
def test_one_succeeding_plugin_promise(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -3829,7 +3886,7 @@ class TestSlapgridPromiseWithMaster(MasterMixin, unittest.TestCase):
result["result"]["message"])
def test_stderr_has_been_sent(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -3850,7 +3907,7 @@ class TestSlapgridPromiseWithMaster(MasterMixin, unittest.TestCase):
self.assertTrue(os.path.isfile(worked_file))
def test_stderr_has_been_sent_plugin(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -3869,7 +3926,7 @@ class TestSlapgridPromiseWithMaster(MasterMixin, unittest.TestCase):
self.assertEqual('FAILED 254554802', result["result"]["message"])
def test_timeout_works(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
......@@ -3891,7 +3948,7 @@ class TestSlapgridPromiseWithMaster(MasterMixin, unittest.TestCase):
self.assertTrue(os.path.isfile(worked_file))
def test_timeout_works_plugin(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -3912,7 +3969,7 @@ class TestSlapgridPromiseWithMaster(MasterMixin, unittest.TestCase):
result["result"]["message"])
def test_two_succeeding_promises(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -3931,7 +3988,7 @@ class TestSlapgridPromiseWithMaster(MasterMixin, unittest.TestCase):
self.assertTrue(os.path.isfile(worked_file))
def test_two_succeeding_plugin_promise(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -3968,7 +4025,7 @@ class TestSlapgridPromiseWithMaster(MasterMixin, unittest.TestCase):
def test_one_succeeding_one_failing_promises(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -3994,7 +4051,7 @@ class TestSlapgridPromiseWithMaster(MasterMixin, unittest.TestCase):
slapos.grid.slapgrid.SLAPGRID_PROMISE_FAIL)
def test_one_succeeding_one_failing_promises_plugin(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -4026,11 +4083,8 @@ class TestSlapgridPromiseWithMaster(MasterMixin, unittest.TestCase):
self.assertEqual('success', result["result"]["message"])
def test_one_succeeding_one_timing_out_promises(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -4056,7 +4110,7 @@ class TestSlapgridPromiseWithMaster(MasterMixin, unittest.TestCase):
slapos.grid.slapgrid.SLAPGRID_PROMISE_FAIL)
def test_one_succeeding_one_failing_promises_plugin(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'started'
......@@ -4091,7 +4145,7 @@ class TestSlapgridPromiseWithMaster(MasterMixin, unittest.TestCase):
result["result"]["message"])
def test_promise_notrun_if_partition_stopped(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'stopped'
......@@ -4106,7 +4160,7 @@ class TestSlapgridPromiseWithMaster(MasterMixin, unittest.TestCase):
self.assertFalse(os.path.exists(promise_file))
def test_promise_notrun_if_partition_stopped_plugin(self):
computer = ComputerForTest(self.software_root, self.instance_root)
computer = self.getTestComputerClass()(self.software_root, self.instance_root)
with httmock.HTTMock(computer.request_handler):
instance = computer.instance_list[0]
instance.requested_state = 'stopped'
......@@ -4122,6 +4176,156 @@ class TestSlapgridPromiseWithMaster(MasterMixin, unittest.TestCase):
".slapgrid/promise/result/fail.status.json")))
class TestSlapgridPluginPromiseWithInstancePython(TestSlapgridPromiseWithMaster):
expect_plugin = False
def setMock(self):
# unlike BasicMixin.setMock, we don't want to patch
# slapos.grid.SlapObject.getPythonExecutableFromSoftwarePath
pass
def setPython(self):
self.python_called = os.path.join(self.software_root, 'called')
wrapper = """#!/bin/sh
touch %s
exec %s "$@"
""" % (self.python_called, sys.executable)
path = os.path.join(self.software_root, 'python')
with open(path, 'w') as f:
f.write(wrapper)
os.chmod(path, 0o755)
return path
def getTestComputerClass(self):
# use a test computer class modified to use a different python, that
# will leave a `self.python_called` file when it's called so that we
# can assert that our custom python was executed, and not the slapos.core
# running python.
test_self = self
class TestComputerWithBuildout(
super(TestSlapgridPluginPromiseWithInstancePython,
self).getTestComputerClass()):
def getTestSoftwareClass(self):
class SoftwareForTestWithBuildout(
super(TestComputerWithBuildout, self).getTestSoftwareClass()):
def setBuildout(self, buildout=None):
buildout = '#!' + test_self.setPython()
return super(SoftwareForTestWithBuildout,
self).setBuildout(buildout)
return SoftwareForTestWithBuildout
def getTestInstanceClass(self):
class InstanceForTestWithBuildout(
super(TestComputerWithBuildout, self).getTestInstanceClass()):
def setPluginPromise(self, *args, **kwargs):
test_self.expect_plugin = self.requested_state == 'started'
return super(InstanceForTestWithBuildout,
self).setPluginPromise(*args, **kwargs)
return InstanceForTestWithBuildout
return TestComputerWithBuildout
def tearDown(self):
try:
os.remove(self.python_called)
called = True
except OSError as e:
if e.errno != errno.ENOENT:
raise
called = False
finally:
super(TestSlapgridPluginPromiseWithInstancePython, self).tearDown()
self.assertEqual(self.expect_plugin, called)
def test_failed_promise_output(self):
computer = self.getTestComputerClass()(self.software_root, self.instance_root, 1, 1)
instance, = computer.instance_list
instance.requested_state = 'started'
instance.setPluginPromise(
"failing_promise_plugin.py",
promise_content="""if 1:
return self.logger.error("héhé fake promise plugin error")
""",
)
with httmock.HTTMock(computer.request_handler), \
patch.object(self.grid.logger, 'info',) as dummyLogger:
self.launchSlapgrid()
self.assertEqual(
dummyLogger.mock_calls[-1][1][0] % dummyLogger.mock_calls[-1][1][1:],
" 0[(not ready)]: Promise 'failing_promise_plugin.py' failed with output: héhé fake promise plugin error")
def test_succeeding_promise_logs_output(self):
computer = self.getTestComputerClass()(self.software_root, self.instance_root, 1, 1)
instance, = computer.instance_list
name = "succeeding_promise_plugin.py"
output = "hehe fake promise plugin succeded !"
instance.requested_state = 'started'
instance.setPluginPromise(
name,
promise_content="""if 1:
return self.logger.info(%r)
""" % output,
)
with httmock.HTTMock(computer.request_handler), \
patch.object(self.grid.logger, 'info',) as dummyLogger:
self.launchSlapgrid()
self.assertIn(
"Checking promise %s..." % name,
dummyLogger.mock_calls[-4][1][0] % dummyLogger.mock_calls[-4][1][1:])
self.assertIn(
output,
dummyLogger.mock_calls[-3][1][0] % dummyLogger.mock_calls[-3][1][1:])
class TestSlapgridPluginPromiseWithInstancePythonOldSlapOSCompatibility(
TestSlapgridPluginPromiseWithInstancePython):
"""Process instance plugins with a different python, but simulate the case
where plugin scripts structure had one extra import
"""
def getTestComputerClass(self):
# use a test computer that will use a custom python (because we reuse
# TestSlapgridPluginPromiseWithInstancePython) and some promise plugins
# scripts that look like the one slapos.cookbook was creating before 1.0.118
class TestComputer(
super(TestSlapgridPluginPromiseWithInstancePythonOldSlapOSCompatibility,
self).getTestComputerClass()):
def getTestInstanceClass(self):
class TestInstance(super(TestComputer, self).getTestInstanceClass()):
def setPluginPromise(self, *args, **kwargs):
plugin_promise = super(TestInstance,
self).setPluginPromise(*args, **kwargs)
with open(plugin_promise) as f:
plugin_code = f.read()
legacy_plugin_code = plugin_code.replace(
textwrap.dedent('''\
# coding: utf-8
import sys
'''),
textwrap.dedent('''\
# coding: utf-8
import json
import sys
'''))
assert legacy_plugin_code != plugin_code # make sure our replace matched
with open(plugin_promise, 'w') as f:
f.write(legacy_plugin_code)
return plugin_promise
return TestInstance
return TestComputer
class TestSVCBackend(unittest.TestCase):
"""Tests for supervisor backend.
"""
......
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