Esempio n. 1
0
        def prep_tmphome():
            # re core.askPass:
            # Don't let git ask for credentials in CI runs. Note, that this variable
            # technically is not a flag, but an executable (which is why name and value
            # are a bit confusing here - we just want a no-op basically). The environment
            # variable GIT_ASKPASS overwrites this, but neither env var nor this config
            # are supported by git-credential on all systems and git versions (most recent
            # ones should work either way, though). Hence use both across CI builds.
            gitconfig = """\
[user]
        name = DataLad Tester
        email = [email protected]
[core]
	askPass =
[datalad "log"]
        exc = 1
[annex "security"]
	# from annex 6.20180626 file:/// and http://localhost access isn't
	# allowed by default
	allowed-url-schemes = http https file
	allowed-http-addresses = all
"""
            # TODO: split into a function + context manager
            with make_tempfile(mkdir=True) as new_home:
                pass
            # register for clean-up on exit
            _TEMP_PATHS_GENERATED.append(new_home)

            # populate default config
            new_home = Path(new_home)
            new_home.mkdir(parents=True, exist_ok=True)
            cfg_file = new_home / '.gitconfig'
            cfg_file.write_text(gitconfig)
            return new_home, cfg_file
Esempio n. 2
0
def test_datalad_credential_helper(path=None):

    ds = Dataset(path).create()

    # tell git to use git-credential-datalad
    ds.config.add('credential.helper', 'datalad', scope='local')
    ds.config.add('datalad.credentials.githelper.noninteractive',
                  'true',
                  scope='global')

    from datalad.downloaders.providers import Providers

    url1 = "https://datalad-test.org/some"
    url2 = "https://datalad-test.org/other"
    provider_name = "datalad-test.org"

    # `Providers` code is old and only considers a dataset root based on PWD
    # for config lookup. contextmanager below can be removed once the
    # provider/credential system is redesigned.
    with chpwd(ds.path):

        gitcred = GitCredentialInterface(url=url1, repo=ds)

        # There's nothing set up yet, helper should return empty
        gitcred.fill()
        eq_(gitcred['username'], '')
        eq_(gitcred['password'], '')

        # store new credentials
        # Note, that `Providers.enter_new()` currently uses user-level config
        # files for storage only. TODO: make that an option!
        # To not mess with existing ones, fail if it already exists:

        cfg_file = Path(Providers._get_providers_dirs()['user']) \
                   / f"{provider_name}.cfg"
        assert_false(cfg_file.exists())

        # Make sure we clean up
        from datalad.tests import _TEMP_PATHS_GENERATED
        _TEMP_PATHS_GENERATED.append(str(cfg_file))

        # Give credentials to git and ask it to store them:
        gitcred = GitCredentialInterface(url=url1,
                                         username="******",
                                         password="******",
                                         repo=ds)
        gitcred.approve()

        assert_true(cfg_file.exists())
        providers = Providers.from_config_files()
        p1 = providers.get_provider(url=url1, only_nondefault=True)
        assert_is_instance(p1.credential, UserPassword)
        eq_(p1.credential.get('user'), 'dl-user')
        eq_(p1.credential.get('password'), 'dl-pwd')

        # default regex should be host only, so matching url2, too
        p2 = providers.get_provider(url=url2, only_nondefault=True)
        assert_is_instance(p1.credential, UserPassword)
        eq_(p1.credential.get('user'), 'dl-user')
        eq_(p1.credential.get('password'), 'dl-pwd')

        # git, too, should now find it for both URLs
        gitcred = GitCredentialInterface(url=url1, repo=ds)
        gitcred.fill()
        eq_(gitcred['username'], 'dl-user')
        eq_(gitcred['password'], 'dl-pwd')

        gitcred = GitCredentialInterface(url=url2, repo=ds)
        gitcred.fill()
        eq_(gitcred['username'], 'dl-user')
        eq_(gitcred['password'], 'dl-pwd')

        # Rejection must not currently lead to deleting anything, since we would
        # delete too broadly.
        gitcred.reject()
        assert_true(cfg_file.exists())
        gitcred = GitCredentialInterface(url=url1, repo=ds)
        gitcred.fill()
        eq_(gitcred['username'], 'dl-user')
        eq_(gitcred['password'], 'dl-pwd')
        dlcred = UserPassword(name=provider_name)
        eq_(dlcred.get('user'), 'dl-user')
        eq_(dlcred.get('password'), 'dl-pwd')
