Beispiel #1
0
def test_main_dirname_provided_use_it(monkeypatch, capsys):
    can_connect_args = _monkeypatch_can_connect_to_socket_to_succeed(
        monkeypatch)

    def main_redis_url(dirname):
        project_dir_disable_dedicated_env(dirname)
        code = _parse_args_and_run_subcommand(
            ['anaconda-project', 'activate', '--directory', dirname])
        assert code == 0

    with_directory_contents_completing_project_file(
        {DEFAULT_PROJECT_FILENAME: """
services:
  REDIS_URL: redis
"""}, main_redis_url)

    assert can_connect_args['port'] == 6379

    out, err = capsys.readouterr()
    assert "export PROJECT_DIR" in out
    assert "export REDIS_URL=redis://localhost:6379\n" in out
    assert "" == err
Beispiel #2
0
def test_provide_no_download_in_check_mode(monkeypatch):
    MIN_DATAFILE_CONTENT = ("downloads:\n"
                            "    DATAFILE: http://localhost/data.csv\n")

    def provide_download(dirname):
        @gen.coroutine
        def mock_downloader_run(self, loop):
            raise Exception("should not have tried to download in check mode")

        monkeypatch.setattr(
            "anaconda_project.internal.http_client.FileDownloader.run",
            mock_downloader_run)

        project = project_no_dedicated_env(dirname)
        result = prepare_without_interaction(
            project,
            environ=minimal_environ(PROJECT_DIR=dirname),
            mode=provide.PROVIDE_MODE_CHECK)
        assert not result

    with_directory_contents_completing_project_file(
        {DEFAULT_PROJECT_FILENAME: MIN_DATAFILE_CONTENT}, provide_download)
def test_list_default_command(capsys):
    def check_empty_project(dirname):
        code = _parse_args_and_run_subcommand([
            'anaconda-project', 'list-default-command', '--directory', dirname
        ])
        assert code == 0

        out, err = capsys.readouterr()
        assert '' == err
        assert out.strip() == 'app'

    with_directory_contents_completing_project_file(
        {
            DEFAULT_PROJECT_FILENAME: ("commands:\n"
                                       "  app:\n"
                                       "    bokeh_app: test.py\n"
                                       "  0second:\n"
                                       "    notebook: test.ipynb\n"
                                       "packages:\n"
                                       " - bokeh\n"
                                       " - notebook\n")
        }, check_empty_project)
def test_env_var_provider_with_no_value():
    def check_env_var_provider(dirname):
        provider = EnvVarProvider()
        requirement = _load_env_var_requirement(dirname, "FOO")
        local_state_file = LocalStateFile.load_for_directory(dirname)
        status = requirement.check_status(dict(), local_state_file, 'default',
                                          UserConfigOverrides())
        context = ProvideContext(environ=dict(),
                                 local_state_file=local_state_file,
                                 default_env_spec_name='default',
                                 status=status,
                                 mode=PROVIDE_MODE_DEVELOPMENT,
                                 frontend=NullFrontend())

        provider.provide(requirement, context=context)
        assert 'FOO' not in context.environ

    with_directory_contents_completing_project_file(
        {DEFAULT_PROJECT_FILENAME: """
variables:
  - FOO
"""}, check_env_var_provider)
Beispiel #5
0
def test_add_command_ask_type_interrupted(monkeypatch, capsys):
    def check_ask_type(dirname):
        def mock_is_interactive():
            return True

        monkeypatch.setattr('anaconda_project.internal.cli.console_utils.stdin_is_interactive', mock_is_interactive)

        def mock_input(prompt):
            raise KeyboardInterrupt('^C')

        monkeypatch.setattr('anaconda_project.internal.cli.console_utils._input', mock_input)

        args = Args(None, 'test', 'file.py', directory=dirname)
        with pytest.raises(SystemExit) as excinfo:
            main(args)
        assert excinfo.value.code == 1

        out, err = capsys.readouterr()
        assert out == ''
        assert err == '\nCanceling\n\n'

    with_directory_contents_completing_project_file({DEFAULT_PROJECT_FILENAME: ''}, check_ask_type)
