Beispiel #1
0
def test_overrides():
    cfg = ConfigManager()
    # any sensible (and also our CI) test environment(s) should have this
    assert_in('user.name', cfg)
    # set
    cfg.set('user.name', 'myoverride', scope='override')
    assert_equal(cfg['user.name'], 'myoverride')
    # unset just removes override, not entire config
    cfg.unset('user.name', scope='override')
    assert_in('user.name', cfg)
    assert_not_equal('user.name', 'myoverride')
    # add
    # there is no initial increment
    cfg.add('user.name', 'myoverride', scope='override')
    assert_equal(cfg['user.name'], 'myoverride')
    # same as with add, not a list
    assert_equal(cfg['user.name'], 'myoverride')
    # but then there is
    cfg.add('user.name', 'myother', scope='override')
    assert_equal(cfg['user.name'], ['myoverride', 'myother'])
    # rename
    assert_not_in('ups.name', cfg)
    cfg.rename_section('user', 'ups', scope='override')
    # original variable still there
    assert_in('user.name', cfg)
    # rename of override in effect
    assert_equal(cfg['ups.name'], ['myoverride', 'myother'])
    # remove entirely by section
    cfg.remove_section('ups', scope='override')
    from datalad.utils import Path
    assert_not_in('ups.name', cfg, (
        cfg._stores,
        cfg.overrides,
    ))
Beispiel #2
0
def test_get_content_info_paths_empty_list(path=None):
    ds = Dataset(path).create()

    # Unlike None, passing any empty list as paths to get_content_info() does
    # not report on all content.
    assert_false(ds.repo.get_content_info(paths=[]))
    assert_false(ds.repo.get_content_info(paths=[], ref="HEAD"))

    # Add annex content to make sure its not reported.
    (ds.pathobj / "foo").write_text("foo")
    ds.save()

    # Same for get_content_annexinfo()...
    assert_false(ds.repo.get_content_annexinfo(paths=[]))
    assert_false(ds.repo.get_content_annexinfo(paths=[], init=None))
    assert_false(ds.repo.get_content_annexinfo(paths=[], ref="HEAD"))
    assert_false(ds.repo.get_content_annexinfo(paths=[], ref="HEAD",
                                               init=None))
    # ... where whatever was passed for init will be returned as is.
    assert_equal(
        ds.repo.get_content_annexinfo(paths=[],
                                      ref="HEAD",
                                      init={"random": {
                                          "entry": "a"
                                      }}), {"random": {
                                          "entry": "a"
                                      }})
Beispiel #3
0
def _test_setup_store(io_cls, io_args, store=None):
    io = io_cls(*io_args)
    store = Path(store)
    version_file = store / 'ria-layout-version'
    error_logs = store / 'error_logs'

    # invalid version raises:
    assert_raises(UnknownLayoutVersion, create_store, io, store, '2')

    # non-existing path should work:
    create_store(io, store, '1')
    assert_true(version_file.exists())
    assert_true(error_logs.exists())
    assert_true(error_logs.is_dir())
    assert_equal([f for f in error_logs.iterdir()], [])

    # empty target directory should work as well:
    rmtree(str(store))
    store.mkdir(exist_ok=False)
    create_store(io, store, '1')
    assert_true(version_file.exists())
    assert_true(error_logs.exists())
    assert_true(error_logs.is_dir())
    assert_equal([f for f in error_logs.iterdir()], [])

    # re-execution also fine:
    create_store(io, store, '1')

    # but version conflict with existing target isn't:
    version_file.write_text("2|unknownflags\n")
    assert_raises(ValueError, create_store, io, store, '1')
def test_get_metadata(path=None):

    ds = Dataset(path).create(force=True)
    p = MetadataExtractor(ds, [])
    meta = p._get_dataset_metadata()
    assert_equal(
        dumps(meta, sort_keys=True, indent=2), """\
{
  "author": "Jane Doe <*****@*****.**>",
  "conformsto": "http://specs.frictionlessdata.io/data-packages",
  "contributors": [
    "Joe Bloggs <*****@*****.**> (http://www.example.com)"
  ],
  "description": "Annual Consumer Price Index (CPI) for most countries in the world. Reference year is 2005.",
  "license": "http://opendatacommons.org/licenses/pddl/",
  "name": "cpi",
  "shortdescription": "Annual Consumer Price Index (CPI)",
  "tag": [
    "CPI",
    "World",
    "Consumer Price Index",
    "Annual Data",
    "The World Bank"
  ],
  "version": "2.0.0"
}""")
 def decorated_test1(url):
     # we expect a file-scheme url to a cached version of `ds_url`
     expect_origin_path = cache_dir / name_in_cache
     assert_equal(expect_origin_path.as_uri(), url)
     origin = Dataset(expect_origin_path)
     assert_true(origin.is_installed())
     assert_false(origin.repo.file_has_content(str(annexed_file)))
