Beispiel #1
0
def test_torrent(hash16, hash32):
    m = torf.Magnet(xt='urn:btih:' + hash16(b'some string'),
                    dn='foo', xl=1e6,
                    tr=('http://foo.bar/baz', 'http://asdf'),
                    ws=('http://x/y', 'http://z'))
    t = m.torrent()
    assert t.name == 'foo'
    assert t.size == 1e6
    assert t.trackers == [['http://foo.bar/baz'], ['http://asdf']]
    assert t.webseeds == ['http://x/y', 'http://z']
    assert t.infohash == hash16(b'some string')
    m = torf.Magnet(xt='urn:btih:' + hash32(b'some string'))
    assert m.torrent().infohash == hash16(b'some string')
    assert 'length' not in m.torrent().metainfo['info']
Beispiel #2
0
def test_getting_info__xs_times_out(generated_singlefile_torrent, monkeypatch):
    torrent = generated_singlefile_torrent
    total_timeout = 100
    now = 0.0
    mock_time_monotonic = mock.MagicMock(return_value=now)
    monkeypatch.setattr(time, 'monotonic', mock_time_monotonic)

    def timed_out_download(url, *args, **kwargs):
        # First download() call (xs) took almost all our available time
        mock_time_monotonic.return_value = now + total_timeout
        # Remove mock for second download() call (as)
        download_patch.stop()
        raise torf.ConnectionError(url, 'Timed out (mocked)')
    download_patch = mock.patch('torf._utils.download', timed_out_download)
    download_patch.start()

    magnet = torf.Magnet(torrent.infohash,
                         xs='http://xs.foo:123/torrent',
                         as_='http://as.foo:123/torrent')

    cb = mock.MagicMock()
    assert magnet.get_info(callback=cb, timeout=total_timeout) is False
    exp_calls = [mock.call(ComparableException(torf.ConnectionError('http://xs.foo:123/torrent', 'Timed out (mocked)'))),
                 mock.call(ComparableException(torf.ConnectionError('http://as.foo:123/torrent', 'Timed out')))]
    assert cb.call_args_list == exp_calls

    torrent_ = magnet.torrent()
    assert torrent_.metainfo['info'] == {}
Beispiel #3
0
def test_x(xt):
    m = torf.Magnet(xt, x_foo='asdf', x_bar=(1, 2, 3))
    assert m.x['foo'] == 'asdf'
    assert m.x['bar'] == (1, 2, 3)
    m.x['foo'] = '1234'
    assert m.x['foo'] == '1234'
    assert m.x['baz'] is None
Beispiel #4
0
def test_getting_info__xs_fails__as_succeeds(generated_singlefile_torrent, httpserver, monkeypatch):
    torrent = generated_singlefile_torrent
    total_timeout = 100
    now = 0.0
    mock_time_monotonic = mock.MagicMock(return_value=now)
    monkeypatch.setattr(time, 'monotonic', mock_time_monotonic)

    def timed_out_download(url, *args, **kwargs):
        # First download() call (xs) took almost all our available time
        mock_time_monotonic.return_value = now + total_timeout - 1
        # Remove mock for second download() call (as)
        download_patch.stop()
        raise torf.ConnectionError(url, 'Nope')
    download_patch = mock.patch('torf._utils.download', timed_out_download)
    download_patch.start()

    httpserver.expect_request('/as.torrent').respond_with_data(torrent.dump())
    magnet = torf.Magnet(torrent.infohash,
                         xs='http://xs.foo:123/torrent',
                         as_=httpserver.url_for('/as.torrent'))

    cb = mock.MagicMock()
    assert magnet.get_info(callback=cb, timeout=total_timeout) is True
    exp_calls = [mock.call(ComparableException(torf.ConnectionError('http://xs.foo:123/torrent', 'Nope')))]
    assert cb.call_args_list == exp_calls

    torrent_ = magnet.torrent()
    assert torrent_.metainfo['info'] == torrent.metainfo['info']
Beispiel #5
0
def test_kt(xt):
    m = torf.Magnet(xt, kt=('that', 'thing'))
    assert m.kt == ['that', 'thing']
    assert str(m) == f'magnet:?xt={xt}&kt=that,thing'
    m.kt = ('that', 'other', 'thing')
    assert m.kt == ['that', 'other', 'thing']
    assert str(m) == f'magnet:?xt={xt}&kt=that,other,thing'