def test_prepare_command_not_in_project():
    def check(dirname):
        # create a command that isn't in the Project
        project = project_no_dedicated_env(dirname)
        command = ProjectCommand(name="foo",
                                 attributes=dict(bokeh_app="foo.py",
                                                 env_spec=project.default_env_spec_name))
        environ = minimal_environ()
        result = prepare_without_interaction(project, environ=environ, command=command)
        assert result.errors == []
        assert result
        assert os.path.join(project.directory_path, 'foo.py') in result.command_exec_info.args

    with_directory_contents_completing_project_file(
        {DEFAULT_PROJECT_FILENAME: """
commands:
  decoy:
    description: "do not use me"
    unix: foobar
    windows: foobar
""",
         "foo.py": "# foo"}, check)
Beispiel #7
0
def test_failed_download_before_connect(monkeypatch):
    def provide_download(dirname):
        @gen.coroutine
        def mock_downloader_run(self, loop):
            # if we don't even get an HTTP response, the errors are handled this way,
            # e.g. if the URL is bad.
            self._errors = ['This went horribly wrong']
            raise gen.Return(None)

        monkeypatch.setattr(
            "anaconda_project.internal.http_client.FileDownloader.run",
            mock_downloader_run)
        project = project_no_dedicated_env(dirname)
        result = prepare_without_interaction(
            project, environ=minimal_environ(PROJECT_DIR=dirname))
        assert not result
        assert (
            'missing requirement to run this project: A downloaded file which is referenced by DATAFILE.'
        ) in result.errors

    with_directory_contents_completing_project_file(
        {DEFAULT_PROJECT_FILENAME: DATAFILE_CONTENT}, provide_download)
def test_remove_command(monkeypatch, capsys):
    def check(dirname):
        code = _parse_args_and_run_subcommand([
            'anaconda-project', 'remove-command', 'test', '--directory',
            dirname
        ])
        assert code == 0

        project = Project(dirname)

        command = project.project_file.get_value(['commands', 'test'])
        assert command is None

        out, err = capsys.readouterr()
        assert out == "Removed the command 'test' from the project.\n"
        assert err == ''

    with_directory_contents_completing_project_file(
        {
            DEFAULT_PROJECT_FILENAME:
            'packages: ["notebook"]\ncommands:\n  test:\n    notebook: file.ipynb\n'
        }, check)
def _test_run_command_foo(command_line, monkeypatch, capsys, file_assertion=_is_python_exe):
    executed = {}

    def mock_execvpe(file, args, env):
        executed['file'] = file
        executed['args'] = args
        executed['env'] = env

    monkeypatch.setattr('os.execvpe', mock_execvpe)

    def check_run_main(dirname):
        from os.path import abspath as real_abspath

        def mock_abspath(path):
            if path == ".":
                return dirname
            else:
                return real_abspath(path)

        monkeypatch.setattr('os.path.abspath', mock_abspath)

        project_dir_disable_dedicated_env(dirname)

        for n, i in enumerate(command_line):
            if i == '<DIRNAME>':
                command_line[n] = dirname

        result = _parse_args_and_run_subcommand(command_line)

        assert 1 == result
        assert 'file' in executed
        assert 'args' in executed
        assert 'env' in executed
        file_assertion(executed['file'])

        out, err = capsys.readouterr()
        assert "" == out
        assert "" == err

        return executed['args'][1:]

    return with_directory_contents_completing_project_file(
        {DEFAULT_PROJECT_FILENAME: """
commands:
  default:
    conda_app_entry: python --version def
  foo:
    conda_app_entry: python --version foo
  bar:
    conda_app_entry: python --version bar
"""}, check_run_main)
def test_prepare_and_unprepare_download(monkeypatch):
    def provide_download(dirname):
        @gen.coroutine
        def mock_downloader_run(self, loop):
            class Res:
                pass

            res = Res()
            res.code = 200
            with open(os.path.join(dirname, 'data.csv'), 'w') as out:
                out.write('data')
            self._hash = '12345abcdef'
            raise gen.Return(res)

        monkeypatch.setattr(
            "anaconda_project.internal.http_client.FileDownloader.run",
            mock_downloader_run)
        project = project_no_dedicated_env(dirname)
        result = prepare_without_interaction(
            project, environ=minimal_environ(PROJECT_DIR=dirname))
        assert hasattr(result, 'environ')
        assert 'DATAFILE' in result.environ
        filename = os.path.join(dirname, 'data.csv')
        assert os.path.exists(filename)

        project.frontend.reset()
        status = unprepare(project, result)
        assert project.frontend.logs == [
            "Removed downloaded file %s." % filename,
            ("Current environment is not in %s, no need to delete it." %
             dirname)
        ]
        assert status.status_description == 'Success.'
        assert status
        assert not os.path.exists(filename)

    with_directory_contents_completing_project_file(
        {DEFAULT_PROJECT_FILENAME: DATAFILE_CONTENT}, provide_download)
