def main() -> int: """ Entrypoint for ``nait`` which synthesizes a pytest for each fixture name as an function asserting success on the fixture's gather method. For example, given :: nait nanaimo_bar ... the following, equivalent test function would be synthesized :: test_nanaimo_bar(pytest_args, nanaimo_bar): assert_success(nanaimo_bar.gather(**pytest_args)) """ if '--environ-shell' in sys.argv or '-S' in sys.argv: import nanaimo defaults = nanaimo.config.ArgumentDefaults.create_defaults_with_early_rc_config() args_ns = nanaimo.Namespace(defaults=defaults, allow_none_values=False) for key, value in args_ns.get_as_merged_dict('environ').items(): print('export {}="{}";'.format(key, value), end='') argv_len = len(sys.argv) for x in range(0, argv_len): if sys.argv[x] == '--environ' and x < argv_len - 1: environ_pair = sys.argv[x+1].split('=') if len(environ_pair) == 2: print('export {}="{}";'.format(environ_pair[0].strip(), environ_pair[1].strip())) return 0 if '--version' in sys.argv: from nanaimo.version import __version__ print(__version__) return 0 import nanaimo.pytest.plugin import pytest nanaimo.pytest.plugin._nait_mode = True return pytest.main()
async def test_composite_fixture( event_loop: asyncio.AbstractEventLoop) -> None: """ Test creation of a composite fixture. """ class Composite(nanaimo_bar.Fixture, nanaimo_cmd.Fixture): fixture_name = 'test_composite_fixture' argument_prefix = 'tcf' def __init__(self, manager: nanaimo.fixtures.FixtureManager, args: nanaimo.Namespace, **kwargs: typing.Any) -> None: super().__init__(manager, args, **kwargs) @classmethod def on_visit_test_arguments(cls, arguments: nanaimo.Arguments) -> None: nanaimo_bar.Fixture.visit_test_arguments(arguments) nanaimo_cmd.Fixture.visit_test_arguments(arguments) async def on_gather(self, args: nanaimo.Namespace) -> nanaimo.Artifacts: cmd_artifacts = await nanaimo_cmd.Fixture.on_gather(self, args) bar_artifacts = await nanaimo_bar.Fixture.on_gather(self, args) return nanaimo.Artifacts.combine(cmd_artifacts, bar_artifacts) composite = Composite(nanaimo.fixtures.FixtureManager(event_loop), nanaimo.Namespace()) filter = nanaimo.fixtures.SubprocessFixture.SubprocessMessageAccumulator() composite.stdout_filter = filter results = await composite.gather(tcf_shell='nait --version') results.eat() assert filter.getvalue() == nanaimo.version.__version__
def test_set_subprocess_environment_no_environ() -> None: """ Verify that no exceptions are thrown if the defaults config lacks an ``environ`` key. """ defaults = MagicMock(spec=nanaimo.config.ArgumentDefaults) defaults.__getitem__ = MagicMock(side_effect=KeyError()) set_subprocess_environment(nanaimo.Namespace(defaults=defaults))
def test_get_as_merged_dict() -> None: """ Verify that no exceptions are thrown if the defaults config lacks an ``environ`` key when using Namespace.get_as_merged_dict() """ defaults = MagicMock(spec=nanaimo.config.ArgumentDefaults) defaults.__getitem__ = MagicMock(side_effect=KeyError()) nanaimo.Namespace(defaults=defaults).get_as_merged_dict('environ')
def _create_display(cls, args: typing.Optional[nanaimo.Namespace]) -> _CharacterDisplayInterface: if args is None: defaults = nanaimo.config.ArgumentDefaults.create_defaults_with_early_rc_config() args = nanaimo.Namespace(defaults=defaults) try: return _CharacterDisplayAdafruitSerialBackpack(args) except serial.SerialException: pass # No hardware display. Just use the null display. return _CharacterDisplayInterface()
def _create_pytest_fixture( self, pytest_request: typing.Any, nanaimo_fixture_manager: nanaimo.fixtures.FixtureManager, fixture_type: typing.Type['nanaimo.fixtures.Fixture'] ) -> nanaimo.fixtures.Fixture: args = pytest_request.config.option args_ns = nanaimo.Namespace(args, nanaimo.config.ArgumentDefaults(args), allow_none_values=False) return fixture_type(nanaimo_fixture_manager, args_ns)
def to_namespace( fixture_type: typing.Type[nanaimo.fixtures.Fixture], command: str, nanaimo_defaults: nanaimo.config.ArgumentDefaults ) -> nanaimo.Namespace: parser = argparse.ArgumentParser() fixture_type.visit_test_arguments( nanaimo.Arguments(parser, nanaimo_defaults)) return nanaimo.Namespace( parser.parse_args( args=['--bk-port', 'dummy_port', '--bk-command', command]))
async def test_gather_coroutines(nanaimo_fixture_manager: nanaimo.fixtures.FixtureManager) -> None: parser = argparse.ArgumentParser() nanaimo_gather.Fixture.on_visit_test_arguments(nanaimo.Arguments(parser, required_prefix='gather')) args = nanaimo.Namespace(parser.parse_args(['--gather-coroutine', 'nanaimo_bar', '--gather-coroutine', 'nanaimo_bar'])) gather_fixture = nanaimo_gather.Fixture(nanaimo_fixture_manager, args) results = await gather_fixture.gather() assert results.result_code == 0
def pytest_sessionstart(session: _pytest.main.Session) -> None: """ See :func:`_pytest.hookspec.pytest_sessionstart` for documentation. Also see the "`Writing Plugins <https://docs.pytest.org/en/latest/writing_plugins.html>`_" guide. """ args = session.config.option args_ns = nanaimo.Namespace(args, nanaimo.config.ArgumentDefaults(args), allow_none_values=False) nanaimo.set_subprocess_environment(args_ns) _get_display(session.config).set_status('busy')
def __init__(self, manager: 'FixtureManager', args: typing.Optional[nanaimo.Namespace] = None, **kwargs: typing.Any): self._manager = manager self._args = (args if args is not None else nanaimo.Namespace()) self._name = self.get_canonical_name() self._logger = logging.getLogger(self._name) if 'loop' in kwargs: raise ValueError('Do not pass the loop into the fixture. ' 'Fixtures obtain the loop from their FixtureManager.') if 'gather_timeout_seconds' in kwargs: gather_timeout_seconds = typing.cast(typing.Optional[float], kwargs['gather_timeout_seconds']) self._gather_timeout_seconds = gather_timeout_seconds else: self._gather_timeout_seconds = None
def __init__(self, manager: 'FixtureManager', args: typing.Optional[nanaimo.Namespace] = None, **kwargs: typing.Any): self._manager = manager self._args = (args if args is not None else nanaimo.Namespace()) self._name = self.get_canonical_name() self._logger = logging.getLogger(self._name) if 'loop' in kwargs: print( 'WARNING: Passing loop into Fixture is deprecated. (This will be an exception in a future release).' ) if 'gather_timeout_seconds' in kwargs: gather_timeout_seconds = typing.cast( typing.Optional[float], kwargs['gather_timeout_seconds']) self._gather_timeout_seconds = gather_timeout_seconds else: self._gather_timeout_seconds = None
async def test_loop_into_fixture_arg( event_loop: asyncio.AbstractEventLoop) -> None: class Dummy(nanaimo.fixtures.Fixture): def __init__(self, manager: nanaimo.fixtures.FixtureManager, args: nanaimo.Namespace, **kwargs: typing.Any) -> None: super().__init__(manager, args, **kwargs) def on_visit_test_arguments(cls, arguments: nanaimo.Arguments) -> None: pass async def on_gather(self, args: nanaimo.Namespace) -> nanaimo.Artifacts: return nanaimo.Artifacts() with pytest.raises(ValueError): Dummy(nanaimo.fixtures.FixtureManager(event_loop), nanaimo.Namespace(), loop=event_loop)
def nanaimo_arguments(request: typing.Any) -> nanaimo.Namespace: """ Exposes the commandline arguments and defaults provided to a test. .. invisible-code-block: python import nanaimo import nanaimo.fixtures .. code-block:: python def test_example(nanaimo_arguments: nanaimo.Namespace) -> None: an_argument = nanaimo_arguments.some_arg :param pytest_request: The request object passed into the pytest fixture factory. :type pytest_request: _pytest.fixtures.FixtureRequest :return: A namespace with the pytest commandline args added per the documented rules. :rtype: nanaimo.Namespace """ return nanaimo.Namespace(request.config.option)
def runtest(self) -> None: """ Run all fixtures specified on the command-line. """ loop = asyncio.get_event_loop() fixtures = [] nanaimo_defaults = nanaimo.config.ArgumentDefaults.create_defaults_with_early_rc_config( ) nanaimo_args = nanaimo.Namespace(self.session.config.option, nanaimo_defaults) fixture_manager = PytestFixtureManager(self.config.pluginmanager, loop) for fixture_name in self._fixture_names: fixtures.append( fixture_manager.create_fixture(fixture_name, nanaimo_args)) gathers = [asyncio.ensure_future(f.gather()) for f in fixtures] results = loop.run_until_complete(asyncio.gather(*gathers, loop=loop)) combined = nanaimo.Artifacts.combine(*results) assert combined.result_code == 0 getattr(self.session.config, self.nanaimo_results_sneaky_key)[','.join( self._fixture_names)] = combined
def gather_timeout_fixture(request: typing.Any) -> nanaimo.fixtures.Fixture: args = nanaimo.Namespace(request.config.option, nanaimo.config.ArgumentDefaults( request.config.option), allow_none_values=False) return GatherTimeoutFixture(nanaimo.fixtures.FixtureManager(), args)