Esempio n. 3
0
def setup_package():
    import os
    from datalad import consts
    _test_states['HOME'] = os.environ.get('HOME', None)
    _test_states['DATASETS_TOPURL_ENV'] = os.environ.get(
        'DATALAD_DATASETS_TOPURL', None)
    _test_states['DATASETS_TOPURL'] = consts.DATASETS_TOPURL
    os.environ[
        'DATALAD_DATASETS_TOPURL'] = consts.DATASETS_TOPURL = 'http://datasets-tests.datalad.org/'

    # To overcome pybuild overriding HOME but us possibly wanting our
    # own HOME where we pre-setup git for testing (name, email)
    if 'GIT_HOME' in os.environ:
        os.environ['HOME'] = os.environ['GIT_HOME']
    else:
        # we setup our own new HOME, the BEST and HUGE one
        from datalad.utils import make_tempfile
        from datalad.tests import _TEMP_PATHS_GENERATED
        # TODO: split into a function + context manager
        with make_tempfile(mkdir=True) as new_home:
            os.environ['HOME'] = new_home
        if not os.path.exists(new_home):
            os.makedirs(new_home)
        with open(os.path.join(new_home, '.gitconfig'), 'w') as f:
            f.write("""\
[user]
	name = DataLad Tester
	email = [email protected]
""")
        _TEMP_PATHS_GENERATED.append(new_home)

    # For now we will just verify that it is ready to run the tests
    from datalad.support.gitrepo import check_git_configured
    check_git_configured()

    # To overcome pybuild by default defining http{,s}_proxy we would need
    # to define them to e.g. empty value so it wouldn't bother touching them.
    # But then haskell libraries do not digest empty value nicely, so we just
    # pop them out from the environment
    for ev in ('http_proxy', 'https_proxy'):
        if ev in os.environ and not (os.environ[ev]):
            lgr.debug("Removing %s from the environment since it is empty", ev)
            os.environ.pop(ev)

    # During tests we allow for "insecure" access to local file:// and
    # http://localhost URLs since all of them either generated as tests
    # fixtures or cloned from trusted sources
    from datalad.support.annexrepo import AnnexRepo
    AnnexRepo._ALLOW_LOCAL_URLS = True

    DATALAD_LOG_LEVEL = os.environ.get('DATALAD_LOG_LEVEL', None)
    if DATALAD_LOG_LEVEL is None:
        # very very silent.  Tests introspecting logs should use
        # swallow_logs(new_level=...)
        _test_states['loglevel'] = lgr.getEffectiveLevel()
        lgr.setLevel(100)

        # And we should also set it within environ so underlying commands also stay silent
        _test_states['DATALAD_LOG_LEVEL'] = DATALAD_LOG_LEVEL
        os.environ['DATALAD_LOG_LEVEL'] = '100'
    else:
        # We are not overriding them, since explicitly were asked to have some log level
        _test_states['loglevel'] = None

    # Set to non-interactive UI
    from datalad.ui import ui
    _test_states['ui_backend'] = ui.backend
    # obtain() since that one consults for the default value
    ui.set_backend(cfg.obtain('datalad.tests.ui.backend'))