Beispiel #11
0
def test_prepare_and_unprepare_two_local_redis_servers_with_failed_unprovide(
        monkeypatch):
    # this test will fail if you don't have Redis installed, since
    # it actually starts it.
    if platform.system() == 'Windows':
        print("Cannot start redis-server on Windows")
        return

    from anaconda_project.requirements_registry.network_util import can_connect_to_socket as real_can_connect_to_socket

    _monkeypatch_can_connect_to_socket_on_nonstandard_port_only(
        monkeypatch, real_can_connect_to_socket)

    def start_local_redis(dirname):
        project = project_no_dedicated_env(dirname)
        result = _prepare_printing_errors(project, environ=minimal_environ())
        assert result

        # now clean it up, but arrange for that to double-fail
        local_state_file = LocalStateFile.load_for_directory(dirname)
        local_state_file.set_service_run_state(
            'REDIS_URL', {'shutdown_commands': [['false']]})
        local_state_file.set_service_run_state(
            'REDIS_URL_2', {'shutdown_commands': [['false']]})
        local_state_file.save()
        status = unprepare(project, result)
        assert not status
        assert status.status_description == 'Failed to clean up REDIS_URL, REDIS_URL_2.'

    with_directory_contents_completing_project_file(
        {
            DEFAULT_PROJECT_FILENAME:
            """
services:
  REDIS_URL: redis
  REDIS_URL_2: redis
"""
        }, start_local_redis)
def test_unprepare_download_fails(monkeypatch):
    def provide_download(dirname):
        @gen.coroutine
        def mock_downloader_run(self, loop):
            class Res:
                pass

            res = Res()
            res.code = 200
            with open(os.path.join(dirname, 'data.csv'), 'w') as out:
                out.write('data')
            self._hash = '12345abcdef'
            raise gen.Return(res)

        monkeypatch.setattr("anaconda_project.internal.http_client.FileDownloader.run", mock_downloader_run)
        project = project_no_dedicated_env(dirname)
        result = prepare_without_interaction(project, environ=minimal_environ(PROJECT_DIR=dirname))
        assert hasattr(result, 'environ')
        assert 'DATAFILE' in result.environ
        filename = os.path.join(dirname, 'data.csv')
        assert os.path.exists(filename)

        def mock_remove(path):
            raise IOError("Not gonna remove this")

        monkeypatch.setattr("os.remove", mock_remove)

        project.frontend.reset()
        status = unprepare(project, result)
        assert project.frontend.logs == []
        assert status.status_description == ('Failed to remove %s: Not gonna remove this.' % filename)
        assert status.errors == []
        assert not status
        assert os.path.exists(filename)

        monkeypatch.undo()  # so os.remove isn't broken during directory cleanup

    with_directory_contents_completing_project_file({DEFAULT_PROJECT_FILENAME: DATAFILE_CONTENT}, provide_download)