Beispiel #6
0
def test_as(xt):
    m = torf.Magnet(xt, as_='http://foo.bar/baz.torrent')
    assert m.as_ == 'http://foo.bar/baz.torrent'
    assert str(m) == f'magnet:?xt={xt}&as_=http%3A%2F%2Ffoo.bar%2Fbaz.torrent'
    m.as_ = 'http://blim/blam.torrent'
    assert m.as_ == 'http://blim/blam.torrent'
    assert str(m) == f'magnet:?xt={xt}&as_=http%3A%2F%2Fblim%2Fblam.torrent'
    with pytest.raises(torf.URLError):
        m.as_ = 23
Beispiel #7
0
def test_xt_is_base32(hash32):
    xt = 'urn:btih:' + hash32(b'foo')
    m = torf.Magnet(xt)
    assert m.xt == xt
    assert m.infohash == hash32(b'foo')
    assert str(m) == f'magnet:?xt=urn:btih:{hash32(b"foo")}'
    m.infohash = hash32(b'bar')
    assert m.infohash == hash32(b'bar')
    assert str(m) == f'magnet:?xt=urn:btih:{hash32(b"bar")}'
Beispiel #8
0
def test_ws(xt):
    m = torf.Magnet(xt,
                    ws=['http://foo.bar/baz.jpg', 'http://bar.foo/baz.jpg'])
    assert m.ws == ['http://foo.bar/baz.jpg', 'http://bar.foo/baz.jpg']
    assert str(
        m
    ) == f'magnet:?xt={xt}&ws=http%3A%2F%2Ffoo.bar%2Fbaz.jpg&ws=http%3A%2F%2Fbar.foo%2Fbaz.jpg'
    m.ws.remove('http://foo.bar/baz.jpg')
    assert str(m) == f'magnet:?xt={xt}&ws=http%3A%2F%2Fbar.foo%2Fbaz.jpg'
Beispiel #9
0
def test_xs(xt):
    m = torf.Magnet(xt, xs='http://foo.bar/baz.torrent')
    assert m.xs == 'http://foo.bar/baz.torrent'
    assert str(m) == f'magnet:?xt={xt}&xs=http%3A%2F%2Ffoo.bar%2Fbaz.torrent'
    m.xs = 'http://blim/blam.torrent'
    assert m.xs == 'http://blim/blam.torrent'
    assert str(m) == f'magnet:?xt={xt}&xs=http%3A%2F%2Fblim%2Fblam.torrent'
    with pytest.raises(torf.URLError) as excinfo:
        m.xs = 23
Beispiel #10
0
def test_kt(xt):
    m = torf.Magnet(xt, kt=('that', 'thing'))
    assert m.kt == ['that', 'thing']
    assert str(m) == f'magnet:?xt={xt}&kt=that+thing'
    m.kt = ('that', 'other', 'thing')
    assert m.kt == ['that', 'other', 'thing']
    assert str(m) == f'magnet:?xt={xt}&kt=that+other+thing'
    with pytest.raises(torf.MagnetError) as excinfo:
        m.kt = 17
    assert str(excinfo.value) == '17: Invalid keyword topic ("kt")'
Beispiel #11
0
def test_setting_info_with_wrong_infohash(generated_singlefile_torrent, generated_multifile_torrent):
    magnet = torf.Magnet(generated_singlefile_torrent.infohash)

    with pytest.raises(torf.MetainfoError) as excinfo:
        magnet._set_info_from_torrent(generated_multifile_torrent.dump(), validate=True)
    assert str(excinfo.value) == ('Invalid metainfo: Mismatching info hashes: '
                                  f'{generated_singlefile_torrent.infohash} != {generated_multifile_torrent.infohash}')

    magnet._set_info_from_torrent(generated_multifile_torrent.dump(), validate=False)
    assert magnet._info == generated_multifile_torrent.metainfo['info']
Beispiel #12
0
def test_dn(xt):
    m = torf.Magnet(xt, dn='Héllo Wörld!')
    assert m.dn == 'Héllo Wörld!'
    assert str(m) == f'magnet:?xt={xt}&dn=H%C3%A9llo+W%C3%B6rld%21'
    m.dn = 'Göödbye World!'
    assert m.dn == 'Göödbye World!'
    assert str(m) == f'magnet:?xt={xt}&dn=G%C3%B6%C3%B6dbye+World%21'
    m.dn = (1, 2, 3)
    assert m.dn == '(1, 2, 3)'
    assert str(m) == f'magnet:?xt={xt}&dn=%281%2C+2%2C+3%29'
