Bug 1581684 - [mach] Fix regression to mach command completion, r=glandium

Not all callables have a __name__ attribute.

Differential Revision: https://phabricator.services.mozilla.com/D70229

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Andrew Halberstadt 2020-04-09 05:00:20 +00:00
parent 2b70a56ef5
commit 8592f79d9a
5 changed files with 116 additions and 5 deletions

View File

@ -23,7 +23,8 @@ class BuiltinCommands(object):
def command_keys(self):
# NOTE 'REMOVED' is a function in testing/mochitest/mach_commands.py
return (k for k, v in self.context.commands.command_handlers.items()
if not v.conditions or v.conditions[0].__name__ != 'REMOVED')
if not v.conditions
or getattr(v.conditions[0], '__name__', None) != 'REMOVED')
@Command('mach-commands', category='misc',
description='List all mach commands.')

View File

@ -9,6 +9,8 @@ import os
import sys
import unittest
import six
try:
from StringIO import StringIO
except ImportError:
@ -24,13 +26,18 @@ class TestBase(unittest.TestCase):
provider_dir = os.path.join(here, 'providers')
@classmethod
def get_mach(cls, provider_file=None, entry_point=None, context_handler=None):
def get_mach(cls, provider_files=None, entry_point=None, context_handler=None):
m = Mach(os.getcwd())
m.define_category('testing', 'Mach unittest', 'Testing for mach core', 10)
m.define_category('misc', 'Mach misc', 'Testing for mach core', 20)
m.populate_context_handler = context_handler
if provider_file:
m.load_commands_from_file(os.path.join(cls.provider_dir, provider_file))
if provider_files:
if isinstance(provider_files, six.string_types):
provider_files = [provider_files]
for path in provider_files:
m.load_commands_from_file(os.path.join(cls.provider_dir, path))
if entry_point:
m.load_commands_from_entry_point(entry_point)

View File

@ -0,0 +1,46 @@
# 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, unicode_literals
from functools import partial
from mach.decorators import (
CommandArgument,
CommandProvider,
Command,
)
def is_foo(cls):
"""Foo must be true"""
return cls.foo
def is_bar(val, cls):
"""Bar must equal val"""
return cls.bar == val
@CommandProvider
class MachCommands(object):
foo = True
bar = False
@Command('cmd_foo', category='testing')
@CommandArgument(
'--arg', default=None,
help="Argument help.")
def run_foo(self):
pass
@Command('cmd_bar', category='testing',
conditions=[partial(is_bar, False)])
def run_bar(self):
pass
@Command('cmd_foobar', category='testing',
conditions=[is_foo, partial(is_bar, True)])
def run_foobar(self):
pass

View File

@ -1,6 +1,7 @@
[DEFAULT]
subsuite = mach
[test_commands.py]
[test_conditions.py]
skip-if = python == 3
[test_config.py]
@ -10,4 +11,4 @@ skip-if = python == 3
skip-if = python == 3
[test_logger.py]
[test_mach.py]
[test_telemetry.py]
[test_telemetry.py]

View File

@ -0,0 +1,56 @@
# 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, unicode_literals
import os
from mozunit import main
import mach
from mach.test.common import TestBase
class TestCommands(TestBase):
all_commands = [
'cmd_bar',
'cmd_foo',
'cmd_foobar',
'mach-commands',
'mach-completion',
'mach-debug-commands',
]
def _run_mach(self, args, context_handler=None):
mach_dir = os.path.dirname(mach.__file__)
providers = [
'commands.py',
os.path.join(mach_dir, 'commands', 'commandinfo.py'),
]
return TestBase._run_mach(self, args, providers,
context_handler=context_handler)
def format(self, targets):
return "\n".join(targets) + "\n"
def test_mach_completion(self):
result, stdout, stderr = self._run_mach(['mach-completion'])
assert result == 0
assert stdout == self.format(self.all_commands)
result, stdout, stderr = self._run_mach(['mach-completion', 'cmd_f'])
assert result == 0
# While it seems like this should return only commands that have
# 'cmd_f' as a prefix, the completion script will handle this case
# properly.
assert stdout == self.format(self.all_commands)
result, stdout, stderr = self._run_mach(['mach-completion', 'cmd_foo'])
assert result == 0
assert stdout == self.format(['help', '--arg'])
if __name__ == '__main__':
main()