Commit a2c9191d authored by Mike Hommey's avatar Mike Hommey
Browse files

Bug 1257516 - Add a unit test for check_prog(). r=ted

At the same time, shell quote the result it prints if it needs to be.
parent e8721f03
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -48,7 +48,10 @@ def checking(what, callback=None):
# it can find. If PROG is already set from the environment or command line,
# use that value instead.
@template
@advanced
def check_prog(var, progs, allow_missing=False):
    from mozbuild.shellutil import quote

    option(env=var, nargs=1, help='Path to the %s program' % var.lower())

    if not (isinstance(progs, tuple) or isinstance(progs, list)):
@@ -56,7 +59,7 @@ def check_prog(var, progs, allow_missing=False):
    progs = list(progs)

    @depends(var)
    @checking('for %s' % var.lower(), lambda x: x or 'not found')
    @checking('for %s' % var.lower(), lambda x: quote(x) if x else 'not found')
    def check(value):
        if value:
            progs[:] = value
@@ -66,10 +69,8 @@ def check_prog(var, progs, allow_missing=False):
                return result

    @depends(check, var)
    @advanced
    def postcheck(value, raw_value):
        if value is None and (not allow_missing or raw_value):
            from mozbuild.shellutil import quote
            die('Cannot find %s (tried: %s)', var.lower(),
                ', '.join(quote(p) for p in progs))