def test_run_command_nonexistent_name(monkeypatch, capsys):
    def check_run_main(dirname):
        from os.path import abspath as real_abspath

        def mock_abspath(path):
            if path == ".":
                return dirname
            else:
                return real_abspath(path)

        monkeypatch.setattr('os.path.abspath', mock_abspath)

        def mock_execvpe(file, args, env):
            assert file == 'nope'
            assert args == ['nope']
            raise OSError("no such file nope")

        monkeypatch.setattr('os.execvpe', mock_execvpe)

        project_dir_disable_dedicated_env(dirname)
        result = _parse_args_and_run_subcommand(['anaconda-project', 'run', '--directory', dirname, 'nope'])

        assert 1 == result

        out, err = capsys.readouterr()
        assert "" == out
        assert "Failed to execute 'nope'" in err

    with_directory_contents_completing_project_file(
        {DEFAULT_PROJECT_FILENAME: """
commands:
  default:
    conda_app_entry: python --version
  foo:
    conda_app_entry: python --version foo
  bar:
    conda_app_entry: python --version bar
"""}, check_run_main)
Beispiel #14
0
def test_provide_whitelist(monkeypatch):
    def check(dirname):
        from anaconda_project.requirements_registry.requirements.conda_env import CondaEnvRequirement

        _monkeypatch_download_file(monkeypatch, dirname, filename="nope")

        no_foo = [('missing requirement to run this project: A downloaded file which is ' + 'referenced by FOO.'),
                  '  Environment variable FOO is not set.']

        # whitelist only the env req by class
        project = project_no_dedicated_env(dirname)
        environ = minimal_environ()
        result = prepare_without_interaction(project, provide_whitelist=(CondaEnvRequirement, ), environ=environ)
        assert result.errors == no_foo

        # whitelist by instance
        env_req = [req for req in project.requirements(None) if isinstance(req, CondaEnvRequirement)][0]
        result = prepare_without_interaction(project, provide_whitelist=(env_req, ), environ=environ)
        assert result.errors == no_foo

        # whitelist by variable name
        result = prepare_without_interaction(project, provide_whitelist=(env_req.env_var, ), environ=environ)
        assert result.errors == no_foo

        # whitelist the download
        result = prepare_without_interaction(
            project, provide_whitelist=(env_req, project.download_requirements(None)[0]), environ=environ)
        assert result.errors == []
        assert 'FOO' in result.environ

    with_directory_contents_completing_project_file(
        {
            DEFAULT_PROJECT_FILENAME: """
downloads:
  FOO: "http://example.com/nope"

"""
        }, check)
def test_main(monkeypatch, capsys):
    def mock_conda_create(prefix, pkgs, channels):
        raise RuntimeError("this test should not create an environment in %s with pkgs %r" % (prefix, pkgs))

    monkeypatch.setattr('anaconda_project.internal.conda_api.create', mock_conda_create)

    executed = {}

    def mock_execvpe(file, args, env):
        executed['file'] = file
        executed['args'] = args
        executed['env'] = env

    monkeypatch.setattr('os.execvpe', mock_execvpe)

    def check_run_main(dirname):
        project_dir_disable_dedicated_env(dirname)
        result = main(Args(directory=dirname))

        assert 1 == result
        assert 'file' in executed
        assert 'args' in executed
        assert 'env' in executed
        assert executed['file'].endswith(python_exe)
        assert executed['args'][0].endswith(python_exe)
        assert '--version' == executed['args'][1]

    with_directory_contents_completing_project_file(
        {DEFAULT_PROJECT_FILENAME: """
commands:
  default:
    conda_app_entry: python --version

"""}, check_run_main)

    out, err = capsys.readouterr()
    assert "" == out
    assert "" == err
def test_remove_download_dir(capsys, monkeypatch):
    def check(dirname):
        _monkeypatch_pwd(monkeypatch, dirname)

        code = _parse_args_and_run_subcommand(
            ['anaconda-project', 'remove-download', 'TEST_FILE'])
        project = Project(dirname)
        assert not project.downloads(project.default_env_spec_name)
        assert code == 0

        out, err = capsys.readouterr()
        filename = os.path.join(dirname, 'foo')
        assert (
            "Removed downloaded file %s.\nRemoved TEST_FILE from the project file.\n"
            % filename) == out
        assert '' == err

    with_directory_contents_completing_project_file(
        {
            DEFAULT_PROJECT_FILENAME:
            "downloads:\n  TEST_FILE: http://localhost/foo.zip",
            'foo/data.txt': 'data here'
        }, check)
