test/unittest_task.py
author Julien Cristau <julien.cristau@logilab.fr>
Mon, 02 Feb 2015 15:35:06 +0100
changeset 1788 8c8c6baadf93
parent 1677 998cd9f5cbed
child 1810 2081821e6924
permissions -rw-r--r--
[pkg] 3.2.1

#!/usr/bin/python

import shutil
import tarfile
import sys
import os
from os.path import exists, join, abspath

from logilab.common.testlib import TestCase, unittest_main, mock_object, within_tempdir

# import this first will set import machinery on
import cubicweb.devtools
from cubes.apycot.testutils import MockTestWriter, MockRepository, MockVCSFile

from apycotlib import SetupException
from apycotlib import SUCCESS, FAILURE, PARTIAL, SKIPPED
from apycotlib.atest import Test as BaseTest

from unittest_checkers import input_path
# manage temporary repo
def setUpModule():
    os.environ['APYCOT_ROOT'] = ''
    mockvcsfile = MockVCSFile('subversion', path='/home/cvs')
    global MOCKREPO, BADREPO, TPP
    MOCKREPO = MockRepository(repository=mockvcsfile,
                              path='soft/goodpkg',
                              command='cp -R %s .' % input_path('goodpkg'))
    BADREPO = MockRepository(repository=mockvcsfile,
                             path='soft/goodpkg', command='false')
    TPP = TouchTestPreprocessor()


def tearDownModule():
    del os.environ['APYCOT_ROOT']
    for repo in ('badpkg2', 'goodpkg'):
        path = input_path(repo)
        if exists(path):
            shutil.rmtree(path)

def Test(tconfig, writer, preprocessors=None, checkers=None,
         repo=None, environment=None):
    pps = preprocessors
    repo = repo or MOCKREPO
    environment = environment or Environment(eid=tconfig['name'], apycot_preprocessors={})
    texec = dict(configuration=tconfig, environment=environment,
                 branch=environment['apycot_configuration'].get('branch'),
                 options='')
    test = BaseTest(texec, writer)
    if pps is not None:
        test.apycot_preprocessors = lambda x: pps
    if checkers is not None:
        test.checkers = checkers
    if repo is not None:
        test._repositories[environment['eid']] = repo
    return test

class TestConfig(dict):
    def __init__(self, name, dependencies=(), environ=None, conf=None):
        super(TestConfig, self).__init__()
        self['name'] = self['eid'] = name
        self['apycot_process_environment'] = environ or {'ZIGUOUIGOUI': 'YOOOO'}


class Environment(dict):
    def __init__(self, eid, apycot_preprocessors={},
                 repository='default',
                 conf=None):
        if repository is 'default':
            repository = dict(type='mercurial', source_url='http://bob.org/hg/toto/', path='')
        super(Environment, self).__init__(
                eid=eid, name='', vcs_path='',
                apycot_configuration=conf or {},
                apycot_process_environment={},
                repository=repository)

    def dc_title(self):
        return self.name

# mock objects ################################################################

class CleanRaisePreprocessor:
    id = 'clean_raise_preprocessor'
    def match(self, name):
        return 1

    def run(self, test, path=None):
        if path is None:
            return 1
        else:
            return 0

class SetupRaisePreprocessor:
    id = 'setup_raise_preprocessor'
    def match(self, name):
        return 1

    def run(self, test, path=None):
        if path is None:
            raise SetupException('in test_preprocessor.test_setup')
        else:
            raise SetupException('%s failed on %r' % (self.id, path))

class TouchTestPreprocessor:
    id = 'touch_preprocessor'
    file = None
    file2 = None

    def run(self, test, path=None):
        self.file = join(test.tmpdir, 'TestTC_pp')
        self.file2 = join(test.tmpdir, 'TestTC2_pp')
        f = open(self.file, 'w')
        f.close()
        f = open(self.file2, 'w')
        f.close()

class SimplePreprocessor(object):

    id = 'simple_preprocessor'
    def __init__(self):
        self.processed    = {}

    def run(self, test, path=None):
        if path == None:
            path = test.project_path()
        self.processed.setdefault(path, 0)
        self.processed[path] += 1

class DummyTest(object):
    need_preprocessor = None

    def check(self, test, writer):
        return SUCCESS
    def check_options(self):
        pass

class SuccessTestChecker(DummyTest):
    id = 'success_test_checker'
    options = {}
    need_preprocessor = 'install'
    def check(self, test, writer):
        return SUCCESS

class FailureTestChecker(DummyTest):
    id = 'failure_test_checker'
    options = {}
    def check(self, test, writer):
        return FAILURE

class ErrorTestChecker(DummyTest):
    id = 'error_test_checker'
    options = {}
    def check(self, test, writer):
        raise Exception('never succeed!')


# real tests ##################################################################