+1 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ PYTHON_UNIT_TESTS += [
    'mozbuild/mozbuild/test/backend/test_recursivemake.py',
    'mozbuild/mozbuild/test/backend/test_visualstudio.py',
    'mozbuild/mozbuild/test/compilation/test_warnings.py',
    'mozbuild/mozbuild/test/configure/test_checks_configure.py',
    'mozbuild/mozbuild/test/configure/test_configure.py',
    'mozbuild/mozbuild/test/configure/test_options.py',
    'mozbuild/mozbuild/test/configure/test_util.py',
+1 −1
Original line number Diff line number Diff line
@@ -528,7 +528,7 @@ class ConfigureSandbox(dict):
        glob = SandboxedGlobal(func.func_globals)
        glob.update(
            __builtins__=self.BUILTINS,
            __file__=self._paths[-1],
            __file__=self._paths[-1] if self._paths else '',
            os=self.OS,
            log=self.log_impl,
        )
+160 −0
Original line number Diff line number Diff line
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

from __future__ import absolute_import, print_function, unicode_literals

from StringIO import StringIO
import os
import unittest

from mozunit import main

from mozbuild.configure import (
    ConfigureError,
    ConfigureSandbox,
)

from buildconfig import topsrcdir


class FindProgramSandbox(ConfigureSandbox):
    def __init__(self, *args, **kwargs):
        super(FindProgramSandbox, self).__init__(*args, **kwargs)

        # We could define self.find_program_impl and have it automatically
        # declared, but then it wouldn't be available in the tested templates.
        # We also need to use super().__setitem__ because ours would do
        # nothing.
        super(FindProgramSandbox, self).__setitem__(
            'find_program', self.template_impl(self.find_program))

    PROGRAMS = {
        'known-a': '/usr/bin/known-a',
        'known-b': '/usr/local/bin/known-b',
        'known c': '/home/user/bin/known c',
    }

    for p in PROGRAMS.values():
        PROGRAMS[p] = p

    @staticmethod
    def find_program(prog):
        return FindProgramSandbox.PROGRAMS.get(prog)

    def __setitem__(self, key, value):
        # Avoid util.configure overwriting our mock find_program
        if key == 'find_program':
            return

        super(FindProgramSandbox, self).__setitem__(key, value)


class TestChecksConfigure(unittest.TestCase):
    def get_result(self, command='', args=[], environ={},
                   prog='/bin/configure'):
        config = {}
        out = StringIO()
        sandbox = FindProgramSandbox(config, environ, [prog] + args, out, out)
        base_dir = os.path.join(topsrcdir, 'build', 'moz.configure')
        sandbox.exec_file(os.path.join(base_dir, 'util.configure'))
        sandbox.exec_file(os.path.join(base_dir, 'checks.configure'))

        status = 0
        try:
            exec(command, sandbox)
        except SystemExit as e:
            status = e.code

        return config, out.getvalue(), status

    def test_check_prog(self):
        config, out, status = self.get_result(
            'check_prog("FOO", ("known-a",))')
        self.assertEqual(status, 0)
        self.assertEqual(config, {'FOO': '/usr/bin/known-a'})
        self.assertEqual(out, 'checking for foo... /usr/bin/known-a\n')

        config, out, status = self.get_result(
            'check_prog("FOO", ("unknown", "known-b", "known c"))')
        self.assertEqual(status, 0)
        self.assertEqual(config, {'FOO': '/usr/local/bin/known-b'})
        self.assertEqual(out, 'checking for foo... /usr/local/bin/known-b\n')

        config, out, status = self.get_result(
            'check_prog("FOO", ("unknown", "unknown-2", "known c"))')
        self.assertEqual(status, 0)
        self.assertEqual(config, {'FOO': '/home/user/bin/known c'})
        self.assertEqual(out, "checking for foo... '/home/user/bin/known c'\n")

        config, out, status = self.get_result(
            'check_prog("FOO", ("unknown",))')
        self.assertEqual(status, 1)
        self.assertEqual(config, {})
        self.assertEqual(out, 'checking for foo... not found\n'
                              'ERROR: Cannot find foo (tried: unknown)\n')

        config, out, status = self.get_result(
            'check_prog("FOO", ("unknown", "unknown-2", "unknown 3"))')
        self.assertEqual(status, 1)
        self.assertEqual(config, {})
        self.assertEqual(out, 'checking for foo... not found\n'
                              'ERROR: Cannot find foo '
                              "(tried: unknown, unknown-2, 'unknown 3')\n")

        config, out, status = self.get_result(
            'check_prog("FOO", ("unknown", "unknown-2", "unknown 3"), '
            'allow_missing=True)')
        self.assertEqual(status, 0)
        self.assertEqual(config, {'FOO': ':'})
        self.assertEqual(out, 'checking for foo... not found\n')

    def test_check_prog_with_args(self):
        config, out, status = self.get_result(
            'check_prog("FOO", ("unknown", "known-b", "known c"))',
            ['FOO=known-a'])
        self.assertEqual(status, 0)
        self.assertEqual(config, {'FOO': '/usr/bin/known-a'})
        self.assertEqual(out, 'checking for foo... /usr/bin/known-a\n')

        config, out, status = self.get_result(
            'check_prog("FOO", ("unknown", "known-b", "known c"))',
            ['FOO=/usr/bin/known-a'])
        self.assertEqual(status, 0)
        self.assertEqual(config, {'FOO': '/usr/bin/known-a'})
        self.assertEqual(out, 'checking for foo... /usr/bin/known-a\n')

        config, out, status = self.get_result(
            'check_prog("FOO", ("unknown", "known-b", "known c"))',
            ['FOO=/usr/local/bin/known-a'])
        self.assertEqual(status, 1)
        self.assertEqual(config, {})
        self.assertEqual(out, 'checking for foo... not found\n'
                              'ERROR: Cannot find foo '
                              '(tried: /usr/local/bin/known-a)\n')

        config, out, status = self.get_result(
            'check_prog("FOO", ("unknown",))',
            ['FOO=known c'])
        self.assertEqual(status, 0)
        self.assertEqual(config, {'FOO': '/home/user/bin/known c'})
        self.assertEqual(out, "checking for foo... '/home/user/bin/known c'\n")

        config, out, status = self.get_result(
            'check_prog("FOO", ("unknown", "unknown-2", "unknown 3"), '
            'allow_missing=True)', ['FOO=unknown'])
        self.assertEqual(status, 1)
        self.assertEqual(config, {})
        self.assertEqual(out, 'checking for foo... not found\n'
                              'ERROR: Cannot find foo (tried: unknown)\n')

    def test_check_prog_configure_error(self):
        with self.assertRaises(ConfigureError) as e:
            self.get_result('check_prog("FOO", "foo")')

        self.assertEqual(e.exception.message,
                         'progs should be a list or tuple!')


if __name__ == '__main__':
    main()