Beispiel #13
0
def test_reading_valid_magnet_URI_from_stdin(capsys, monkeypatch, clear_ansi, regex):
    magnet = torf.Magnet('7edbb76b446f87617393537fffa48af733cb4127', dn='Foo', xl=12345)
    r, w = os.pipe()
    monkeypatch.setattr(sys, 'stdin', os.fdopen(r))
    os.fdopen(w, 'wb').write(str(magnet).encode('utf-8'))

    run(['-i', '-'])
    cap = capsys.readouterr()
    assert clear_ansi(cap.out) == regex(r'^Name\tFoo$', flags=re.MULTILINE)
    assert clear_ansi(cap.out) == regex(r'^Size\t12345$', flags=re.MULTILINE)
    assert cap.err == ''
Beispiel #14
0
def test_tr(xt):
    m = torf.Magnet(xt, tr=('http://foo.bar/baz', ))
    assert m.tr == ['http://foo.bar/baz']
    assert str(m) == f'magnet:?xt={xt}&tr=http%3A%2F%2Ffoo.bar%2Fbaz'
    m.tr.append('http://blim/blam')
    assert m.tr == ['http://foo.bar/baz', 'http://blim/blam']
    assert str(
        m
    ) == f'magnet:?xt={xt}&tr=http%3A%2F%2Ffoo.bar%2Fbaz&tr=http%3A%2F%2Fblim%2Fblam'
    with pytest.raises(torf.URLError) as excinfo:
        m.tr = 'foo'
Beispiel #15
0
def test_getting_info_from_ws(generated_multifile_torrent, httpserver):
    torrent = generated_multifile_torrent
    magnet = torf.Magnet(torrent.infohash, ws=[httpserver.url_for('/bar//')])

    httpserver.expect_request('/bar.torrent').respond_with_data(torrent.dump())
    cb = mock.MagicMock()
    assert magnet.get_info(callback=cb) is True
    assert cb.call_args_list == []

    torrent_ = magnet.torrent()
    assert torrent_.metainfo['info'] == torrent.metainfo['info']
Beispiel #16
0
def test_getting_info__unsupported_protocol(generated_singlefile_torrent):
    torrent = generated_singlefile_torrent
    magnet = torf.Magnet(torrent.infohash, xs='asdf://xs.foo:123/torrent')

    cb = mock.MagicMock()
    assert magnet.get_info(callback=cb) is False
    exp_calls = [mock.call(ComparableException(torf.ConnectionError('asdf://xs.foo:123/torrent', 'Unsupported protocol')))]
    assert cb.call_args_list == exp_calls

    torrent_ = magnet.torrent()
    assert torrent_.metainfo['info'] == {}
Beispiel #17
0
def test_xl(xt):
    m = torf.Magnet(xt, xl=123)
    assert m.xl == 123
    assert str(m) == f'magnet:?xt={xt}&xl=123'
    m.xl = 456
    assert str(m) == f'magnet:?xt={xt}&xl=456'
    with pytest.raises(torf.MagnetError) as excinfo:
        m.xl = 'foo'
    assert str(excinfo.value) == 'foo: Invalid exact length ("xl")'
    with pytest.raises(torf.MagnetError) as excinfo:
        m.xl = -123
    assert str(excinfo.value) == '-123: Must be 1 or larger'
Beispiel #18
0
def test_getting_info_from_tr(generated_multifile_torrent, httpserver):
    torrent = generated_multifile_torrent
    magnet = torf.Magnet(torrent.infohash, tr=[httpserver.url_for('/announce')])

    infohash_enc = urllib.parse.quote_from_bytes(binascii.unhexlify(torrent.infohash))
    httpserver.expect_request('/file', query_string=f'info_hash={infohash_enc}').respond_with_data(torrent.dump())
    cb = mock.MagicMock()
    assert magnet.get_info(callback=cb) is True
    assert cb.call_args_list == []

    torrent_ = magnet.torrent()
    assert torrent_.metainfo['info'] == torrent.metainfo['info']
Beispiel #19
0
def test_getting_info__xs_succeeds__as_fails(generated_singlefile_torrent, httpserver):
    torrent = generated_singlefile_torrent
    magnet = torf.Magnet(torrent.infohash,
                         xs=httpserver.url_for('/torrent'), as_='http://as.foo:123/torrent')
    httpserver.expect_request('/torrent').respond_with_data(torrent.dump())

    cb = mock.MagicMock()
    assert magnet.get_info(callback=cb) is True
    assert cb.call_args_list == []

    torrent_ = magnet.torrent()
    assert torrent_.metainfo['info'] == torrent.metainfo['info']
