262 lines
11 KiB
Python
262 lines
11 KiB
Python
#!/usr/bin/env python
|
|
"""Module ci-scripts AppVeyor unit tests
|
|
"""
|
|
|
|
# SET=test00 in the environment (.appveyor.yml) runs the tests in this script
|
|
# all other jobs are started as compile jobs
|
|
|
|
from __future__ import print_function
|
|
|
|
import sys, os, shutil, fileinput
|
|
import distutils.util
|
|
import re
|
|
import unittest
|
|
|
|
builddir = os.getcwd()
|
|
|
|
def find_in_file(regex, filename):
|
|
file = open (filename, "r")
|
|
for line in file:
|
|
if re.search(regex, line):
|
|
return True
|
|
return False
|
|
|
|
def getStringIO():
|
|
if (sys.version_info > (3, 0)):
|
|
import io
|
|
return io.StringIO()
|
|
else:
|
|
import StringIO
|
|
return StringIO.StringIO()
|
|
|
|
sys.path.append('appveyor')
|
|
import do
|
|
|
|
# we're working with tags (detached heads) a lot: suppress advice
|
|
do.call_git(['config', '--global', 'advice.detachedHead', 'false'])
|
|
|
|
class TestSourceSet(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
os.environ['SETUP_PATH'] = '.:appveyor'
|
|
if 'BASE' in os.environ:
|
|
del os.environ['BASE']
|
|
do.clear_lists()
|
|
os.chdir(builddir)
|
|
|
|
def test_EmptySetupDirsPath(self):
|
|
del os.environ['SETUP_PATH']
|
|
self.assertRaisesRegexp(NameError, '\(SETUP_PATH\) is empty', do.source_set, 'test01')
|
|
|
|
def test_InvalidSetupName(self):
|
|
self.assertRaisesRegexp(NameError, 'does not exist in SETUP_PATH', do.source_set, 'xxdoesnotexistxx')
|
|
|
|
def test_ValidSetupName(self):
|
|
capturedOutput = getStringIO()
|
|
sys.stdout = capturedOutput
|
|
do.source_set('test01')
|
|
sys.stdout = sys.__stdout__
|
|
self.assertEqual(do.setup['BASE'], '7.0', 'BASE was not set to \'7.0\'')
|
|
|
|
def test_SetupDoesNotOverridePreset(self):
|
|
os.environ['BASE'] = 'foo'
|
|
capturedOutput = getStringIO()
|
|
sys.stdout = capturedOutput
|
|
do.source_set('test01')
|
|
sys.stdout = sys.__stdout__
|
|
self.assertEqual(do.setup['BASE'], 'foo',
|
|
'Preset BASE was overridden by test01 setup (expected \'foo\' got {0})'
|
|
.format(do.setup['BASE']))
|
|
|
|
def test_IncludeSetupFirstSetWins(self):
|
|
capturedOutput = getStringIO()
|
|
sys.stdout = capturedOutput
|
|
do.source_set('test02')
|
|
sys.stdout = sys.__stdout__
|
|
self.assertEqual(do.setup['BASE'], 'foo',
|
|
'BASE set in test02 was overridden by test01 setup (expected \'foo\' got {0})'
|
|
.format(do.setup['BASE']))
|
|
self.assertEqual(do.setup['FOO'], 'bar', 'Setting of single word does not work')
|
|
self.assertEqual(do.setup['FOO2'], 'bar bar2', 'Setting of multiple words does not work')
|
|
self.assertEqual(do.setup['FOO3'], 'bar bar2', 'Indented setting of multiple words does not work')
|
|
self.assertEqual(do.setup['SNCSEQ'], 'R2-2-7', 'Setup test01 was not included')
|
|
|
|
def test_DoubleIncludeGetsIgnored(self):
|
|
capturedOutput = getStringIO()
|
|
sys.stdout = capturedOutput
|
|
do.source_set('test03')
|
|
sys.stdout = sys.__stdout__
|
|
self.assertRegexpMatches(capturedOutput.getvalue(), 'Ignoring already included setup file')
|
|
|
|
class TestUpdateReleaseLocal(unittest.TestCase):
|
|
|
|
release_local = os.path.join(do.cachedir, 'RELEASE.local')
|
|
|
|
def setUp(self):
|
|
if os.path.exists(self.release_local):
|
|
os.remove(self.release_local)
|
|
os.chdir(builddir)
|
|
|
|
def test_SetModule(self):
|
|
do.update_release_local('MOD1', '/foo/bar')
|
|
found = 0
|
|
for line in fileinput.input(self.release_local, inplace=1):
|
|
if 'MOD1=' in line:
|
|
self.assertEqual(line.strip(), 'MOD1=/foo/bar', 'MOD1 not set correctly')
|
|
found += 1
|
|
fileinput.close()
|
|
self.assertEqual(found, 1, 'MOD1 not written once to RELEASE.local (found {0})'.format(found))
|
|
|
|
def test_SetBaseAndMultipleModules(self):
|
|
do.update_release_local('EPICS_BASE', '/bar/foo')
|
|
do.update_release_local('MOD1', '/foo/bar')
|
|
do.update_release_local('MOD2', '/foo/bar2')
|
|
do.update_release_local('MOD1', '/foo/bar1')
|
|
found = {}
|
|
foundat = {}
|
|
for line in fileinput.input(self.release_local, inplace=1):
|
|
if 'MOD1=' in line:
|
|
self.assertEqual(line.strip(), 'MOD1=/foo/bar1',
|
|
'MOD1 not set correctly (expected \'MOD1=/foo/bar1\' found \'{0}\')'
|
|
.format(line))
|
|
if 'mod1' in found:
|
|
found['mod1'] += 1
|
|
else:
|
|
found['mod1'] = 1
|
|
foundat['mod1'] = fileinput.filelineno()
|
|
if 'MOD2=' in line:
|
|
self.assertEqual(line.strip(), 'MOD2=/foo/bar2',
|
|
'MOD2 not set correctly (expected \'MOD2=/foo/bar2\' found \'{0}\')'
|
|
.format(line))
|
|
if 'mod2' in found:
|
|
found['mod2'] += 1
|
|
else:
|
|
found['mod2'] = 1
|
|
foundat['mod2'] = fileinput.filelineno()
|
|
if 'EPICS_BASE=' in line:
|
|
self.assertEqual(line.strip(), 'EPICS_BASE=/bar/foo',
|
|
'EPICS_BASE not set correctly (expected \'EPICS_BASE=/bar/foo\' found \'{0}\')'
|
|
.format(line))
|
|
if 'base' in found:
|
|
found['base'] += 1
|
|
else:
|
|
found['base'] = 1
|
|
foundat['base'] = fileinput.filelineno()
|
|
fileinput.close()
|
|
self.assertEqual(found['mod1'], 1,
|
|
'MOD1 does not appear once in RELEASE.local (found {0})'.format(found['mod1']))
|
|
self.assertEqual(found['mod2'], 1,
|
|
'MOD2 does not appear once in RELEASE.local (found {0})'.format(found['mod2']))
|
|
self.assertEqual(found['base'], 1,
|
|
'EPICS_BASE does not appear once in RELEASE.local (found {0})'.format(found['base']))
|
|
self.assertGreater(foundat['base'], foundat['mod2'],
|
|
'EPICS_BASE (line {0}) appears before MOD2 (line {1})'
|
|
.format(foundat['base'], foundat['mod2']))
|
|
self.assertGreater(foundat['mod2'], foundat['mod1'],
|
|
'MOD2 (line {0}) appears before MOD1 (line {1})'.format(foundat['mod2'], foundat['mod1']))
|
|
|
|
class TestAddDependency(unittest.TestCase):
|
|
|
|
hash_3_15_6 = "ce7943fb44beb22b453ddcc0bda5398fadf72096"
|
|
location = os.path.join(do.cachedir, 'base-R3.15.6')
|
|
licensefile = os.path.join(location, 'LICENSE')
|
|
checked_file = os.path.join(location, 'checked_out')
|
|
release_file = os.path.join(location, 'configure', 'RELEASE')
|
|
|
|
def setUp(self):
|
|
os.environ['SETUP_PATH'] = '.:appveyor'
|
|
if os.path.exists(self.location):
|
|
shutil.rmtree(self.location, onerror=do.remove_readonly)
|
|
do.clear_lists()
|
|
os.chdir(builddir)
|
|
do.source_set('defaults')
|
|
do.complete_setup('BASE')
|
|
|
|
def test_MissingDependency(self):
|
|
do.setup['BASE'] = 'R3.15.6'
|
|
do.add_dependency('BASE')
|
|
self.assertTrue(os.path.exists(self.licensefile), 'Missing dependency was not checked out')
|
|
self.assertTrue(os.path.exists(self.checked_file), 'Checked-out commit marker was not written')
|
|
with open(self.checked_file, 'r') as bfile:
|
|
checked_out = bfile.read().strip()
|
|
bfile.close()
|
|
self.assertEqual(checked_out, self.hash_3_15_6,
|
|
'Wrong commit of dependency checked out (expected=\"{0}\" found=\"{1}\")'
|
|
.format(self.hash_3_15_6, checked_out))
|
|
self.assertFalse(find_in_file('include \$\(TOP\)/../RELEASE.local', self.release_file),
|
|
'RELEASE in Base includes TOP/../RELEASE.local')
|
|
|
|
def test_UpToDateDependency(self):
|
|
do.setup['BASE'] = 'R3.15.6'
|
|
do.add_dependency('BASE')
|
|
os.remove(self.licensefile)
|
|
do.add_dependency('BASE')
|
|
self.assertFalse(os.path.exists(self.licensefile), 'Check out on top of existing up-to-date dependency')
|
|
|
|
def test_OutdatedDependency(self):
|
|
do.setup['BASE'] = 'R3.15.6'
|
|
do.add_dependency('BASE')
|
|
os.remove(self.licensefile)
|
|
with open(self.checked_file, "w") as fout:
|
|
print('XXX not the right hash XXX', file=fout)
|
|
fout.close()
|
|
do.add_dependency('BASE')
|
|
self.assertTrue(os.path.exists(self.licensefile), 'No check-out on top of out-of-date dependency')
|
|
with open(self.checked_file, 'r') as bfile:
|
|
checked_out = bfile.read().strip()
|
|
bfile.close()
|
|
self.assertEqual(checked_out, self.hash_3_15_6,
|
|
"Wrong commit of dependency checked out (expected='{0}' found='{1}')"
|
|
.format(self.hash_3_15_6, checked_out))
|
|
|
|
def repo_access(dep):
|
|
do.set_setup_from_env(dep)
|
|
do.setup.setdefault(dep + "_DIRNAME", dep.lower())
|
|
do.setup.setdefault(dep + "_REPONAME", dep.lower())
|
|
do.setup.setdefault('REPOOWNER', 'epics-modules')
|
|
do.setup.setdefault(dep + "_REPOOWNER", do.setup['REPOOWNER'])
|
|
do.setup.setdefault(dep + "_REPOURL", 'https://github.com/{0}/{1}.git'
|
|
.format(do.setup[dep + '_REPOOWNER'], do.setup[dep + '_REPONAME']))
|
|
with open(os.devnull, 'w') as devnull:
|
|
return do.call_git(['ls-remote', '--quiet', '--heads', do.setup[dep + '_REPOURL']],
|
|
stdout=devnull, stderr=devnull)
|
|
|
|
class TestDefaultModuleURLs(unittest.TestCase):
|
|
|
|
modules = ['BASE', 'PVDATA', 'PVACCESS', 'NTYPES',
|
|
'SNCSEQ', 'STREAM', 'ASYN', 'STD',
|
|
'CALC', 'AUTOSAVE', 'BUSY', 'SSCAN',
|
|
'IOCSTATS', 'MOTOR', 'IPAC', ]
|
|
|
|
def setUp(self):
|
|
os.environ['SETUP_PATH'] = '.:appveyor'
|
|
do.clear_lists()
|
|
os.chdir(builddir)
|
|
do.source_set('defaults')
|
|
|
|
def test_Repos(self):
|
|
for mod in self.modules:
|
|
self.assertEqual(repo_access(mod), 0, 'Defaults for {0} do not point to a valid git repository at {1}'
|
|
.format(mod, do.setup[mod + '_REPOURL']))
|
|
|
|
class TestVCVars(unittest.TestCase):
|
|
def test_vcvars(self):
|
|
if ('CC' in os.environ and os.environ['CC'] in ('mingw',)) \
|
|
or distutils.util.get_platform() != "win32":
|
|
raise unittest.SkipTest()
|
|
|
|
do.with_vcvars('env')
|
|
|
|
if __name__ == "__main__":
|
|
if 'SET' in os.environ and os.environ['SET'] == "test00":
|
|
do.host_info()
|
|
if sys.argv[1:]==['env']:
|
|
# testing with_vcvars
|
|
[print(K,'=',V) for K, V in os.environ.items()]
|
|
else:
|
|
unittest.main()
|
|
else:
|
|
do.actions['prepare']()
|
|
do.actions['build']()
|
|
do.actions['test']()
|