def test_remove_platforms_from_specific_environment(capsys, monkeypatch):
    def check(dirname):
        _monkeypatch_pwd(monkeypatch, dirname)
        params = _monkeypatch_remove_platforms(
            monkeypatch, SimpleStatus(success=True,
                                      description='Installed ok.'))

        code = _parse_args_and_run_subcommand([
            'anaconda-project', 'remove-platforms', '--env-spec', 'foo', 'bar'
        ])
        assert code == 0

        out, err = capsys.readouterr()
        assert (
            'Installed ok.\n' +
            'Removed platforms from environment foo in project file: bar.\n'
        ) == out
        assert '' == err

        assert 1 == len(params['args'])
        assert dict(env_spec_name='foo', platforms=['bar']) == params['kwargs']

    with_directory_contents_completing_project_file(dict(), check)
def test_add_pip_packages_to_all_environments(capsys, monkeypatch):
    def check(dirname):
        _monkeypatch_pwd(monkeypatch, dirname)
        params = _monkeypatch_add_packages(
            monkeypatch, SimpleStatus(success=True,
                                      description='Installed ok.'))

        code = _parse_args_and_run_subcommand(
            ['anaconda-project', 'add-packages', '--pip', 'a', 'b'])
        assert code == 0

        out, err = capsys.readouterr()
        assert ('Installed ok.\n' +
                'Added packages to project file: a, b.\n') == out
        assert '' == err

        assert 1 == len(params['args'])
        assert dict(env_spec_name=None,
                    packages=['a', 'b'],
                    channels=None,
                    pip=True) == params['kwargs']

    with_directory_contents_completing_project_file(dict(), check)
def test_add_env_spec_with_packages(capsys, monkeypatch):
    def check(dirname):
        _monkeypatch_pwd(monkeypatch, dirname)
        params = _monkeypatch_add_env_spec(
            monkeypatch,
            SimpleStatus(success=True, description='Environment looks good.'))

        code = _parse_args_and_run_subcommand([
            'anaconda-project', 'add-env-spec', '--name', 'foo', '--channel',
            'c1', '--channel=c2', 'a', 'b'
        ])
        assert code == 0

        out, err = capsys.readouterr()
        assert ('Environment looks good.\n' +
                'Added environment foo to the project file.\n') == out
        assert '' == err

        assert 1 == len(params['args'])
        assert dict(name='foo', packages=['a', 'b'],
                    channels=['c1', 'c2']) == params['kwargs']

    with_directory_contents_completing_project_file(dict(), check)
def test_do_not_start_local_redis_server_in_check_mode(monkeypatch, capsys):
    can_connect_args_list = _monkeypatch_can_connect_to_socket_always_succeeds_on_nonstandard(
        monkeypatch)

    def no_start_local_redis(dirname):
        project = project_no_dedicated_env(dirname)
        result = _prepare_printing_errors(project,
                                          environ=minimal_environ(),
                                          mode=provide.PROVIDE_MODE_CHECK)
        assert not result
        assert 3 == len(can_connect_args_list)

    with_directory_contents_completing_project_file(
        {DEFAULT_PROJECT_FILENAME: """
services:
  REDIS_URL: redis
"""}, no_start_local_redis)

    out, err = capsys.readouterr()
    assert "Could not connect to system default Redis." in err
    assert "REDIS_URL" in err
    assert "missing requirement" in err
    assert "" == out
Beispiel #21
0
def test_unset_variable_command(monkeypatch):

    params = []

    def mock_unset_variables(project, _vars):
        params.append(_vars)
        return SimpleStatus(success=True, description="BOO")

    monkeypatch.setattr('anaconda_project.project_ops.unset_variables', mock_unset_variables)

    def check(dirname):
        res = _parse_args_and_run_subcommand(['anaconda-project', 'unset-variable', '--directory', dirname, 'foo', 'baz'
                                              ])
        assert res == 0

    with_directory_contents_completing_project_file(
        {DEFAULT_PROJECT_FILENAME: """
variables:
  - foo
  - baz
    """}, check)

    assert ['foo', 'baz'] == params[0]