Esempio n. 4
0
def setup_package():
    import os
    from datalad.utils import on_osx
    from datalad.tests import _TEMP_PATHS_GENERATED

    if on_osx:
        # enforce honoring TMPDIR (see gh-5307)
        import tempfile
        tempfile.tempdir = os.environ.get('TMPDIR', tempfile.gettempdir())

    from datalad import consts

    _test_states['env'] = {}

    def set_envvar(v, val):
        """Memoize and then set env var"""
        _test_states['env'][v] = os.environ.get(v, None)
        os.environ[v] = val

    _test_states['DATASETS_TOPURL'] = consts.DATASETS_TOPURL
    consts.DATASETS_TOPURL = 'http://datasets-tests.datalad.org/'
    set_envvar('DATALAD_DATASETS_TOPURL', consts.DATASETS_TOPURL)

    from datalad.tests.utils import (
        DEFAULT_BRANCH,
        DEFAULT_REMOTE,
    )
    set_envvar(
        "GIT_CONFIG_PARAMETERS",
        "'init.defaultBranch={}' 'clone.defaultRemoteName={}'".format(
            DEFAULT_BRANCH, DEFAULT_REMOTE))

    # To overcome pybuild overriding HOME but us possibly wanting our
    # own HOME where we pre-setup git for testing (name, email)
    if 'GIT_HOME' in os.environ:
        set_envvar('HOME', os.environ['GIT_HOME'])
        set_envvar('DATALAD_LOG_EXC', "1")
    else:
        # we setup our own new HOME, the BEST and HUGE one
        from datalad.utils import make_tempfile
        # TODO: split into a function + context manager
        with make_tempfile(mkdir=True) as new_home:
            pass
        for v, val in get_home_envvars(new_home).items():
            set_envvar(v, val)
        if not os.path.exists(new_home):
            os.makedirs(new_home)
        with open(os.path.join(new_home, '.gitconfig'), 'w') as f:
            f.write("""\
[user]
	name = DataLad Tester
	email = [email protected]
[datalad "log"]
	exc = 1
""")
        _TEMP_PATHS_GENERATED.append(new_home)

    # Re-load ConfigManager, since otherwise it won't consider global config
    # from new $HOME (see gh-4153
    cfg.reload(force=True)

    from datalad.interface.common_cfg import compute_cfg_defaults
    compute_cfg_defaults()
    # datalad.locations.sockets has likely changed. Discard any cached values.
    ssh_manager._socket_dir = None

    # To overcome pybuild by default defining http{,s}_proxy we would need
    # to define them to e.g. empty value so it wouldn't bother touching them.
    # But then haskell libraries do not digest empty value nicely, so we just
    # pop them out from the environment
    for ev in ('http_proxy', 'https_proxy'):
        if ev in os.environ and not (os.environ[ev]):
            lgr.debug("Removing %s from the environment since it is empty", ev)
            os.environ.pop(ev)

    # During tests we allow for "insecure" access to local file:// and
    # http://localhost URLs since all of them either generated as tests
    # fixtures or cloned from trusted sources
    from datalad.support.annexrepo import AnnexRepo
    AnnexRepo._ALLOW_LOCAL_URLS = True

    DATALAD_LOG_LEVEL = os.environ.get('DATALAD_LOG_LEVEL', None)
    if DATALAD_LOG_LEVEL is None:
        # very very silent.  Tests introspecting logs should use
        # swallow_logs(new_level=...)
        _test_states['loglevel'] = lgr.getEffectiveLevel()
        lgr.setLevel(100)

        # And we should also set it within environ so underlying commands also stay silent
        set_envvar('DATALAD_LOG_LEVEL', '100')
    else:
        # We are not overriding them, since explicitly were asked to have some log level
        _test_states['loglevel'] = None

    # Set to non-interactive UI
    from datalad.ui import ui
    _test_states['ui_backend'] = ui.backend
    # obtain() since that one consults for the default value
    ui.set_backend(cfg.obtain('datalad.tests.ui.backend'))

    # Monkey patch nose so it does not ERROR out whenever code asks for fileno
    # of the output. See https://github.com/nose-devs/nose/issues/6
    from io import StringIO as OrigStringIO

    class StringIO(OrigStringIO):
        fileno = lambda self: 1
        encoding = None

    from nose.ext import dtcompat
    from nose.plugins import capture, multiprocess, plugintest
    dtcompat.StringIO = StringIO
    capture.StringIO = StringIO
    multiprocess.StringIO = StringIO
    plugintest.StringIO = StringIO

    # in order to avoid having to fiddle with rather uncommon
    # file:// URLs in the tests, have a standard HTTP server
    # that serves an 'httpserve' directory in the test HOME
    # the URL will be available from datalad.test_http_server.url
    from datalad.tests.utils import HTTPPath
    import tempfile
    global test_http_server
    serve_path = tempfile.mkdtemp(
        dir=cfg.get("datalad.tests.temp.dir"),
        prefix='httpserve',
    )
    test_http_server = HTTPPath(serve_path)
    test_http_server.start()
    _TEMP_PATHS_GENERATED.append(serve_path)

    if cfg.obtain('datalad.tests.setup.testrepos'):
        lgr.debug("Pre-populating testrepos")
        from datalad.tests.utils import with_testrepos
        with_testrepos()(lambda repo: 1)()
