# -*- coding: utf-8 -*- import io import textwrap import click from click.testing import CliRunner from six.moves import builtins from valuedispatch import valuedispatch from profiling.__about__ import __version__ from profiling.__main__ import cli, Module, profiler_options, ProfilingCLI from profiling.sampling import SamplingProfiler from profiling.sampling.samplers import TracingSampler from profiling.tracing import TracingProfiler class MockFileIO(io.StringIO): def close(self): self.seek(0) def mock_file(indented_content): return MockFileIO(textwrap.dedent(indented_content)) cli_runner = CliRunner() def test_module_param_type(): t = Module() # timeit filename, code, globals_ = t.convert('timeit', None, None) assert filename.endswith('timeit.py') assert code.co_filename.endswith('timeit.py') assert globals_['__name__'] == '__main__' assert globals_['__file__'].endswith('timeit.py') assert globals_['__package__'] == '' # profiling.__main__ filename, code, globals_ = t.convert('profiling', None, None) assert filename.endswith('profiling/__main__.py') assert code.co_filename.endswith('profiling/__main__.py') assert globals_['__name__'] == '__main__' assert globals_['__file__'].endswith('profiling/__main__.py') assert globals_['__package__'] == 'profiling' def test_customized_cli(): cli = ProfilingCLI(default='bar') @cli.command(aliases=['fooo', 'foooo']) def foo(): pass @cli.command() @click.argument('l', default='answer') @click.option('-n', type=int, default=0) def bar(l, n=0): click.echo('%s: %d' % (l, n)) assert len(cli.commands) == 2 ctx = click.Context(cli) assert cli.get_command(ctx, 'foo').name == 'foo' assert cli.get_command(ctx, 'fooo').name == 'foo' assert cli.get_command(ctx, 'foooo').name == 'foo' assert cli.get_command(ctx, 'bar').name == 'bar' assert cli.get_command(ctx, 'hello.txt').name == 'bar' assert 'Usage:' in cli_runner.invoke(cli, []).output assert cli_runner.invoke(cli, ['zero']).output == 'zero: 0\n' assert cli_runner.invoke(cli, ['one', '-n', '1']).output == 'one: 1\n' assert cli_runner.invoke(cli, ['-n', '42']).output == 'answer: 42\n' assert 'no such option' in cli_runner.invoke(cli, ['-x']).output def test_profiling_command_usage(): for cmd in ['profile', 'live-profile', 'remote-profile']: r = cli_runner.invoke(cli, [cmd, '--help']) assert 'SCRIPT [--] [ARGV]...' in r.output def test_version(): r = cli_runner.invoke(cli, ['--version']) assert r.output.strip() == 'profiling, version %s' % __version__ def test_config(monkeypatch): @click.command() @profiler_options def f(profiler_factory, **kwargs): profiler = profiler_factory() return profiler, kwargs # no config. def io_error(*args, **kwargs): raise IOError monkeypatch.setattr(builtins, 'open', io_error) profiler, kwargs = f([], standalone_mode=False) assert isinstance(profiler, TracingProfiler) # config to use SamplingProfiler. monkeypatch.setattr(builtins, 'open', lambda *a, **k: mock_file(u''' [profiling] profiler = sampling sampler = tracing ''')) profiler, kwargs = f([], standalone_mode=False) assert isinstance(profiler, SamplingProfiler) assert isinstance(profiler.sampler, TracingSampler) # set both of setup.cfg and .profiling. @valuedispatch def mock_open(path, *args, **kwargs): raise IOError @mock_open.register('setup.cfg') def open_setup_cfg(*_, **__): return mock_file(u''' [profiling] profiler = sampling pickle-protocol = 3 ''') @mock_open.register('.profiling') def open_profiling(*_, **__): return mock_file(u''' [profiling] pickle-protocol = 0 ''') monkeypatch.setattr(builtins, 'open', mock_open) profiler, kwargs = f([], standalone_mode=False) assert isinstance(profiler, SamplingProfiler) # from setup.cfg assert kwargs['pickle_protocol'] == 0 # from .profiling