Beispiel #22
0
def test_add_packages_to_specific_environment(capsys, monkeypatch):
    def check(dirname):
        _monkeypatch_pwd(monkeypatch, dirname)
        params = _monkeypatch_add_packages(monkeypatch, SimpleStatus(success=True, description='Installed ok.'))

        code = _parse_args_and_run_subcommand(['anaconda-project', 'add-packages', '--env-spec', 'foo', '--channel',
                                               'c1', '--channel=c2', 'a', 'b'])
        assert code == 0

        out, err = capsys.readouterr()
        assert ('Installed ok.\n' + 'Added packages to environment foo in project file: a, b.\n') == out
        assert '' == err

        assert 1 == len(params['args'])
        assert dict(env_spec_name='foo', packages=['a', 'b'], channels=['c1', 'c2']) == params['kwargs']

    with_directory_contents_completing_project_file(
        {DEFAULT_PROJECT_FILENAME: """
env_specs:
  foo:
   packages:
     - bar
"""}, check)
def test_set_variable_command_with_env_spec(monkeypatch):

    params = _monkeypatch_set_variables(monkeypatch)

    def check(dirname):
        res = _parse_args_and_run_subcommand([
            'anaconda-project', 'set-variable', '--env-spec', 'somespec', '--directory', dirname, 'foo=bar', 'baz=qux',
            'has_two_equals=foo=bar'
        ])
        assert res == 0

    with_directory_contents_completing_project_file(
        {
            DEFAULT_PROJECT_FILENAME: """
variables:
  - foo
  - baz
  - has_two_equals
    """
        }, check)

    assert 'somespec' == params[0]
    assert [('foo', 'bar'), ('baz', 'qux'), ('has_two_equals', 'foo=bar')] == params[1]
def test_prepare_download_mismatched_checksum_after_download(monkeypatch):
    def provide_download(dirname):
        @gen.coroutine
        def mock_downloader_run(self, loop):
            class Res:
                pass

            res = Res()
            res.code = 200
            with open(os.path.join(dirname, 'data.csv'), 'w') as out:
                out.write('data')
            self._hash = 'mismatched'
            raise gen.Return(res)

        monkeypatch.setattr("anaconda_project.internal.http_client.FileDownloader.run", mock_downloader_run)

        project = project_no_dedicated_env(dirname)
        result = prepare_without_interaction(project, environ=minimal_environ(PROJECT_DIR=dirname))
        assert not result
        assert ('Error downloading http://localhost/data.csv: mismatched hashes. '
                'Expected: 12345abcdef, calculated: mismatched') in result.errors

    with_directory_contents_completing_project_file({DEFAULT_PROJECT_FILENAME: DATAFILE_CONTENT}, provide_download)
def test_list_variables(capsys):
    def check_list_not_empty(dirname):
        code = _parse_args_and_run_subcommand(['anaconda-project', 'list-variables', '--directory', dirname])

        assert code == 0
        out, err = capsys.readouterr()
        expected_out = """
Variables for project: {dirname}

Name{space}Description
===={space}===========
{varname}  The project needs a Conda environment containing all required packages.
tes2{space}A downloaded file which is referenced by tes2.
test{space}A downloaded file which is referenced by test.
""".format(dirname=dirname, varname=PLATFORM_ENV_VAR, space="".ljust(len(PLATFORM_ENV_VAR) - 2)).strip() + "\n"
        assert out == expected_out

    with_directory_contents_completing_project_file(
        {
            DEFAULT_PROJECT_FILENAME: ('downloads:\n'
                                       '  test: http://localhost:8000/test.tgz\n'
                                       '  tes2: http://localhost:8000/train.tgz\n')
        }, check_list_not_empty)
Beispiel #26
0
def test_main(monkeypatch, capsys):
    def mock_conda_create(prefix, pkgs, channels):
        raise RuntimeError("this test should not create an environment in %s with pkgs %r" % (prefix, pkgs))

    monkeypatch.setattr('anaconda_project.internal.conda_api.create', mock_conda_create)

    can_connect_args = _monkeypatch_can_connect_to_socket_to_succeed(monkeypatch)

    def main_redis_url(dirname):
        project_dir_disable_dedicated_env(dirname)
        main(Args(directory=dirname))

    with_directory_contents_completing_project_file({DEFAULT_PROJECT_FILENAME: """
services:
  REDIS_URL: redis
"""}, main_redis_url)

    assert can_connect_args['port'] == 6379

    out, err = capsys.readouterr()

    assert "export REDIS_URL=redis://localhost:6379\n" in out
    assert "" == err