Esempio n. 5
0
def setup_package():
    import os
    from datalad import consts
    _test_states['HOME'] = os.environ.get('HOME', None)
    _test_states['DATASETS_TOPURL_ENV'] = os.environ.get('DATALAD_DATASETS_TOPURL', None)
    _test_states['DATASETS_TOPURL'] = consts.DATASETS_TOPURL
    os.environ['DATALAD_DATASETS_TOPURL'] = consts.DATASETS_TOPURL = 'http://datasets-tests.datalad.org/'

    # To overcome pybuild overriding HOME but us possibly wanting our
    # own HOME where we pre-setup git for testing (name, email)
    if 'GIT_HOME' in os.environ:
        os.environ['HOME'] = os.environ['GIT_HOME']
    else:
        # we setup our own new HOME, the BEST and HUGE one
        from datalad.utils import make_tempfile
        from datalad.tests import _TEMP_PATHS_GENERATED
        # TODO: split into a function + context manager
        with make_tempfile(mkdir=True) as new_home:
            os.environ['HOME'] = new_home
        if not os.path.exists(new_home):
            os.makedirs(new_home)
        with open(os.path.join(new_home, '.gitconfig'), 'w') as f:
            f.write("""\
[user]
	name = DataLad Tester
	email = [email protected]
""")
        _TEMP_PATHS_GENERATED.append(new_home)

    # If there is a bundled git, make sure GitPython uses it too
    # (some parts of the test utilities still rely on GitPython)
    from datalad.cmd import GitRunner
    GitRunner._check_git_path()
    if GitRunner._GIT_PATH:
        import os
        os.environ['GIT_PYTHON_GIT_EXECUTABLE'] = \
            os.path.join(GitRunner._GIT_PATH, 'git')

    # Re-load ConfigManager, since otherwise it won't consider global config
    # from new $HOME (see gh-4153
    cfg.reload(force=True)

    # To overcome pybuild by default defining http{,s}_proxy we would need
    # to define them to e.g. empty value so it wouldn't bother touching them.
    # But then haskell libraries do not digest empty value nicely, so we just
    # pop them out from the environment
    for ev in ('http_proxy', 'https_proxy'):
        if ev in os.environ and not (os.environ[ev]):
            lgr.debug("Removing %s from the environment since it is empty", ev)
            os.environ.pop(ev)

    # During tests we allow for "insecure" access to local file:// and
    # http://localhost URLs since all of them either generated as tests
    # fixtures or cloned from trusted sources
    from datalad.support.annexrepo import AnnexRepo
    AnnexRepo._ALLOW_LOCAL_URLS = True

    DATALAD_LOG_LEVEL = os.environ.get('DATALAD_LOG_LEVEL', None)
    if DATALAD_LOG_LEVEL is None:
        # very very silent.  Tests introspecting logs should use
        # swallow_logs(new_level=...)
        _test_states['loglevel'] = lgr.getEffectiveLevel()
        lgr.setLevel(100)

        # And we should also set it within environ so underlying commands also stay silent
        _test_states['DATALAD_LOG_LEVEL'] = DATALAD_LOG_LEVEL
        os.environ['DATALAD_LOG_LEVEL'] = '100'
    else:
        # We are not overriding them, since explicitly were asked to have some log level
        _test_states['loglevel'] = None

    # Set to non-interactive UI
    from datalad.ui import ui
    _test_states['ui_backend'] = ui.backend
    # obtain() since that one consults for the default value
    ui.set_backend(cfg.obtain('datalad.tests.ui.backend'))

    # Monkey patch nose so it does not ERROR out whenever code asks for fileno
    # of the output. See https://github.com/nose-devs/nose/issues/6
    from io import StringIO as OrigStringIO

    class StringIO(OrigStringIO):
        fileno = lambda self: 1
        encoding = None

    from nose.ext import dtcompat
    from nose.plugins import capture, multiprocess, plugintest
    dtcompat.StringIO = StringIO
    capture.StringIO = StringIO
    multiprocess.StringIO = StringIO
    plugintest.StringIO = StringIO