class TestTC(TestCase):

    def test_branch(self):
        test = Test(TestConfig('yo'),
                    MockTestWriter(),
                    environment=Environment('babar', conf={'branch': 'bob'}),
                    checkers=[SuccessTestChecker()])
        del test._repositories['babar'] # XXX clean up this mess
        repo = test.apycot_repository()
        self.assertEqual(repo.branch, 'bob')

    def test_branch_deps_with_branch(self):
        dep = Environment('babar', conf={'branch': 'Onk'})
        test = Test(TestConfig('yo', dependencies=(dep, )),
                    MockTestWriter(),
                    checkers=[SuccessTestChecker()])
        repo = test.apycot_repository(dep)
        self.assertEqual(repo.branch, 'Onk')

    def test_branch_deps_without_branch(self):
        dep = Environment('babar')
        test = Test(TestConfig('yo', dependencies=(dep, )),
                    MockTestWriter(),
                    checkers=[SuccessTestChecker()])
        repo = test.apycot_repository(dep)
        # default should be the branch name (as none is defined)
        self.assertEqual(repo.branch, 'default')

    def test_missing_repo(self):
        dep = Environment('babar', repository=None)
        test = Test(TestConfig('yo', dependencies=(dep,)),
                    MockTestWriter(), {},
                    checkers=[SuccessTestChecker()])
        self.assertRaises(Exception, test.apycot_repository, dep)


class EnvironmentTrackerMixinTC(TestCase):

    def setUp(self):
        self._PYTHONPATH = os.environ.get('PYTHONPATH', '')
        os.environ['PYTHONPATH'] = ''
        self.tracker = Test(TestConfig('yo', dependencies=(Environment('pypasax'),)),
                            MockTestWriter())

    def tearDown(self):
        os.environ['PYTHONPATH'] = self._PYTHONPATH

    def test_update_clean_env(self):
        lc_all = os.environ.get('LC_ALL')
        self.tracker.update_env('key', 'LC_ALL', 'XXXX')
        self.assertEqual(os.environ['LC_ALL'], 'XXXX')
        self.tracker.clean_env('key', 'LC_ALL')
        self.assertEqual(os.environ.get('LC_ALL'), lc_all)

        self.tracker.update_env('key', '__ENVIRONMENTTRACKERMIXINTC__', 'XXXX')
        self.assertEqual(os.environ['__ENVIRONMENTTRACKERMIXINTC__'], 'XXXX')
        self.tracker.clean_env('key', '__ENVIRONMENTTRACKERMIXINTC__')
        self.assertRaises(KeyError, os.environ.__getitem__,
                          '__ENVIRONMENTTRACKERMIXINTC__')

    def test_nested(self):
        lc_all = os.environ.get('LC_ALL')
        self.tracker.update_env('key', 'LC_ALL', 'XXXX')
        self.assertEqual(os.environ['LC_ALL'], 'XXXX')
        self.tracker.update_env('key2', 'LC_ALL', 'YYYY')
        self.assertEqual(os.environ['LC_ALL'], 'YYYY')
        self.tracker.clean_env('key2', 'LC_ALL')
        self.assertEqual(os.environ['LC_ALL'], 'XXXX')
        self.tracker.clean_env('key', 'LC_ALL')
        self.assertEqual(os.environ.get('LC_ALL'), lc_all)

    def test_update_clean_env_sep(self):
        path = os.environ['PATH']
        self.tracker.update_env('key', 'PATH', '/mybin', ':')
        self.assertEqual(os.environ['PATH'], '/mybin:' + path)
        self.tracker.clean_env('key', 'PATH')
        self.assertEqual(os.environ['PATH'], path)

    def test_nested_sep(self):
        path = os.environ['PATH']
        self.tracker.update_env('key', 'PATH', '/mybin', ':')
        if path:
            self.assertEqual(os.environ['PATH'], '/mybin:' + path)
        else:
            self.assertEqual(os.environ['PATH'], '/mybin')
        self.tracker.update_env('key2', 'PATH', '/myotherbin', ':')
        if path:
            self.assertEqual(os.environ['PATH'], '/myotherbin:/mybin:' + path)
        else:
            self.assertEqual(os.environ['PATH'], '/myotherbin:/mybin')
        self.tracker.clean_env('key2', 'PATH')
        if path:
            self.assertEqual(os.environ['PATH'], '/mybin:' + path)
        else:
            self.assertEqual(os.environ['PATH'], '/mybin')
        self.tracker.clean_env('key', 'PATH')
        self.assertEqual(os.environ['PATH'], path)

    def test_python_path_sync(self):
        self.tracker.update_env('key', 'PYTHONPATH', '/mylib', ':')
        self.assertEqual(os.environ['PYTHONPATH'], '/mylib')
        self.assertEqual(sys.path[0], '/mylib')
        self.tracker.update_env('key2', 'PYTHONPATH', '/otherlib', ':')
        self.assertEqual(os.environ['PYTHONPATH'], '/otherlib:/mylib')
        self.assertEqual(sys.path[0], '/otherlib')
        self.tracker.clean_env('key2', 'PYTHONPATH')
        self.assertEqual(os.environ['PYTHONPATH'], '/mylib')
        self.assertNotEqual(sys.path[0], '/otherlib')
        self.tracker.clean_env('key', 'PYTHONPATH')
        self.assertEqual(os.environ['PYTHONPATH'], '')
        self.assertNotEqual(sys.path[0], '/otherlib')

    def test_update_undefined_env(self):

        var = 'XNZOUACONFVESUHFJGSLKJ'
        while os.environ.get(var) is not None:
            var = ''.join(chr(randint(ord('A'), ord('Z') +1))
                for cnt in xrange(randint(10, 20)))

        self.tracker.update_env('key', var, 'to be or not to be', ':')
        self.assertMultiLineEqual(os.environ.get(var),  'to be or not to be')
        self.tracker.clean_env('key', var)
        self.assertEqual(os.environ.get(var), None)



if __name__ == '__main__':
    unittest_main()