Beispiel #6
0
def test_verify_ria_url():
    # unsupported protocol
    assert_raises(ValueError, verify_ria_url, 'ria+ftp://localhost/tmp/this',
                  {})
    # bunch of caes that should work
    cases = {
        'ria+file:///tmp/this': (None, '/tmp/this'),
        # no normalization
        'ria+file:///tmp/this/': (None, '/tmp/this/'),
        # with hosts
        'ria+ssh://localhost/tmp/this': ('ssh://localhost', '/tmp/this'),
        'ria+http://localhost/tmp/this': ('http://localhost', '/tmp/this'),
        'ria+https://localhost/tmp/this': ('https://localhost', '/tmp/this'),
        # with username
        'ria+ssh://humbug@localhost/tmp/this':
        ('ssh://humbug@localhost', '/tmp/this'),
        # with port
        'ria+ssh://humbug@localhost:2222/tmp/this':
        ('ssh://humbug@localhost:2222', '/tmp/this'),
        'ria+ssh://localhost:2200/tmp/this':
        ('ssh://*****:*****@localhost:8080/tmp/this':
        ('https://*****:*****@localhost:8080', '/tmp/this'),
        # document a strange (MIH thinks undesirable), but pre-existing
        # behavior an 'ssh example.com' would end up in the user HOME,
        # not in '/'
        'ria+ssh://example.com': ('ssh://example.com', '/')
    }
    for i, o in cases.items():
        # we are not testing the URL rewriting here
        assert_equal(o, verify_ria_url(i, {})[:2])
Beispiel #7
0
def test_stalling(kill=False):
    import concurrent.futures

    from datalad.cmd import WitlessRunner

    def worker():
        WitlessRunner().run(["echo", "1"])

    t0 = time()
    v1 = worker()
    dt1 = time() - t0

    t0 = time()
    with concurrent.futures.ThreadPoolExecutor(1) as executor:
        # print("submitting")
        future = executor.submit(worker)
        dt2_limit = dt1 * 5
        # print("waiting for up to %.2f sec" % dt2_limit)
        while not future.done():
            # print("not yet")
            sleep(dt1 / 3)
            if time() - t0 > dt2_limit:
                # does not even shutdown
                # executor.shutdown(wait=False)
                if kill:
                    # raising an exception isn't enough!
                    print("exceeded")
                    import os
                    import signal
                    os.kill(os.getpid(), signal.SIGTERM)
                raise AssertionError("Future has not finished in 5x time")
        v2 = future.result()
    assert_equal(v1, v2)
Beispiel #8
0
def test_get_metadata(path1=None, path2=None):
    for p in (path1, path2):
        print('PATH')
        ds = create(p, force=True)
        ds.save()
        meta = MetadataExtractor(
                ds,
                _get_metadatarelevant_paths(ds, []))._get_dataset_metadata()
        assert_equal(
            dumps(meta, sort_keys=True, indent=2),
            """\
{
  "author": [
    "Last1, First1",
    "Last2, First2"
  ],
  "citation": [
    "10.1016/j.cub.2011.08.031"
  ],
  "description": "Some long description.",
  "formats": [
    "application/matlab",
    "NIFTY"
  ],
  "name": "CRCNS.org xxx-1",
  "sameas": "10.6080/K0QN64NG",
  "shortdescription": "Main title",
  "tag": [
    "Neuroscience",
    "fMRI"
  ],
  "version": "1.0"
}""")
Beispiel #9
0
def test_get_metadata(path=None):

    ds = Dataset(path).create(force=True)
    ds.save()
    meta = MetadataExtractor(ds, [])._get_dataset_metadata()
    assert_equal(
        dumps(meta, sort_keys=True, indent=2), """\
{
  "citation": "Cool (2016)",
  "conformsto": "http://docs.datalad.org/metadata.html#v0-1",
  "description": "A text with arbitrary length and content that can span multiple\\nparagraphs (this is a new one)",
  "fundedby": "BMBFGQ1411, NSF 1429999",
  "homepage": "http://studyforrest.org",
  "issuetracker": "https://github.com/psychoinformatics-de/studyforrest-data-phase2/issues",
  "license": [
    "CC0-1.0",
    "The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law.\\nYou can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission."
  ],
  "maintainer": [
    "Mike One <*****@*****.**>",
    "Anna Two <*****@*****.**>"
  ],
  "name": "studyforrest_phase2",
  "sameas": "http://dx.doi.org/10.5281/zenodo.48421",
  "shortdescription": "Basic summary",
  "version": "1.0.0-rc3"
}""")
Beispiel #10
0
def test_annexinfo_init(path=None):
    ds = Dataset(path).create()
    foo = ds.pathobj / "foo"
    foo_cont = b"foo content"
    foo.write_bytes(foo_cont)
    bar = ds.pathobj / "bar"
    bar.write_text(u"bar content")
    ds.save()

    # Custom init limits report, with original dict getting updated.
    cinfo_custom_init = ds.repo.get_content_annexinfo(
        init={foo: {
            "bytesize": 0,
            "this-is-surely-only-here": "right?"
        }})
    assert_not_in(bar, cinfo_custom_init)
    assert_in(foo, cinfo_custom_init)
    assert_equal(cinfo_custom_init[foo]["bytesize"], len(foo_cont))
    assert_equal(cinfo_custom_init[foo]["this-is-surely-only-here"], "right?")

    # "git" injects get_content_info() values.
    cinfo_init_git = ds.repo.get_content_annexinfo(init="git")
    assert_in("gitshasum", cinfo_init_git[foo])

    # init=None, on the other hand, does not.
    cinfo_init_none = ds.repo.get_content_annexinfo(init=None)
    assert_in(foo, cinfo_init_none)
    assert_in(bar, cinfo_init_none)
    assert_not_in("gitshasum", cinfo_init_none[foo])
Beispiel #11
0
def test_color_enabled():
    # In the absence of NO_COLOR, follow ui.color, or ui.is_interactive if 'auto'
    with patch.dict(os.environ), \
         patch('datalad.support.ansi_colors.ui'):
        os.environ.pop('NO_COLOR', None)
        for is_interactive in (True, False):
            colors.ui.is_interactive = is_interactive
            with patch_config({'datalad.ui.color': 'off'}):
                assert_equal(colors.color_enabled(), False)
            with patch_config({'datalad.ui.color': 'on'}):
                assert_equal(colors.color_enabled(), True)
            with patch_config({'datalad.ui.color': 'auto'}):
                assert_equal(colors.color_enabled(), is_interactive)

    # In the presence of NO_COLOR, default to disable, unless ui.color is "on"
    # The value of NO_COLOR should have no effect, so try true-ish and false-ish values
    for NO_COLOR in ("", "1", "0"):
        with patch.dict(os.environ, {'NO_COLOR': NO_COLOR}), \
             patch('datalad.support.ansi_colors.ui'):
            for is_interactive in (True, False):
                colors.ui.is_interactive = is_interactive
                with patch_config({'datalad.ui.color': 'on'}):
                    assert_equal(colors.color_enabled(), True)
                for ui_color in ('off', 'auto'):
                    with patch_config({'datalad.ui.color': ui_color}):
                        assert_equal(colors.color_enabled(), False)
Beispiel #12
0
def test_file_number_activity_detection():
    # Expect an output queue that just has the process exit notification.
    # empty output queue without active threads
    # waits for the process and progresses the generator state
    # to `_ResultGenerator.GeneratorState.process_exited`.
    class TestFNADProtocol(GeneratorMixIn, NoCapture):
        def __init__(self):
            GeneratorMixIn.__init__(self)
            NoCapture.__init__(self)

        def process_exited(self):
            self.send_result(3)

        def connection_lost(self, exc: Optional[Exception]) -> None:
            self.send_result(4)

    wl_runner = WitlessRunner()
    result_generator = wl_runner.run(cmd=["echo", "a"],
                                     protocol=TestFNADProtocol)

    runner = result_generator.runner
    output_queue = runner.output_queue
    assert len(result_generator.runner.active_file_numbers) == 1
    while runner.should_continue():
        runner.process_queue()

    # Expect process exited and connection lost to be called.
    assert_equal(result_generator.send(None), 3)
    assert_equal(result_generator.send(None), 4)
    assert_raises(StopIteration, result_generator.send, None)
Beispiel #13
0
def test_dirty(path=None):
    for mode in _dirty_modes:
        # does nothing without a dataset
        handle_dirty_dataset(None, mode)
    # placeholder, but not yet created
    ds = Dataset(path)
    # unknown mode
    assert_raises(ValueError, handle_dirty_dataset, ds, 'MADEUP')
    # not yet created is very dirty
    assert_raises(RuntimeError, handle_dirty_dataset, ds, 'fail')
    handle_dirty_dataset(ds, 'ignore')
    assert_raises(RuntimeError, handle_dirty_dataset, ds, 'save-before')
    # should yield a clean repo
    ds.create()
    orig_state = ds.repo.get_hexsha()
    _check_all_clean(ds, orig_state)
    # tainted: untracked
    with open(opj(ds.path, 'something'), 'w') as f:
        f.write('some')
    # we don't want to auto-add untracked files by saving (anymore)
    assert_raises(AssertionError, _check_auto_save, ds, orig_state)
    # tainted: staged
    ds.repo.add('something', git=True)
    orig_state = _check_auto_save(ds, orig_state)
    # tainted: submodule
    # not added to super on purpose!
    subds = ds.create('subds')
    _check_all_clean(subds, subds.repo.get_hexsha())
    assert_repo_status(ds.path)
    # subdataset must be added as a submodule!
    assert_equal(ds.subdatasets(result_xfm='relpaths'), ['subds'])
Beispiel #14
0
def test_result_filter():
    # ensure baseline without filtering
    assert_equal([r['somekey'] for r in TestUtils().__call__(4)], [0, 1, 2, 3])
    # test two functionally equivalent ways to filter results
    # 1. Constraint-based -- filter by exception
    #    we have a full set of AND and OR operators for this
    # 2. custom filer function -- filter by boolean return value
    for filt in (EnsureKeyChoice('somekey', (0, 2)), lambda x: x['somekey'] in
                 (0, 2)):
        assert_equal([
            r['somekey'] for r in TestUtils().__call__(4, result_filter=filt)
        ], [0, 2])
        # constraint returns full dict
        assert_dict_equal(TestUtils().__call__(4, result_filter=filt)[-1], {
            'action': 'off',
            'path': 'some',
            'status': 'ok',
            'somekey': 2
        })

    # test more sophisticated filters that actually get to see the
    # API call's kwargs
    def greatfilter(res, **kwargs):
        assert_equal(kwargs.get('dataset', 'bob'), 'awesome')
        return True

    TestUtils().__call__(4, dataset='awesome', result_filter=greatfilter)

    def sadfilter(res, **kwargs):
        assert_equal(kwargs.get('dataset', 'bob'), None)
        return True

    TestUtils().__call__(4, result_filter=sadfilter)
 def assert_no_trash_left_behind(self):
     assert_equal(
         list(
             find_files(r'\.datalad..*',
                        self.annex.path,
                        exclude="config",
                        dirs=True)), [])
Beispiel #16
0
def test_batched_command():
    bc = BatchedCommand(cmd=[sys.executable, "-i", "-u", "-q", "-"])
    response = bc("print('a')")
    assert_equal(response, "a")
    response = bc("print(2 + 1)")
    assert_equal(response, "3")
    stderr = bc.close(return_stderr=True)
    assert_is_not_none(stderr)
Beispiel #17
0
def test_line_splitter_unterminated():
    # Expect two lines split at "x", after the second process-call
    line_splitter = LineSplitter("x")
    lines = line_splitter.process("first line")
    assert_equal(lines, [])
    lines = line_splitter.process("xsecond linex")
    assert_equal(lines, ["first line", "second line"])
    assert_is_none(line_splitter.finish_processing())
Beispiel #18
0
def test_choice():
    c = ct.EnsureChoice('choice1', 'choice2', None)
    # this should always work
    assert_equal(c('choice1'), 'choice1')
    assert_equal(c(None), None)
    # this should always fail
    assert_raises(ValueError, lambda: c('fail'))
    assert_raises(ValueError, lambda: c('None'))
Beispiel #19
0
def test_format_no_errors():
    json_objects = get_json_objects(1, 3)

    result = _format_json_error_messages(json_objects)
    assert_equal(result, "")

    result = _format_json_error_messages(json_objects + json_objects)
    assert_equal(result, "")
Beispiel #20
0
def test_none():
    c = ct.EnsureNone()
    # this should always work
    assert_equal(c(None), None)
    # instance of NoneDeprecated is also None
    assert_equal(c(ct.NoneDeprecated), None)
    # this should always fail
    assert_raises(ValueError, lambda: c('None'))
    assert_raises(ValueError, lambda: c([]))
Beispiel #21
0
def _check_mocked_install(default_dspath, mock_install):
    gen = search(".", return_type='generator')
    assert_is_generator(gen)
    # we no longer do any custom path tune up from the one returned by search
    # so should match what search returns
    assert_equal(list(gen), [report for report in _mocked_search_results])
    mock_install.assert_called_once_with(default_dspath,
                                         source='///',
                                         result_renderer='disabled')
Beispiel #22
0
def test_ancient_annex():
    class _runner(object):
        def run(self, cmd, *args, **kwargs):
            if '--raw' in cmd:
                raise CommandError
            return dict(stdout="git-annex version: 0.1", stderr="")

    ev = ExternalVersions()
    with patch('datalad.support.external_versions._runner', _runner()):
        assert_equal(ev['cmd:annex'], '0.1')
Beispiel #23
0
def test_setup():
    # insufficient arguments
    check_setup_parser([], 2)
    assert_in('too few arguments', check_setup_parser(['datalad'], 2)['err'])
    assert_in('.', check_setup_parser(['datalad', '--version'], 0)['out'])
    parser = check_setup_parser(['datalad', 'wtf'])['parser']
    # check into the guts of argparse to check that really only a single
    # subparser was constructed
    assert_equal(list(parser._positionals._group_actions[0].choices.keys()),
                 ['wtf'])
Beispiel #24
0
def test_both():
    # this should always work
    c = ct.AltConstraints(
        ct.Constraints(
            ct.EnsureFloat(),
            ct.EnsureRange(min=7.0, max=44.0)),
        ct.EnsureNone())
    assert_equal(c(7.0), 7.0)
    assert_equal(c(None), None)
    # this should always fail
    assert_raises(ValueError, lambda: c(77.0))
Beispiel #25
0
 def assert_provides_and_raises(pc, exception, target=None):
     """Helper to get all results before exception is raised"""
     results = []
     with assert_raises(exception):
         for r in pc:
             results.append(r)
     # results should be sorted since we do not guarantee order
     results = sorted(results)
     if target is not None:
         assert_equal(results, target)
     return results
Beispiel #26
0
def check_producing_consumer(jobs):
    def producer():
        yield from range(3)

    def consumer(i):
        yield i
        if isinstance(i, int):
            pc.add_to_producer_queue(str(i**2))

    # we auto-detect generator function producer
    pc = ProducerConsumer(producer, consumer, jobs=jobs)
    assert_equal(list(pc), [0, 1, 2, "0", "1", "4"])
Beispiel #27
0
def test_exit_code():
    # will relay actual exit code on CommandError
    cmd = ['datalad', 'sshrun', 'datalad-test', 'exit 42']
    with assert_raises(SystemExit) as cme:
        # running nosetests without -s
        if isinstance(sys.stdout, StringIO):  # pragma: no cover
            with swallow_outputs():  # need to give smth with .fileno ;)
                main(cmd)
        else:
            # to test both scenarios
            main(cmd)
    assert_equal(cme.value.code, 42)
Beispiel #28
0
def test_batched_close_ok():
    # Expect a long wait and no timeout if the process runs longer than timeout
    # seconds and the config for "datalad.runtime.stalled-external" has its
    # default value.
    bc = BatchedCommand(cmd=[sys.executable, "-i", "-u", "-q", "-"], timeout=2)
    # Send at least one instruction to start the subprocess
    response = bc("import time; print('a')")
    assert_equal(response, "a")
    bc.stdin_queue.put("time.sleep(.5); exit(3)\n".encode())
    bc.close(return_stderr=False)
    assert_true(bc.wait_timed_out is False)
    assert_equal(bc.return_code, 3)
Beispiel #29
0
def test_no_stdin_swallow(fname=None):
    # will relay actual exit code on CommandError
    cmd = ['datalad', 'sshrun', 'datalad-test', 'cat']

    out = WitlessRunner().run(cmd, stdin=open(fname), protocol=StdOutCapture)
    assert_equal(out['stdout'].rstrip(), '123magic')

    # test with -n switch now, which we could place even at the end
    out = WitlessRunner().run(cmd + ['-n'],
                              stdin=open(fname),
                              protocol=StdOutCapture)
    assert_equal(out['stdout'], '')
Beispiel #30
0
def test_global_config():

    # from within tests, global config should be read from faked $HOME (see
    # setup_package) or from GIT_CONFIG_GLOBAL

    if 'GIT_CONFIG_GLOBAL' in os.environ.keys():
        glb_cfg_file = Path(os.environ.get('GIT_CONFIG_GLOBAL'))
    else:
        glb_cfg_file = Path(os.path.expanduser('~')) / '.gitconfig'
    assert any(
        glb_cfg_file.samefile(Path(p)) for p in dl_cfg._stores['git']['files'])
    assert_equal(dl_cfg.get("user.name"), "DataLad Tester")
    assert_equal(dl_cfg.get("user.email"), "*****@*****.**")