Esempio n. 6
0
def setup_package():
    import tempfile
    from pathlib import Path

    from datalad import consts
    from datalad.support.annexrepo import AnnexRepo
    from datalad.support.cookies import cookies_db
    from datalad.support.external_versions import external_versions
    from datalad.tests import _TEMP_PATHS_GENERATED
    from datalad.tests.utils_pytest import (
        DEFAULT_BRANCH,
        DEFAULT_REMOTE,
        OBSCURE_FILENAME,
        HTTPPath,
        rmtemp,
    )
    from datalad.ui import ui
    from datalad.utils import (
        make_tempfile,
        on_osx,
    )

    if on_osx:
        # enforce honoring TMPDIR (see gh-5307)
        tempfile.tempdir = os.environ.get('TMPDIR', tempfile.gettempdir())

    with pytest.MonkeyPatch().context() as m:
        m.setattr(consts, "DATASETS_TOPURL",
                  'https://datasets-tests.datalad.org/')
        m.setenv('DATALAD_DATASETS_TOPURL', consts.DATASETS_TOPURL)

        m.setenv(
            "GIT_CONFIG_PARAMETERS",
            "'init.defaultBranch={}' 'clone.defaultRemoteName={}'".format(
                DEFAULT_BRANCH, DEFAULT_REMOTE))

        def prep_tmphome():
            # re core.askPass:
            # Don't let git ask for credentials in CI runs. Note, that this variable
            # technically is not a flag, but an executable (which is why name and value
            # are a bit confusing here - we just want a no-op basically). The environment
            # variable GIT_ASKPASS overwrites this, but neither env var nor this config
            # are supported by git-credential on all systems and git versions (most recent
            # ones should work either way, though). Hence use both across CI builds.
            gitconfig = """\
[user]
        name = DataLad Tester
        email = [email protected]
[core]
	askPass =
[datalad "log"]
        exc = 1
[annex "security"]
	# from annex 6.20180626 file:/// and http://localhost access isn't
	# allowed by default
	allowed-url-schemes = http https file
	allowed-http-addresses = all
"""
            # TODO: split into a function + context manager
            with make_tempfile(mkdir=True) as new_home:
                pass
            # register for clean-up on exit
            _TEMP_PATHS_GENERATED.append(new_home)

            # populate default config
            new_home = Path(new_home)
            new_home.mkdir(parents=True, exist_ok=True)
            cfg_file = new_home / '.gitconfig'
            cfg_file.write_text(gitconfig)
            return new_home, cfg_file

        if external_versions['cmd:git'] < "2.32":
            # To overcome pybuild overriding HOME but us possibly wanting our
            # own HOME where we pre-setup git for testing (name, email)
            if 'GIT_HOME' in os.environ:
                m.setenv('HOME', os.environ['GIT_HOME'])
            else:
                # we setup our own new HOME, the BEST and HUGE one
                new_home, _ = prep_tmphome()
                for v, val in get_home_envvars(new_home).items():
                    m.setenv(v, val)
        else:
            _, cfg_file = prep_tmphome()
            m.setenv('GIT_CONFIG_GLOBAL', str(cfg_file))

        # Re-load ConfigManager, since otherwise it won't consider global config
        # from new $HOME (see gh-4153
        cfg.reload(force=True)

        # datalad.locations.sockets has likely changed. Discard any cached values.
        ssh_manager._socket_dir = None

        # To overcome pybuild by default defining http{,s}_proxy we would need
        # to define them to e.g. empty value so it wouldn't bother touching them.
        # But then haskell libraries do not digest empty value nicely, so we just
        # pop them out from the environment
        for ev in ('http_proxy', 'https_proxy'):
            if ev in os.environ and not (os.environ[ev]):
                lgr.debug("Removing %s from the environment since it is empty",
                          ev)
                os.environ.pop(ev)

        # Prevent interactive credential entry (note "true" is the command to run)
        # See also the core.askPass setting above
        m.setenv('GIT_ASKPASS', 'true')

        # Set to non-interactive UI
        _test_states['ui_backend'] = ui.backend
        # obtain() since that one consults for the default value
        ui.set_backend(cfg.obtain('datalad.tests.ui.backend'))

        # in order to avoid having to fiddle with rather uncommon
        # file:// URLs in the tests, have a standard HTTP server
        # that serves an 'httpserve' directory in the test HOME
        # the URL will be available from datalad.test_http_server.url

        global test_http_server
        # Start the server only if not running already
        # Relevant: we have test_misc.py:test_test which runs datalad.test but
        # not doing teardown, so the original server might never get stopped
        if test_http_server is None:
            serve_path = tempfile.mkdtemp(
                dir=cfg.get("datalad.tests.temp.dir"),
                prefix='httpserve',
            )
            test_http_server = HTTPPath(serve_path)
            test_http_server.start()
            _TEMP_PATHS_GENERATED.append(serve_path)

        if cfg.obtain('datalad.tests.setup.testrepos'):
            lgr.debug("Pre-populating testrepos")
            from datalad.tests.utils_pytest import with_testrepos
            with_testrepos()(lambda repo: 1)()

        yield

        lgr.debug("Printing versioning information collected so far")
        # Query for version of datalad, so it is included in ev.dumps below - useful while
        # testing extensions where version of datalad might differ in the environment.
        external_versions['datalad']
        print(external_versions.dumps(query=True))
        try:
            print("Obscure filename: str=%s repr=%r" %
                  (OBSCURE_FILENAME.encode('utf-8'), OBSCURE_FILENAME))
        except UnicodeEncodeError as exc:
            ce = CapturedException(exc)
            print("Obscure filename failed to print: %s" % ce)

        def print_dict(d):
            return " ".join("%s=%r" % v for v in d.items())

        print("Encodings: %s" % print_dict(get_encoding_info()))
        print("Environment: %s" % print_dict(get_envvars_info()))

        if os.environ.get('DATALAD_TESTS_NOTEARDOWN'):
            return

        ui.set_backend(_test_states['ui_backend'])

        if test_http_server:
            test_http_server.stop()
            test_http_server = None
        else:
            lgr.debug(
                "For some reason global http_server was not set/running, thus not stopping"
            )

        if len(_TEMP_PATHS_GENERATED):
            msg = "Removing %d dirs/files: %s" % (
                len(_TEMP_PATHS_GENERATED), ', '.join(_TEMP_PATHS_GENERATED))
        else:
            msg = "Nothing to remove"
        lgr.debug("Teardown tests. " + msg)
        for path in _TEMP_PATHS_GENERATED:
            rmtemp(str(path), ignore_errors=True)

    # Re-establish correct global config after changing $HOME.
    # Might be superfluous, since after teardown datalad.cfg shouldn't be
    # needed. However, maintaining a consistent state seems a good thing
    # either way.
    cfg.reload(force=True)

    ssh_manager._socket_dir = None

    cookies_db.close()
