salt/tests/unit/modules/zcbuildout_test.py
2015-02-04 21:11:17 -07:00

518 lines
19 KiB
Python

# -*- coding: utf-8 -*-
# Import python libs
from __future__ import absolute_import
import os
import tempfile
import logging
import shutil
# Import 3rd-party libs
# pylint: disable=import-error,no-name-in-module,redefined-builtin
import salt.ext.six as six
from salt.ext.six.moves.urllib.error import URLError
from salt.ext.six.moves.urllib.request import urlopen
# pylint: enable=import-error,no-name-in-module,redefined-builtin
# Import Salt Testing libs
from salttesting import TestCase, skipIf
from salttesting.helpers import (
ensure_in_syspath,
requires_network,
skip_if_binaries_missing
)
ensure_in_syspath('../..')
# Import Salt libs
import integration # pylint: disable=import-error
import salt.utils
from salt.modules import zcbuildout as buildout
from salt.modules import cmdmod as cmd
ROOT = os.path.join(integration.FILES, 'file', 'base', 'buildout')
KNOWN_VIRTUALENV_BINARY_NAMES = (
'virtualenv',
'virtualenv2',
'virtualenv-2.6',
'virtualenv-2.7'
)
buildout.__salt__ = {
'cmd.run_all': cmd.run_all,
'cmd.run': cmd.run,
'cmd.retcode': cmd.retcode,
}
BOOT_INIT = {
1: [
'var/ver/1/bootstrap/bootstrap.py',
],
2: [
'var/ver/2/bootstrap/bootstrap.py',
'b/bootstrap.py',
]}
log = logging.getLogger(__name__)
def download_to(url, dest):
with salt.utils.fopen(dest, 'w') as fic:
fic.write(urlopen(url, timeout=10).read())
@skipIf(True, 'These tests are not running reliably')
class Base(TestCase):
@classmethod
def setUpClass(cls):
if not os.path.isdir(integration.TMP):
os.makedirs(integration.TMP)
cls.rdir = tempfile.mkdtemp(dir=integration.TMP)
cls.tdir = os.path.join(cls.rdir, 'test')
for idx, url in six.iteritems(buildout._URL_VERSIONS):
log.debug('Downloading bootstrap from {0}'.format(url))
dest = os.path.join(
cls.rdir, '{0}_bootstrap.py'.format(idx)
)
try:
download_to(url, dest)
except URLError:
log.debug('Failed to download {0}'.format(url))
# creating a new setuptools install
cls.ppy_st = os.path.join(cls.rdir, 'psetuptools')
cls.py_st = os.path.join(cls.ppy_st, 'bin', 'python')
ret1 = buildout._Popen((
'{0} --no-site-packages {1};'
'{1}/bin/pip install -U setuptools; '
'{1}/bin/easy_install -U distribute;').format(
salt.utils.which_bin(KNOWN_VIRTUALENV_BINARY_NAMES),
cls.ppy_st
)
)
assert ret1['retcode'] == 0
@classmethod
def tearDownClass(cls):
if os.path.isdir(cls.rdir):
shutil.rmtree(cls.rdir)
def setUp(self):
super(Base, self).setUp()
self._remove_dir()
shutil.copytree(ROOT, self.tdir)
for idx in BOOT_INIT:
path = os.path.join(
self.rdir, '{0}_bootstrap.py'.format(idx)
)
for fname in BOOT_INIT[idx]:
shutil.copy2(path, os.path.join(self.tdir, fname))
def tearDown(self):
super(Base, self).tearDown()
self._remove_dir()
def _remove_dir(self):
if os.path.isdir(self.tdir):
shutil.rmtree(self.tdir)
@skipIf(True, 'These tests are not running reliably')
@skipIf(salt.utils.which_bin(KNOWN_VIRTUALENV_BINARY_NAMES) is None,
'The \'virtualenv\' packaged needs to be installed')
@skip_if_binaries_missing(['tar'])
class BuildoutTestCase(Base):
@requires_network()
def test_onlyif_unless(self):
b_dir = os.path.join(self.tdir, 'b')
ret = buildout.buildout(b_dir, onlyif='/bin/false')
self.assertTrue(ret['comment'] == 'onlyif execution failed')
self.assertTrue(ret['status'] is True)
ret = buildout.buildout(b_dir, unless='/bin/true')
self.assertTrue(ret['comment'] == 'unless execution succeeded')
self.assertTrue(ret['status'] is True)
@requires_network()
def test_salt_callback(self):
@buildout._salt_callback
def callback1(a, b=1):
for i in buildout.LOG.levels:
getattr(buildout.LOG, i)('{0}bar'.format(i[0]))
return 'foo'
def callback2(a, b=1):
raise Exception('foo')
# pylint: disable=invalid-sequence-index
ret1 = callback1(1, b=3)
# These lines are throwing pylint errors - disabling for now since we are skipping
# these tests
#self.assertEqual(ret1['status'], True)
#self.assertEqual(ret1['logs_by_level']['warn'], ['wbar'])
#self.assertEqual(ret1['comment'], '')
# These lines are throwing pylint errors - disabling for now since we are skipping
# these tests
#self.assertTrue(
# u''
# u'OUTPUT:\n'
# u'foo\n'
# u''
#in ret1['outlog']
#)
# These lines are throwing pylint errors - disabling for now since we are skipping
# these tests
#self.assertTrue(u'Log summary:\n' in ret1['outlog'])
# These lines are throwing pylint errors - disabling for now since we are skipping
# these tests
# self.assertTrue(
# u'INFO: ibar\n'
# u'WARN: wbar\n'
# u'DEBUG: dbar\n'
# u'ERROR: ebar\n'
#in ret1['outlog']
#)
# These lines are throwing pylint errors - disabling for now since we are skipping
# these tests
#self.assertTrue('by level' in ret1['outlog_by_level'])
#self.assertEqual(ret1['out'], 'foo')
ret2 = buildout._salt_callback(callback2)(2, b=6)
self.assertEqual(ret2['status'], False)
self.assertTrue(
ret2['logs_by_level']['error'][0].startswith('Traceback'))
self.assertTrue(
'We did not get any '
'expectable answer '
'from buildout' in ret2['comment'])
self.assertEqual(ret2['out'], None)
for l in buildout.LOG.levels:
self.assertTrue(0 == len(buildout.LOG.by_level[l]))
# pylint: enable=invalid-sequence-index
@requires_network()
def test_get_bootstrap_url(self):
for path in [os.path.join(self.tdir, 'var/ver/1/dumppicked'),
os.path.join(self.tdir, 'var/ver/1/bootstrap'),
os.path.join(self.tdir, 'var/ver/1/versions')]:
self.assertEqual(buildout._URL_VERSIONS[1],
buildout._get_bootstrap_url(path),
"b1 url for {0}".format(path))
for path in [
os.path.join(self.tdir, '/non/existing'),
os.path.join(self.tdir, 'var/ver/2/versions'),
os.path.join(self.tdir, 'var/ver/2/bootstrap'),
os.path.join(self.tdir, 'var/ver/2/default'),
]:
self.assertEqual(buildout._URL_VERSIONS[2],
buildout._get_bootstrap_url(path),
"b2 url for {0}".format(path))
@requires_network()
def test_get_buildout_ver(self):
for path in [os.path.join(self.tdir, 'var/ver/1/dumppicked'),
os.path.join(self.tdir, 'var/ver/1/bootstrap'),
os.path.join(self.tdir, 'var/ver/1/versions')]:
self.assertEqual(1,
buildout._get_buildout_ver(path),
"1 for {0}".format(path))
for path in [os.path.join(self.tdir, '/non/existing'),
os.path.join(self.tdir, 'var/ver/2/versions'),
os.path.join(self.tdir, 'var/ver/2/bootstrap'),
os.path.join(self.tdir, 'var/ver/2/default')]:
self.assertEqual(2,
buildout._get_buildout_ver(path),
"2 for {0}".format(path))
@requires_network()
def test_get_bootstrap_content(self):
self.assertEqual(
'',
buildout._get_bootstrap_content(
os.path.join(self.tdir, '/non/existing'))
)
self.assertEqual(
'',
buildout._get_bootstrap_content(
os.path.join(self.tdir, 'var/tb/1')))
self.assertEqual(
'foo\n',
buildout._get_bootstrap_content(
os.path.join(self.tdir, 'var/tb/2')))
@requires_network()
def test_logger_clean(self):
buildout.LOG.clear()
# nothing in there
self.assertTrue(
True not in
[len(buildout.LOG.by_level[a]) > 0
for a in buildout.LOG.by_level])
buildout.LOG.info('foo')
self.assertTrue(
True in
[len(buildout.LOG.by_level[a]) > 0
for a in buildout.LOG.by_level])
buildout.LOG.clear()
self.assertTrue(
True not in
[len(buildout.LOG.by_level[a]) > 0
for a in buildout.LOG.by_level])
@requires_network()
def test_logger_loggers(self):
buildout.LOG.clear()
# nothing in there
for i in buildout.LOG.levels:
getattr(buildout.LOG, i)('foo')
getattr(buildout.LOG, i)('bar')
getattr(buildout.LOG, i)('moo')
self.assertTrue(len(buildout.LOG.by_level[i]) == 3)
self.assertEqual(buildout.LOG.by_level[i][0], 'foo')
self.assertEqual(buildout.LOG.by_level[i][-1], 'moo')
@requires_network()
def test__find_cfgs(self):
result = sorted(
[a.replace(ROOT, '') for a in buildout._find_cfgs(ROOT)])
assertlist = sorted(
['/buildout.cfg',
'/c/buildout.cfg',
'/etc/buildout.cfg',
'/e/buildout.cfg',
'/b/buildout.cfg',
'/b/bdistribute/buildout.cfg',
'/b/b2/buildout.cfg',
'/foo/buildout.cfg'])
self.assertEqual(result, assertlist)
@requires_network()
def skip_test_upgrade_bootstrap(self):
b_dir = os.path.join(self.tdir, 'b')
bpy = os.path.join(b_dir, 'bootstrap.py')
buildout.upgrade_bootstrap(b_dir)
time1 = os.stat(bpy).st_mtime
with salt.utils.fopen(bpy) as fic:
data = fic.read()
self.assertTrue('setdefaulttimeout(2)' in data)
flag = os.path.join(b_dir, '.buildout', '2.updated_bootstrap')
self.assertTrue(os.path.exists(flag))
buildout.upgrade_bootstrap(b_dir, buildout_ver=1)
time2 = os.stat(bpy).st_mtime
with salt.utils.fopen(bpy) as fic:
data = fic.read()
self.assertTrue('setdefaulttimeout(2)' in data)
flag = os.path.join(b_dir, '.buildout', '1.updated_bootstrap')
self.assertTrue(os.path.exists(flag))
buildout.upgrade_bootstrap(b_dir, buildout_ver=1)
time3 = os.stat(bpy).st_mtime
self.assertNotEqual(time2, time1)
self.assertEqual(time2, time3)
@skipIf(salt.utils.which_bin(KNOWN_VIRTUALENV_BINARY_NAMES) is None,
'The \'virtualenv\' packaged needs to be installed')
@skipIf(True, 'These tests are not running reliably')
class BuildoutOnlineTestCase(Base):
@classmethod
def setUpClass(cls):
super(BuildoutOnlineTestCase, cls).setUpClass()
cls.ppy_dis = os.path.join(cls.rdir, 'pdistibute')
cls.ppy_blank = os.path.join(cls.rdir, 'pblank')
cls.py_dis = os.path.join(cls.ppy_dis, 'bin', 'python')
cls.py_blank = os.path.join(cls.ppy_blank, 'bin', 'python')
# creating a distribute based install
try:
ret20 = buildout._Popen((
'{0} --no-site-packages --no-setuptools --no-pip {1}'.format(
salt.utils.which_bin(KNOWN_VIRTUALENV_BINARY_NAMES),
cls.ppy_dis
)
))
except buildout._BuildoutError:
ret20 = buildout._Popen((
'{0} --no-site-packages {1}'.format(
salt.utils.which_bin(KNOWN_VIRTUALENV_BINARY_NAMES),
cls.ppy_dis
))
)
assert ret20['retcode'] == 0
download_to('https://pypi.python.org/packages/source'
'/d/distribute/distribute-0.6.43.tar.gz',
os.path.join(cls.ppy_dis, 'distribute-0.6.43.tar.gz'))
ret2 = buildout._Popen((
'cd {0} &&'
' tar xzvf distribute-0.6.43.tar.gz && cd distribute-0.6.43 &&'
' {0}/bin/python setup.py install'
).format(cls.ppy_dis))
assert ret2['retcode'] == 0
# creating a blank based install
try:
ret3 = buildout._Popen((
'{0} --no-site-packages --no-setuptools --no-pip {1}'.format(
salt.utils.which_bin(KNOWN_VIRTUALENV_BINARY_NAMES),
cls.ppy_blank
)
))
except buildout._BuildoutError:
ret3 = buildout._Popen((
'{0} --no-site-packages {1}'.format(
salt.utils.which_bin(KNOWN_VIRTUALENV_BINARY_NAMES),
cls.ppy_blank
)
))
assert ret3['retcode'] == 0
@requires_network()
def test_buildout_bootstrap(self):
b_dir = os.path.join(self.tdir, 'b')
bd_dir = os.path.join(self.tdir, 'b', 'bdistribute')
b2_dir = os.path.join(self.tdir, 'b', 'b2')
self.assertTrue(buildout._has_old_distribute(self.py_dis))
# this is too hard to check as on debian & other where old
# packages are present (virtualenv), we can't have
# a clean site-packages
# self.assertFalse(buildout._has_old_distribute(self.py_blank))
self.assertFalse(buildout._has_old_distribute(self.py_st))
self.assertFalse(buildout._has_setuptools7(self.py_dis))
self.assertTrue(buildout._has_setuptools7(self.py_st))
self.assertFalse(buildout._has_setuptools7(self.py_blank))
ret = buildout.bootstrap(
bd_dir, buildout_ver=1, python=self.py_dis)
comment = ret['outlog']
self.assertTrue('--distribute' in comment)
self.assertTrue('Generated script' in comment)
ret = buildout.bootstrap(b_dir, buildout_ver=1, python=self.py_blank)
comment = ret['outlog']
# as we may have old packages, this test the two
# behaviors (failure with old setuptools/distribute)
self.assertTrue(
('Got ' in comment
and 'Generated script' in comment)
or ('setuptools>=0.7' in comment)
)
ret = buildout.bootstrap(b_dir, buildout_ver=2, python=self.py_blank)
comment = ret['outlog']
self.assertTrue(
('setuptools' in comment
and 'Generated script' in comment)
or ('setuptools>=0.7' in comment)
)
ret = buildout.bootstrap(b_dir, buildout_ver=2, python=self.py_st)
comment = ret['outlog']
self.assertTrue(
('setuptools' in comment
and 'Generated script' in comment)
or ('setuptools>=0.7' in comment)
)
ret = buildout.bootstrap(b2_dir, buildout_ver=2, python=self.py_st)
comment = ret['outlog']
self.assertTrue(
('setuptools' in comment
and 'Creating directory' in comment)
or ('setuptools>=0.7' in comment)
)
@requires_network()
def test_run_buildout(self):
b_dir = os.path.join(self.tdir, 'b')
ret = buildout.bootstrap(b_dir, buildout_ver=2, python=self.py_st)
self.assertTrue(ret['status'])
ret = buildout.run_buildout(b_dir,
parts=['a', 'b'])
out = ret['out']
self.assertTrue('Installing a' in out)
self.assertTrue('Installing b' in out)
@requires_network()
def test_buildout(self):
b_dir = os.path.join(self.tdir, 'b')
ret = buildout.buildout(b_dir, buildout_ver=2, python=self.py_st)
self.assertTrue(ret['status'])
out = ret['out']
comment = ret['comment']
self.assertTrue(ret['status'])
self.assertTrue('Creating directory' in out)
self.assertTrue('Installing a.' in out)
self.assertTrue('psetuptools/bin/python bootstrap.py' in comment)
self.assertTrue('buildout -c buildout.cfg' in comment)
ret = buildout.buildout(b_dir,
parts=['a', 'b', 'c'],
buildout_ver=2,
python=self.py_st)
outlog = ret['outlog']
out = ret['out']
comment = ret['comment']
self.assertTrue('Installing single part: a' in outlog)
self.assertTrue('buildout -c buildout.cfg -N install a' in comment)
self.assertTrue('Installing b.' in out)
self.assertTrue('Installing c.' in out)
ret = buildout.buildout(b_dir,
parts=['a', 'b', 'c'],
buildout_ver=2,
newest=True,
python=self.py_st)
outlog = ret['outlog']
out = ret['out']
comment = ret['comment']
self.assertTrue('buildout -c buildout.cfg -n install a' in comment)
@skipIf(True, 'These tests are not running reliably')
class BuildoutAPITestCase(TestCase):
def test_merge(self):
buildout.LOG.clear()
buildout.LOG.info('àé')
buildout.LOG.info(u'àé')
buildout.LOG.error('àé')
buildout.LOG.error(u'àé')
ret1 = buildout._set_status({}, out='éà')
uret1 = buildout._set_status({}, out=u'éà')
buildout.LOG.clear()
buildout.LOG.info('ççàé')
buildout.LOG.info(u'ççàé')
buildout.LOG.error('ççàé')
buildout.LOG.error(u'ççàé')
ret2 = buildout._set_status({}, out='çéà')
uret2 = buildout._set_status({}, out=u'çéà')
uretm = buildout._merge_statuses([ret1, uret1, ret2, uret2])
for ret in ret1, uret1, ret2, uret2:
out = ret['out']
if not isinstance(ret['out'], six.text_type):
out = ret['out'].decode('utf-8')
for out in ['àé', 'ççàé']:
self.assertTrue(out in uretm['logs_by_level']['info'])
self.assertTrue(out in uretm['outlog_by_level'])
def test_setup(self):
buildout.LOG.clear()
buildout.LOG.info('àé')
buildout.LOG.info(u'àé')
buildout.LOG.error('àé')
buildout.LOG.error(u'àé')
ret = buildout._set_status({}, out='éà')
uret = buildout._set_status({}, out=u'éà')
self.assertTrue(ret['outlog'] == uret['outlog'])
self.assertTrue('àé' in uret['outlog_by_level'])
if __name__ == '__main__':
from integration import run_tests # pylint: disable=import-error
run_tests(
BuildoutAPITestCase,
BuildoutTestCase,
BuildoutOnlineTestCase,
needs_daemon=False)