Beispiel #20
0
def test_getting_info__xs_fails__as_fails(generated_singlefile_torrent):
    torrent = generated_singlefile_torrent
    magnet = torf.Magnet(torrent.infohash,
                         xs='http://xs.foo:123/torrent', as_='http://as.foo:123/torrent')

    cb = mock.MagicMock()
    assert magnet.get_info(callback=cb) is False
    exp_calls = [mock.call(ComparableException(torf.ConnectionError('http://xs.foo:123/torrent', 'Name or service not known'))),
                 mock.call(ComparableException(torf.ConnectionError('http://as.foo:123/torrent', 'Name or service not known')))]
    assert cb.call_args_list == exp_calls

    torrent_ = magnet.torrent()
    assert torrent_.metainfo['info'] == {}
Beispiel #21
0
def test_getting_info__as_returns_invalid_bytes(generated_singlefile_torrent, httpserver):
    torrent = generated_singlefile_torrent
    magnet = torf.Magnet(torrent.infohash,
                         xs='http://xs.foo:123/torrent', as_=httpserver.url_for('/torrent'))
    httpserver.expect_request('/torrent').respond_with_data(b'not bencoded bytes')

    cb = mock.MagicMock()
    assert magnet.get_info(callback=cb) is False
    exp_calls = [mock.call(ComparableException(torf.ConnectionError('http://xs.foo:123/torrent', 'Name or service not known'))),
                 mock.call(ComparableException(torf.BdecodeError()))]
    assert cb.call_args_list == exp_calls

    torrent_ = magnet.torrent()
    assert torrent_.metainfo['info'] == {}
Beispiel #22
0
def test_repr(xt):
    m = torf.Magnet(xt, dn='Foo', xl=123, tr=('http://tracker:123',),
                    xs='http://primary.source/url.torrent',
                    as_='http://alt.source/url.torrent',
                    ws=('http://webseed/url/file.content',),
                    kt=('keyword1', 'keyword2'),
                    x_foo='some', x_bar='junk')
    assert repr(m) == ("Magnet(xt='urn:btih:8867c88b56e0bfb82cffaf15a66bc8d107d6754a', "
                       "dn='Foo', xl=123, tr=['http://tracker:123'], "
                       "xs='http://primary.source/url.torrent', "
                       "as_='http://alt.source/url.torrent', "
                       "ws=['http://webseed/url/file.content'], "
                       "kt=['keyword1', 'keyword2'], "
                       "x_foo='some', x_bar='junk')")
Beispiel #23
0
def test_ws(xt):
    m = torf.Magnet(xt, ws=['http://foo.bar/baz.jpg',
                            'http://bar.foo/baz.jpg'])
    assert m.ws == ['http://foo.bar/baz.jpg',
                    'http://bar.foo/baz.jpg']
    with pytest.raises(torf.URLError):
        m.ws = ['foo']
    assert str(m) == f'magnet:?xt={xt}&ws=http%3A%2F%2Ffoo.bar%2Fbaz.jpg&ws=http%3A%2F%2Fbar.foo%2Fbaz.jpg'
    m.ws.remove('http://foo.bar/baz.jpg')
    assert str(m) == f'magnet:?xt={xt}&ws=http%3A%2F%2Fbar.foo%2Fbaz.jpg'
    m.ws = 'http://some/other/url/to/baz.jpg'
    assert m.ws == ['http://some/other/url/to/baz.jpg']
    with pytest.raises(torf.URLError):
        m.ws.replace(('adf',))
    assert m.ws == ['http://some/other/url/to/baz.jpg']
Beispiel #24
0
def test_xt_is_naked_infohash(hash16, hash32):
    for infohash in (hash16(b'foo'), hash32(b'foo')):
        m = torf.Magnet(infohash)
        assert m.xt == f'urn:btih:{infohash}'
Beispiel #25
0
def test_xt_invalid():
    with pytest.raises(torf.MagnetError) as excinfo:
        torf.Magnet('asdf')
    assert str(excinfo.value) == 'asdf: Invalid exact topic ("xt")'
Beispiel #26
0
def test_invalid_argument():
    with pytest.raises(TypeError):
        torf.Magnet(foo='bar')
Beispiel #27
0
def test_xt_missing():
    with pytest.raises(TypeError):
        torf.Magnet()