Esempio n. 7
0
def setup_package():
    import os
    from datalad import consts
    _test_states['HOME'] = os.environ.get('HOME', None)
    _test_states['DATASETS_TOPURL_ENV'] = os.environ.get('DATALAD_DATASETS_TOPURL', None)
    _test_states['DATASETS_TOPURL'] = consts.DATASETS_TOPURL
    os.environ['DATALAD_DATASETS_TOPURL'] = consts.DATASETS_TOPURL = 'http://datasets-tests.datalad.org/'

    # To overcome pybuild overriding HOME but us possibly wanting our
    # own HOME where we pre-setup git for testing (name, email)
    if 'GIT_HOME' in os.environ:
        os.environ['HOME'] = os.environ['GIT_HOME']
    else:
        # we setup our own new HOME, the BEST and HUGE one
        from datalad.utils import make_tempfile
        from datalad.tests import _TEMP_PATHS_GENERATED
        # TODO: split into a function + context manager
        with make_tempfile(mkdir=True) as new_home:
            os.environ['HOME'] = new_home
        if not os.path.exists(new_home):
            os.makedirs(new_home)
        with open(os.path.join(new_home, '.gitconfig'), 'w') as f:
            f.write("""\
[user]
	name = DataLad Tester
	email = [email protected]
""")
        _TEMP_PATHS_GENERATED.append(new_home)

    # For now we will just verify that it is ready to run the tests
    from datalad.support.gitrepo import check_git_configured
    check_git_configured()

    # To overcome pybuild by default defining http{,s}_proxy we would need
    # to define them to e.g. empty value so it wouldn't bother touching them.
    # But then haskell libraries do not digest empty value nicely, so we just
    # pop them out from the environment
    for ev in ('http_proxy', 'https_proxy'):
        if ev in os.environ and not (os.environ[ev]):
            lgr.debug("Removing %s from the environment since it is empty", ev)
            os.environ.pop(ev)

    # During tests we allow for "insecure" access to local file:// and
    # http://localhost URLs since all of them either generated as tests
    # fixtures or cloned from trusted sources
    from datalad.support.annexrepo import AnnexRepo
    AnnexRepo._ALLOW_LOCAL_URLS = True

    DATALAD_LOG_LEVEL = os.environ.get('DATALAD_LOG_LEVEL', None)
    if DATALAD_LOG_LEVEL is None:
        # very very silent.  Tests introspecting logs should use
        # swallow_logs(new_level=...)
        _test_states['loglevel'] = lgr.getEffectiveLevel()
        lgr.setLevel(100)

        # And we should also set it within environ so underlying commands also stay silent
        _test_states['DATALAD_LOG_LEVEL'] = DATALAD_LOG_LEVEL
        os.environ['DATALAD_LOG_LEVEL'] = '100'
    else:
        # We are not overriding them, since explicitly were asked to have some log level
        _test_states['loglevel'] = None

    # Set to non-interactive UI
    from datalad.ui import ui
    _test_states['ui_backend'] = ui.backend
    # obtain() since that one consults for the default value
    ui.set_backend(cfg.obtain('datalad.tests.ui.backend'))