Beispiel #27
0
def test_archive_command_on_simple_project(capsys):
    def check(dirname):
        archivefile = os.path.join(dirname, "foo.zip")
        code = _parse_args_and_run_subcommand([
            'anaconda-project', 'archive', '--directory', dirname, archivefile
        ])
        assert code == 0

        out, err = capsys.readouterr()
        assert ('  added %s\n  added %s\nCreated project archive %s\n' %
                (os.path.join("some_name", DEFAULT_PROJECT_FILENAME),
                 os.path.join("some_name", "foo.py"), archivefile)) == out

        with zipfile.ZipFile(archivefile, mode='r') as zf:
            assert [os.path.basename(x) for x in sorted(zf.namelist())
                    ] == [DEFAULT_PROJECT_FILENAME, "foo.py"]

        assert os.path.exists(os.path.join(dirname, DEFAULT_PROJECT_FILENAME))

        assert '' == err

    with_directory_contents_completing_project_file(
        {'foo.py': 'print("hello")\n'}, check)
def test_archive_command_on_simple_project(capsys):
    def check(dirname):
        archivefile = os.path.join(dirname, "foo.zip")
        code = _parse_args_and_run_subcommand(['anaconda-project', 'archive', '--directory', dirname, archivefile])
        assert code == 0

        unlocked_warning = ("Warning: env specs are not locked, which means they may not work "
                            "consistently for others or when deployed.\n"
                            "  Consider using the 'anaconda-project lock' command to lock the project.")

        out, err = capsys.readouterr()
        assert ('  added %s\n  added %s\n%s\nCreated project archive %s\n' %
                (os.path.join("some_name", DEFAULT_PROJECT_FILENAME), os.path.join(
                    "some_name", "foo.py"), unlocked_warning, archivefile)) == out

        with zipfile.ZipFile(archivefile, mode='r') as zf:
            assert [os.path.basename(x) for x in sorted(zf.namelist())] == [DEFAULT_PROJECT_FILENAME, "foo.py"]

        assert os.path.exists(os.path.join(dirname, DEFAULT_PROJECT_FILENAME))

        assert '' == err

    with_directory_contents_completing_project_file({'foo.py': 'print("hello")\n'}, check)
def test_add_service(capsys, monkeypatch):
    def check(dirname):
        _monkeypatch_pwd(monkeypatch, dirname)

        status = SimpleStatus(success=True, description='Service added.')
        status.requirement = RedisRequirement(RequirementsRegistry(),
                                              env_var='REDIS_URL',
                                              options=dict(type='redis'))

        _monkeypatch_add_service(monkeypatch, status)

        code = _parse_args_and_run_subcommand(
            ['anaconda-project', 'add-service', 'redis'])
        assert code == 0

        out, err = capsys.readouterr()
        assert (
            'Service added.\n' +
            'Added service redis to the project file, its address will be in REDIS_URL.\n'
        ) == out
        assert '' == err

    with_directory_contents_completing_project_file(dict(), check)
def test_display_suggestions(monkeypatch, capsys):
    def check(dirname):
        project_dir_disable_dedicated_env(dirname)

        def mock_is_interactive():
            return True

        monkeypatch.setattr(
            'anaconda_project.internal.cli.console_utils.stdin_is_interactive',
            mock_is_interactive)

        def mock_console_input(prompt, encrypted):
            raise Exception("should not have been called")

        monkeypatch.setattr(
            'anaconda_project.internal.cli.console_utils.console_input',
            mock_console_input)

        res = _parse_args_and_run_subcommand(
            ['anaconda-project', 'prepare', '--directory', dirname])
        assert res == 0

        out, err = capsys.readouterr()

        assert """Potential issues with this project:
  * anaconda-project.yml: Unknown field name 'weird_field'

The project is ready to run commands.
Use `anaconda-project list-commands` to see what's available.
""" == out
        assert '' == err

    with_directory_contents_completing_project_file(
        {DEFAULT_PROJECT_FILENAME: """
packages: []
weird_field: 42
"""}, check)