Ejemplo n.º 1
0
    def subtest_add_content_piece_length(self):
        """ Add a single file with piece length to a TorrentDef """
        t = TorrentDef()
        fn = os.path.join(TESTS_API_DIR, "video.avi")
        t.add_content(fn)
        t.set_piece_length(2**16)
        t.set_tracker(TRACKER)
        t.finalize()

        metainfo = t.get_metainfo()
        self.general_check(metainfo)
        self.assert_(metainfo['info']['piece length'] == 2**16)
Ejemplo n.º 2
0
    def subtest_add_content_piece_length(self):
        """ Add a single file with piece length to a TorrentDef """
        t = TorrentDef()
        fn = os.path.join(TESTS_API_DIR, "video.avi")
        t.add_content(fn)
        t.set_piece_length(2 ** 16)
        t.set_tracker(TRACKER)
        t.finalize()

        metainfo = t.get_metainfo()
        self.general_check(metainfo)
        self.assert_(metainfo['info']['piece length'] == 2 ** 16)
Ejemplo n.º 3
0
    def test_add_content_piece_length(self):
        """
        Add a single file with piece length to a TorrentDef
        """
        t = TorrentDef()
        fn = os.path.join(TESTS_DATA_DIR, VIDEO_FILE_NAME)
        t.add_content(fn)
        t.set_piece_length(2**16)
        t.save()

        metainfo = t.get_metainfo()
        self.assertEqual(metainfo['info']['piece length'], 2**16)
Ejemplo n.º 4
0
    def test_add_content_piece_length(self):
        """ Add a single file with piece length to a TorrentDef """
        t = TorrentDef()
        fn = os.path.join(TESTS_DATA_DIR, self.VIDEO_FILE_NAME)
        t.add_content(fn)
        t.set_piece_length(2 ** 16)
        t.set_tracker(TRACKER)
        t.finalize()

        metainfo = t.get_metainfo()
        self.general_check(metainfo)
        self.assertEqual(metainfo['info']['piece length'], 2 ** 16)
Ejemplo n.º 5
0
    def test_add_content_piece_length(self):
        """ Add a single file with piece length to a TorrentDef """
        t = TorrentDef()
        fn = os.path.join(TESTS_DATA_DIR, self.VIDEO_FILE_NAME)
        t.add_content(fn)
        t.set_piece_length(2**16)
        t.set_tracker(TRACKER)
        t.finalize()

        metainfo = t.get_metainfo()
        self.general_check(metainfo)
        self.assertEqual(metainfo['info']['piece length'], 2**16)
Ejemplo n.º 6
0
class TestVideoOnDemand(TestAsServer):

    """
    Testing Merkle hashpiece messages for both:
    * Merkle BEP style
    * old Tribler <= 4.5.2 that did not use the Extention protocol (BEP 10).

    See BitTornado/BT1/Connecter.py
    """

    @inlineCallbacks
    def setUp(self):
        yield TestAsServer.setUp(self)
        self.content = None
        self.tdef = None
        self.test_deferred = Deferred()
        self.contentlen = None
        self.piecelen = 0

    def setUpPreSession(self):
        TestAsServer.setUpPreSession(self)
        self.config.set_libtorrent_enabled(True)

    def create_torrent(self):
        [srchandle, sourcefn] = mkstemp()
        self.content = Rand.rand_bytes(self.contentlen)
        os.write(srchandle, self.content)
        os.close(srchandle)

        self.tdef = TorrentDef()
        self.tdef.add_content(sourcefn)
        self.tdef.set_piece_length(self.piecelen)
        self.tdef.set_tracker("http://127.0.0.1:12/announce")
        self.tdef.finalize()

        torrentfn = os.path.join(self.session.config.get_state_dir(), "gen.torrent")
        self.tdef.save(torrentfn)

        dscfg = DownloadStartupConfig()
        destdir = os.path.dirname(sourcefn)
        dscfg.set_dest_dir(destdir)
        dscfg.set_mode(DLMODE_VOD)

        download = self.session.start_download_from_tdef(self.tdef, dscfg)
        download.set_state_callback(self.state_callback)

        self.session.set_download_states_callback(self.states_callback)

    def states_callback(self, dslist):
        ds = dslist[0]
        d = ds.get_download()
        self._logger.debug('%s %s %5.2f%% %s up %8.2fKB/s down %8.2fKB/s',
                           d.get_def().get_name(),
                           dlstatus_strings[ds.get_status()],
                           ds.get_progress() * 100,
                           ds.get_error(),
                           ds.get_current_speed(UPLOAD),
                           ds.get_current_speed(DOWNLOAD))

        return []

    def state_callback(self, ds):
        download = ds.get_download()
        if ds.get_vod_prebuffering_progress() == 1.0:

            self._logger.debug("Test: state_callback")

            stream = VODFile(open(download.get_content_dest(), 'rb'), download)

            # Read last piece
            lastpieceoff = ((self.contentlen - 1) / self.piecelen) * self.piecelen
            lastpiecesize = self.contentlen - lastpieceoff
            self._logger.debug("stream: lastpieceoff %s %s", lastpieceoff, lastpiecesize)
            self.stream_read(stream, lastpieceoff, lastpiecesize, self.piecelen)

            # Read second,3rd,4th byte, only
            secoff = 1
            secsize = 3
            blocksize = 3
            self.stream_read(stream, secoff, secsize, blocksize)

            # Read last byte
            lastoff = self.contentlen - 1
            lastsize = 1
            self.stream_read(stream, lastoff, lastsize, self.piecelen)

            self.test_deferred.callback(None)

            return 0
        return 1.0

    def stream_read(self, stream, off, size, blocksize):
        stream.seek(off)
        data = stream.read(blocksize)
        self._logger.debug("stream: Got data %s", len(data))
        self.assertEquals(len(data), size)
        self.assertEquals(data, self.content[off:off + size])

    @trial_timeout(10)
    def test_99(self):
        self.contentlen = 99
        self.piecelen = 16
        self.create_torrent()

        self._logger.debug("Letting network thread create Download, sleeping")
        return self.test_deferred

    @trial_timeout(10)
    def test_100(self):
        self.contentlen = 100
        self.piecelen = 16
        self.create_torrent()

        self._logger.debug("Letting network thread create Download, sleeping")
        return self.test_deferred

    @trial_timeout(10)
    def test_101(self):
        self.contentlen = 101
        self.piecelen = 16
        self.create_torrent()

        self._logger.debug("Letting network thread create Download, sleeping")
        return self.test_deferred
Ejemplo n.º 7
0
class TestMetadata(TestAsServer, MagnetHelpers):
    """
    Once we are downloading a torrent, our client should respond to
    the ut_metadata extention message.  This allows other clients to
    obtain the info part of the metadata from us.
    """
    def setUp(self):
        """ override TestAsServer """
        TestAsServer.setUp(self)
        print >>sys.stderr,"test: Giving MyLaunchMany time to startup"
        time.sleep(5)
        print >>sys.stderr,"test: MyLaunchMany should have started up"

        # the metadata that we want to transfer
        self.tdef = TorrentDef()
        self.tdef.add_content(os.path.join(os.getcwd(), "API", "file.wmv"))
        self.tdef.set_tracker(self.session.get_internal_tracker_url())
        # we use a small piece length to obtain multiple pieces
        self.tdef.set_piece_length(1)
        self.tdef.finalize()
        # self.tdef.save(os.path.join(self.session.get_state_dir(), "gen.torrent"))

        MagnetHelpers.__init__(self, self.tdef)

    def setup_seeder(self):
        self.seeder_setup_complete = False
        self.seeder_teardown_complete = False
        self.seeder_teardown = False

        self.dscfg = DownloadStartupConfig()
        self.dscfg.set_dest_dir(os.getcwd())
        self.download = self.session.start_download(self.tdef, self.dscfg)
        self.download.set_state_callback(self.seeder_state_callback)

        counter = 0
        while not self.seeder_setup_complete:
            counter += 1
            time.sleep(1)
            assert counter < 30, "timeout"

        print >> sys.stderr, "test: setup_seeder() complete"

    def teardown_seeder(self):
        self.seeder_teardown_complete = False
        self.session.remove_download(self.download)

        counter = 0
        while not self.seeder_setup_complete:
            counter += 1
            time.sleep(1)
            assert counter < 30, "timeout"

        print >> sys.stderr, "test: teardown_seeder() complete"

    def seeder_state_callback(self,ds):
        assert not self.seeder_teardown_complete
        self.seeder_setup_complete = (ds.get_status() == DLSTATUS_DOWNLOADING)
        d = ds.get_download()
        print >> sys.stderr, "test: seeder:", `d.get_def().get_name()`, dlstatus_strings[ds.get_status()], ds.get_progress()
        if self.seeder_teardown:
            self.seeder_teardown_complete = True
        else:
            return (1.0, False)

    def test_all(self):
        self.setup_seeder()
        try:
            self.subtest_good_flood()
        finally:
            self.teardown_seeder()

        self.setup_seeder()
        try:
            self.subtest_good_request()
            self.subtest_bad_request()
        finally:
            self.teardown_seeder()

    def subtest_good_request(self):
        conn = BTConnection("localhost", self.hisport, user_infohash=self.tdef.get_infohash())
        conn.send(self.create_good_extend_handshake())
        conn.read_handshake_medium_rare()
        metadata_id = self.read_extend_handshake(conn)

        # request metadata block 0, 2, 3, and the last
        conn.send(self.create_good_extend_metadata_request(metadata_id, 0))
        conn.send(self.create_good_extend_metadata_request(metadata_id, 2))
        conn.send(self.create_good_extend_metadata_request(metadata_id, 3))
        conn.send(self.create_good_extend_metadata_request(metadata_id, len(self.metadata_list) - 1))

        self.read_extend_metadata_reply(conn, 0)
        self.read_extend_metadata_reply(conn, 2)
        self.read_extend_metadata_reply(conn, 3)
        self.read_extend_metadata_reply(conn, len(self.metadata_list) - 1)

    def subtest_good_flood(self):
        conn = BTConnection("localhost", self.hisport, user_infohash=self.tdef.get_infohash())
        conn.send(self.create_good_extend_handshake())
        conn.read_handshake_medium_rare()
        metadata_id = self.read_extend_handshake(conn)

        for counter in xrange(len(self.metadata_list) * 2):
            piece = counter % len(self.metadata_list)
            conn.send(self.create_good_extend_metadata_request(metadata_id, piece))

            if counter > len(self.metadata_list):
                self.read_extend_metadata_reject(conn, piece)
            else:
                self.read_extend_metadata_reply(conn, piece)

    def subtest_bad_request(self):
        self.bad_request_and_disconnect({"msg_type":0, "piece":len(self.metadata_list)})
        self.bad_request_and_disconnect({"msg_type":0, "piece":-1})
        self.bad_request_and_disconnect({"msg_type":0, "piece":"1"})
        self.bad_request_and_disconnect({"msg_type":0, "piece":[1,2]})
        self.bad_request_and_disconnect({"msg_type":0, "PIECE":1})

    def bad_request_and_disconnect(self, payload):
        conn = BTConnection("localhost", self.hisport, user_infohash=self.tdef.get_infohash())
        conn.send(self.create_good_extend_handshake())
        conn.read_handshake_medium_rare()
        metadata_id = self.read_extend_handshake(conn)

        conn.send(EXTEND + chr(metadata_id) + bencode(payload))
        self.read_extend_metadata_close(conn)
Ejemplo n.º 8
0
 def test_set_piece_length_invalid_type(self):
     t = TorrentDef()
     t.set_piece_length("20")
Ejemplo n.º 9
0
    def setUpPostSession(self):
        """ override TestAsServer """
        TestAsServer.setUpPostSession(self)

        # Let Tribler start downloading an non-functioning torrent, so
        # we can talk to a normal download engine.
        self.tdef = TorrentDef()
        self.sourcefn = os.path.join(os.getcwd(), "API", "file2.wmv")
        self.tdef.add_content(self.sourcefn)
        self.tdef.set_create_merkle_torrent(True)
        self.tdef.set_tracker("http://127.0.0.1:12/announce")
        self.tdef.finalize()

        self.torrentfn = os.path.join(self.session.get_state_dir(), "gen.torrent")
        self.tdef.save(self.torrentfn)

        dscfg = self.setUpDownloadConfig()

        self.session.start_download(self.tdef, dscfg)

        self.infohash = self.tdef.get_infohash()
        self.mylistenport = 4810

        self.numpieces = (self.tdef.get_length() + self.tdef.get_piece_length() - 1) / self.tdef.get_piece_length()
        b = Bitfield(self.numpieces)
        for i in range(self.numpieces):
            b[i] = True
        self.assert_(b.complete())
        self.seederbitfieldstr = b.tostring()

        # piece_hashes = ['\x01\x02\x03\x04\x05\x06\x07\x08\x07\x06\x05\x04\x03\x02\x01\x00\x01\x02\x03\x04' ] * npieces
        # Construct Merkle tree
        tdef2 = TorrentDef()
        tdef2.add_content(self.sourcefn)
        tdef2.set_create_merkle_torrent(False)
        tdef2.set_tracker("http://127.0.0.1:12/announce")
        tdef2.set_piece_length(self.tdef.get_piece_length())
        tdef2.finalize()
        metainfo = tdef2.get_metainfo()

        piecesstr = metainfo['info']['pieces']
        print >> sys.stderr, "test: pieces has len", len(piecesstr)
        piece_hashes = []
        for i in range(0, len(piecesstr), 20):
            hash = piecesstr[i:i + 20]
            print >> sys.stderr, "test: piece", i / 20, "hash", repr(hash)
            piece_hashes.append(hash)

        print >> sys.stderr, "test: Putting", len(piece_hashes), "into MerkleTree, size", self.tdef.get_piece_length(), tdef2.get_piece_length()

        self.tree = MerkleTree(self.tdef.get_piece_length(), self.tdef.get_length(), None, piece_hashes)

        f = open(self.sourcefn, "rb")
        piece1 = f.read(2 ** 18)
        piece2 = f.read(2 ** 18)
        print >> sys.stderr, "read piece1", len(piece1)
        print >> sys.stderr, "read piece2", len(piece2)
        f.close()
        hash1 = sha(piece1).digest()
        hash2 = sha(piece2).digest()
        print >> sys.stderr, "hash piece1", repr(hash1)
        print >> sys.stderr, "hash piece2", repr(hash2)
        f2 = open("piece1.bin", "wb")
        f2.write(piece2)
        f2.close()
Ejemplo n.º 10
0
class TestMagnetFakePeer(TestAsServer, MagnetHelpers):
    """
    A MiniBitTorrent instance is used to connect to BitTorrent clients
    and download the info part from the metadata.
    """
    def setUp(self):
        # listener for incoming connections from MiniBitTorrent
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.bind(("", self.session.get_listen_port()))
        self.server.listen(5)

        TestAsServer.setUp(self)

        # the metadata that we want to transfer
        self.tdef = TorrentDef()
        self.tdef.add_content(os.path.join(TESTS_API_DIR, "video.avi"))
        self.tdef.set_tracker("http://fake.net/announce")
        # we use a small piece length to obtain multiple pieces
        self.tdef.set_piece_length(1)
        self.tdef.finalize()

        MagnetHelpers.__init__(self, self.tdef)

    def setUpPreSession(self):
        TestAsServer.setUpPreSession(self)
        self.config.set_libtorrent(True)

    def create_good_url(self, infohash=None, title=None, tracker=None):
        url = "magnet:?xt=urn:btih:"
        if infohash:
            assert isinstance(infohash, str)
            url += hexlify(infohash)
        else:
            url += hexlify(self.tdef.get_infohash())
        if title:
            assert isinstance(title, str)
            url += "&dn=" + title
        if tracker:
            assert isinstance(tracker, str)
            url += "&tr=" + tracker
        return url

    @skip("not working, seems to return binary data")
    def test_good_transfer(self):
        def torrentdef_retrieved(meta_info):
            tags["metainfo"] = meta_info
            tags["retrieved"].set()

        tags = {"retrieved": threading.Event()}

        self.session.lm.ltmgr.get_metainfo(self.create_good_url(),
                                           torrentdef_retrieved,
                                           timeout=60)

        def do_supply():
            # supply fake addresses (regular dht obviously wont work here)
            ltmgr = LibtorrentMgr.getInstance()
            for infohash in ltmgr.metainfo_requests:
                handle = ltmgr.ltsession.find_torrent(
                    lt.big_number(infohash.decode('hex')))
                handle.connect_peer(
                    ("127.0.0.1", self.session.get_listen_port()), 0)

        self.session.lm.threadpool.add_task(do_supply, delay=5.0)

        # accept incoming connection
        # self.server.settimeout(10.0)
        sock, address = self.server.accept()
        assert sock, "No incoming connection"

        # handshakes
        conn = BTConnection(address[0],
                            address[1],
                            opensock=sock,
                            user_infohash=self.tdef.get_infohash())
        conn.send(self.create_good_extend_handshake())
        conn.read_handshake_medium_rare()
        metadata_id = self.read_extend_handshake(conn)

        # serve pieces
        for counter in xrange(len(self.metadata_list)):
            piece = self.read_extend_metadata_request(conn)
            assert 0 <= piece < len(self.metadata_list)
            conn.send(
                self.create_good_extend_metadata_reply(metadata_id, piece))

        # no more metadata request may be send and the connection must
        # be closed
        self.read_extend_metadata_close(conn)

        assert tags["retrieved"].wait(5)
        assert tags["metainfo"]["info"] == self.tdef.get_metainfo()["info"]
Ejemplo n.º 11
0
class TestVideoOnDemand(TestAsServer):
    """
    Testing Merkle hashpiece messages for both:
    * Merkle BEP style
    * old Tribler <= 4.5.2 that did not use the Extention protocol (BEP 10).

    See BitTornado/BT1/Connecter.py
    """
    @blocking_call_on_reactor_thread
    @inlineCallbacks
    def setUp(self, autoload_discovery=True):
        yield TestAsServer.setUp(self, autoload_discovery=autoload_discovery)
        self.content = None
        self.tdef = None
        self.test_deferred = Deferred()
        self.contentlen = None
        self.piecelen = 0

    def setUpPreSession(self):
        TestAsServer.setUpPreSession(self)
        self.config.set_libtorrent_enabled(True)

    def create_torrent(self):
        [srchandle, sourcefn] = mkstemp()
        self.content = Rand.rand_bytes(self.contentlen)
        os.write(srchandle, self.content)
        os.close(srchandle)

        self.tdef = TorrentDef()
        self.tdef.add_content(sourcefn)
        self.tdef.set_piece_length(self.piecelen)
        self.tdef.set_tracker("http://127.0.0.1:12/announce")
        self.tdef.finalize()

        torrentfn = os.path.join(self.session.config.get_state_dir(),
                                 "gen.torrent")
        self.tdef.save(torrentfn)

        dscfg = DownloadStartupConfig()
        destdir = os.path.dirname(sourcefn)
        dscfg.set_dest_dir(destdir)
        dscfg.set_mode(DLMODE_VOD)

        download = self.session.start_download_from_tdef(self.tdef, dscfg)
        download.set_state_callback(self.state_callback)

        self.session.set_download_states_callback(self.states_callback)

    def states_callback(self, dslist):
        ds = dslist[0]
        d = ds.get_download()
        self._logger.debug('%s %s %5.2f%% %s up %8.2fKB/s down %8.2fKB/s',
                           d.get_def().get_name(),
                           dlstatus_strings[ds.get_status()],
                           ds.get_progress() * 100, ds.get_error(),
                           ds.get_current_speed(UPLOAD),
                           ds.get_current_speed(DOWNLOAD))

        return []

    def state_callback(self, ds):
        download = ds.get_download()
        if ds.get_vod_prebuffering_progress() == 1.0:

            self._logger.debug("Test: state_callback")

            stream = VODFile(open(download.get_content_dest(), 'rb'), download)

            # Read last piece
            lastpieceoff = (
                (self.contentlen - 1) / self.piecelen) * self.piecelen
            lastpiecesize = self.contentlen - lastpieceoff
            self._logger.debug("stream: lastpieceoff %s %s", lastpieceoff,
                               lastpiecesize)
            self.stream_read(stream, lastpieceoff, lastpiecesize,
                             self.piecelen)

            # Read second,3rd,4th byte, only
            secoff = 1
            secsize = 3
            blocksize = 3
            self.stream_read(stream, secoff, secsize, blocksize)

            # Read last byte
            lastoff = self.contentlen - 1
            lastsize = 1
            self.stream_read(stream, lastoff, lastsize, self.piecelen)

            self.test_deferred.callback(None)

            return 0
        return 1.0

    def stream_read(self, stream, off, size, blocksize):
        stream.seek(off)
        data = stream.read(blocksize)
        self._logger.debug("stream: Got data %s", len(data))
        self.assertEquals(len(data), size)
        self.assertEquals(data, self.content[off:off + size])

    @deferred(timeout=10)
    def test_99(self):
        self.contentlen = 99
        self.piecelen = 16
        self.create_torrent()

        self._logger.debug("Letting network thread create Download, sleeping")
        return self.test_deferred

    @deferred(timeout=10)
    def test_100(self):
        self.contentlen = 100
        self.piecelen = 16
        self.create_torrent()

        self._logger.debug("Letting network thread create Download, sleeping")
        return self.test_deferred

    @deferred(timeout=10)
    def test_101(self):
        self.contentlen = 101
        self.piecelen = 16
        self.create_torrent()

        self._logger.debug("Letting network thread create Download, sleeping")
        return self.test_deferred
Ejemplo n.º 12
0
def make_meta_file(srcpaths, params, userabortflag, progressCallback, torrentfilenameCallback):
    tdef = TorrentDef()

    basedir = None
    if len(srcpaths) > 1:
        basepath = []
        for srcpath in srcpaths:
            path, filename = os.path.split(srcpath)
            basepath.append(path)

        basepath, basedir = os.path.split(os.path.commonprefix(basepath))
        for srcpath in srcpaths:
            outpath = os.path.relpath(srcpath, basepath)

            # h4x0r playtime
            if "playtime" in params:
                tdef.add_content(srcpath, outpath, playtime=params["playtime"])
            else:
                tdef.add_content(srcpath, outpath)
    else:
        srcpath = srcpaths[0]
        basepath, _ = os.path.split(srcpath)
        if "playtime" in params:
            tdef.add_content(srcpath, playtime=params["playtime"])
        else:
            tdef.add_content(srcpath)

    if params["name"]:
        tdef.set_name(params["name"])
    if params["comment"]:
        tdef.set_comment(params["comment"])
    if params["created by"]:
        tdef.set_created_by(params["created by"])
    if params["announce"]:
        tdef.set_tracker(params["announce"])
    if params["announce-list"]:
        tdef.set_tracker_hierarchy(params["announce-list"])
    if params["nodes"]:  # mainline DHT
        tdef.set_dht_nodesmax(params["nodes"])
    if params["httpseeds"]:
        tdef.set_httpseeds(params["httpseeds"])
    if params["encoding"]:
        tdef.set_encoding(params["encoding"])
    if params["piece length"]:
        tdef.set_piece_length(params["piece length"])
    if params["makehash_md5"]:
        print >>sys.stderr, "TorrentMaker: make MD5"
        tdef.set_add_md5hash(params["makehash_md5"])
    if params["makehash_crc32"]:
        print >>sys.stderr, "TorrentMaker: make CRC32"
        tdef.set_add_crc32(params["makehash_crc32"])
    if params["makehash_sha1"]:
        print >>sys.stderr, "TorrentMaker: make SHA1"
        tdef.set_add_sha1hash(params["makehash_sha1"])
    if params["createmerkletorrent"]:
        tdef.set_create_merkle_torrent(params["createmerkletorrent"])
    if params["torrentsigkeypairfilename"]:
        tdef.set_signature_keypair_filename(params["torrentsigkeypairfilename"])
    if params["thumb"]:
        tdef.set_thumbnail(params["thumb"])

    tdef.finalize(userabortflag=userabortflag, userprogresscallback=progressCallback)

    if params["createmerkletorrent"]:
        postfix = TRIBLER_TORRENT_EXT
    else:
        postfix = ".torrent"

    if params.get("target", False):
        torrentfilename = os.path.join(params["target"], os.path.split(os.path.normpath(srcpath))[1] + postfix)
    else:
        torrentfilename = os.path.join(basepath, tdef.get_name() + postfix)
    tdef.save(torrentfilename)

    # Inform higher layer we created torrent
    torrentfilenameCallback(basepath, basedir, torrentfilename)
class TestQueryReplyActive(TestAsServer):

    """
    Testing QUERY_REPLY message of Query extension V1

    This test checks how the Tribler code responds to good and bad
    QUERY_REPLY messages. I.e. the Tribler client initiates
    the dialback by connecting to us and sending a QUERY and we
    reply with good and bad messages.

    This test allows authoritative answers from superpeers.

    WARNING: Each of the test_ methods should be tested by running the TestCase
    in a separate Python interpreter to prevent problems with our singleton
    classes, e.g. SuperPeerDB, etc.
    """

    def setUpPreSession(self):
        """ override TestAsServer """
        print >> sys.stderr,"test: Pre Tribler Init"
        TestAsServer.setUpPreSession(self)
        print >> sys.stderr,"test: Pre Tribler Init: config_path",self.config_path
        # Enable remote querying
        self.config.set_remote_query(True)

    def setUpPostSession(self):
        """ override TestAsServer """
        TestAsServer.setUpPostSession(self)
        self.hispermid = str(self.his_keypair.pub().get_der())
        self.my_permid = str(self.my_keypair.pub().get_der())

    def pretest_simple(self,keyword):
        self.pretest_q('SIMPLE',keyword)

    def pretest_simpleplustorrents(self,keyword):
        self.pretest_q('SIMPLE+METADATA',keyword)

    def pretest_q(self,queryprefix,keyword):

        query = queryprefix+' '+keyword

        self.content_name = keyword.upper()+' S22E44'
        self.tdef = TorrentDef()
        self.tdef.set_tracker('http://localhost:0/announce')
        self.tdef.set_piece_length(2 ** 15)
        self.tdef.create_live(self.content_name,2 ** 16)
        self.tdef.finalize()

        # 1. First connect to Tribler
        self.openconn = OLConnection(self.my_keypair,'localhost',self.hisport)
        sleep(3)

        # 2. Make Tribler send query
        self.query = query
        self.session.query_connected_peers(query,self.query_usercallback,max_peers_to_query=10)

    def query_usercallback(self,permid,query,hits):

        print >>sys.stderr,"test: query_usercallback:",`permid`,`query`,`hits`

        self.assert_(query == self.query)
        self.assert_(permid == self.my_permid)
        self.check_good_qreply(hits)

        # TODO: if SIMPLE+METADATA: check torrent now in db.


    #
    # Good SIMPLE QUERY, builds on TestQueryReply code
    #
    def singtest_good_simple_reply(self):
        self.pretest_simple('hallo')
        self._test_qreply(self.create_good_simple_reply,True)

    #
    # Good SIMPLE+METADATA QUERY, builds on TestQueryReply code
    #
    def singtest_good_simpleplustorrents_reply(self):
        self.pretest_simpleplustorrents('hallo')
        self._test_qreply(self.create_good_simpleplustorrents_reply,True)


    #
    # Good SIMPLE QUERY Unicode, builds on TestQueryReply code
    #
    def singtest_good_simple_reply_unicode(self):
        self.pretest_simple(u'Ch\u00e8rie')
        self._test_qreply(self.create_good_simple_reply,True)

    #
    # Good SIMPLE+METADATA QUERY Unicode, builds on TestQueryReply code
    #
    def singtest_good_simpleplustorrents_reply_unicode(self):
        self.pretest_simpleplustorrents(u'Ch\u00e8rie')
        self._test_qreply(self.create_good_simpleplustorrents_reply,True)


    #
    # Bad QUERY, builds on TestQueryReply code
    #
    def singtest_bad_not_bdecodable(self):
        self.pretest_simple('hallo')
        self._test_qreply(self.create_not_bdecodable,False)

    #
    # Bad SIMPLE+METADATA QUERY, builds on TestQueryReply code
    #
    def singtest_bad_not_bdecodable_torrentfile(self):
        self.pretest_simpleplustorrents('hallo')
        self._test_qreply(self.create_not_bdecodable_torrentfile,False)


    ### TODO: send different valid answers so consensus not reached

    #
    # Main test code
    #
    def _test_qreply(self,gen_qreply,good):
        print >> sys.stderr,"test: waiting for reply"
        s = self.openconn

        msg = s.recv()
        self.assert_(len(msg) > 0)
        print >> sys.stderr,"test: Received overlay message",getMessageName(msg[0])
        self.assert_(msg[0] == QUERY)
        id = self.check_rquery(msg[1:])

        resp = gen_qreply(id)
        print >> sys.stderr,"test: sending QUERY_REPLY"
        s.send(resp)
        if good:
            time.sleep(10)
            # the other side should not have closed the connection, as
            # this is all valid, so this should not throw an exception:
            s.send('bla')
            s.close()
        else:
            # the other side should not like this and close the connection
            self.assert_(len(s.recv())==0)
            s.close()


    def create_good_simple_reply_dict(self,id):
        r = {}
        r['content_name'] = self.content_name.encode("UTF-8")
        r['length'] = LENGTH
        r['leecher'] = LEECHERS
        r['seeder'] = SEEDERS
        r['category'] = CATEGORY
        # OLPROTO_PROTO_ELEVENTH
        # set later r['torrent_size'] = 42
        r['channel_permid'] = '$' * 83
        r['channel_name'] = 'Nitin Channel'

        d2 = {}
        d2[self.tdef.get_infohash()] = r

        d = {}
        d['id'] = id
        d['a'] = d2
        return d

    def create_good_simple_reply(self,id):
        d = self.create_good_simple_reply_dict(id)
        bmetainfo = bencode(self.tdef.get_metainfo())
        d['a'][self.tdef.get_infohash()]['torrent_size'] = len(bmetainfo)
        b = bencode(d)
        return QUERY_REPLY+b

    def create_good_simpleplustorrents_reply(self,id):
        d = self.create_good_simple_reply_dict(id)
        bmetainfo = bencode(self.tdef.get_metainfo())
        d['a'][self.tdef.get_infohash()]['torrent_size'] = len(bmetainfo)
        d['a'][self.tdef.get_infohash()]['metatype'] = 'application/x-tribler-stream'
        d['a'][self.tdef.get_infohash()]['metadata'] = bmetainfo
        b = bencode(d)
        return QUERY_REPLY+b



    def check_good_qreply(self,hits):
        self.assert_(len(hits) == 1)
        self.assert_(hits.keys()[0] == self.tdef.get_infohash())
        hit = hits[self.tdef.get_infohash()]
        self.assert_(hit['content_name'] == self.content_name)
        self.assert_(hit['length'] == LENGTH)
        self.assert_(hit['leecher'] == LEECHERS)
        self.assert_(hit['seeder'] == SEEDERS)
        self.assert_(hit['category'] ==  CATEGORY)

        # OLPROTO_VERSION_ELEVENTH
        bmetainfo = bencode(self.tdef.get_metainfo())
        self.assert_(hit['torrent_size'] == len(bmetainfo))
        if self.query.startswith('SIMPLE+METADATA'):
            self.assert_(hit['metadata'] == bmetainfo)

    def create_not_bdecodable(self,id):
        return QUERY_REPLY+"bla"

    def create_not_bdecodable_torrentfile(self,id):
        d = self.create_good_simple_reply_dict(id)
        d['a'][self.tdef.get_infohash()]['torrent_size'] = 3 # consistent with metadata. Should be named "metasize"
        d['a'][self.tdef.get_infohash()]['metadata'] = 'bla'
        b = bencode(d)
        return QUERY_REPLY+b

    def check_rquery(self,data):
        d = bdecode(data)
        self.assert_(type(d) == DictType)
        self.assert_(d.has_key('q'))
        q = d['q']
        self.assert_(type(q) == StringType)
        self.assert_(d.has_key('id'))
        id = d['id']
        self.assert_(type(id) == StringType)

        self.assert_(q == self.query.encode("UTF-8"))
        return d['id']
Ejemplo n.º 14
0
 def test_set_piece_length_invalid_type(self):
     t = TorrentDef()
     t.set_piece_length("20")
Ejemplo n.º 15
0
class TestVideoOnDemand(TestAsServer):
    """
    Testing Merkle hashpiece messages for both:
    * Merkle BEP style
    * old Tribler <= 4.5.2 that did not use the Extention protocol (BEP 10).

    See BitTornado/BT1/Connecter.py
    """
    def setUp(self):
        """ override TestAsServer """
        TestAsServer.setUp(self)
        self.vodstarted = False

    def setUpPreSession(self):
        TestAsServer.setUpPreSession(self)
        self.config.set_libtorrent(True)

    def create_torrent(self):
        [srchandle, self.sourcefn] = mkstemp()
        self.content = Rand.rand_bytes(self.contentlen)
        os.write(srchandle, self.content)
        os.close(srchandle)

        self.tdef = TorrentDef()
        self.tdef.add_content(self.sourcefn)
        self.tdef.set_piece_length(self.piecelen)
        self.tdef.set_tracker("http://127.0.0.1:12/announce")
        self.tdef.finalize()

        self.torrentfn = os.path.join(self.session.get_state_dir(),
                                      "gen.torrent")
        self.tdef.save(self.torrentfn)

        dscfg = DownloadStartupConfig()
        destdir = os.path.dirname(self.sourcefn)
        dscfg.set_dest_dir(destdir)
        dscfg.set_video_event_callback(self.sesscb_vod_event_callback)

        self.session.set_download_states_callback(self.states_callback)
        self.session.start_download(self.tdef, dscfg)

    def states_callback(self, dslist):
        ds = dslist[0]
        d = ds.get_download()
        #    print >>sys.stderr,`d.get_def().get_name()`,dlstatus_strings[ds.get_status()],ds.get_progress(),"%",ds.get_error(),"up",ds.get_current_speed(UPLOAD),"down",ds.get_current_speed(DOWNLOAD)
        print >> sys.stderr, '%s %s %5.2f%% %s up %8.2fKB/s down %8.2fKB/s' % \
            (d.get_def().get_name(),
                dlstatus_strings[ds.get_status()],
                ds.get_progress() * 100,
                ds.get_error(),
                ds.get_current_speed(UPLOAD),
                ds.get_current_speed(DOWNLOAD))

        return (1.0, [])

    def sesscb_vod_event_callback(self, d, event, params):
        if self.vodstarted:
            return
        self.vodstarted = True

        print >> sys.stderr, "Test: vod_event_callback", event, params
        if event == VODEVENT_START:
            stream = params['stream']

            # Read last piece
            lastpieceoff = (
                (self.contentlen - 1) / self.piecelen) * self.piecelen
            lastpiecesize = self.contentlen - lastpieceoff
            print >> sys.stderr, "Test: stream: lastpieceoff", lastpieceoff, lastpiecesize
            self.stream_read(stream, lastpieceoff, lastpiecesize,
                             self.piecelen)

            # Read second,3rd,4th byte, only
            secoff = 1
            secsize = 3
            blocksize = 3
            self.stream_read(stream, secoff, secsize, blocksize)

            # Read last byte
            lastoff = self.contentlen - 1
            lastsize = 1
            self.stream_read(stream, lastoff, lastsize, self.piecelen)

    def stream_read(self, stream, off, size, blocksize):
        stream.seek(off)
        data = stream.read(blocksize)
        print >> sys.stderr, "Test: stream: Got data", len(data)
        self.assertEquals(len(data), size)
        self.assertEquals(data, self.content[off:off + size])

    def test_99(self):
        self.contentlen = 99
        self.piecelen = 10
        self.create_torrent()

        print >> sys.stderr, "Test: Letting network thread create Download, sleeping"
        time.sleep(5)

        dlist = self.session.get_downloads()
        d = dlist[0]
        vs = d.get_vod_info()['status']

        if vs:
            goodrange = ((0, 0), (9, 8))
            self.assertEqual(vs.movie_range, goodrange)
            self.assertEqual(vs.first_piecelen, 10)
            self.assertEqual(vs.last_piecelen, 9)
            self.assertEqual(vs.first_piece, 0)
            self.assertEqual(vs.last_piece, 9)
            self.assertEqual(vs.movie_numpieces, 10)

    def test_100(self):
        self.contentlen = 100
        self.piecelen = 10
        self.create_torrent()

        print >> sys.stderr, "Test: Letting network thread create Download, sleeping"
        time.sleep(5)

        dlist = self.session.get_downloads()
        d = dlist[0]
        vs = d.get_vod_info()['status']

        if vs:
            goodrange = ((0, 0), (9, 9))
            self.assertEqual(vs.movie_range, goodrange)
            self.assertEqual(vs.first_piecelen, 10)
            self.assertEqual(vs.last_piecelen, 10)
            self.assertEqual(vs.first_piece, 0)
            self.assertEqual(vs.last_piece, 9)
            self.assertEqual(vs.movie_numpieces, 10)

    def test_101(self):
        self.contentlen = 101
        self.piecelen = 10
        self.create_torrent()

        print >> sys.stderr, "Test: Letting network thread create Download, sleeping"
        time.sleep(5)

        dlist = self.session.get_downloads()
        d = dlist[0]
        vs = d.get_vod_info()['status']

        if vs:
            goodrange = ((0, 0), (10, 0))
            self.assertEqual(vs.movie_range, goodrange)
            self.assertEqual(vs.first_piecelen, 10)
            self.assertEqual(vs.last_piecelen, 1)
            self.assertEqual(vs.first_piece, 0)
            self.assertEqual(vs.last_piece, 10)
            self.assertEqual(vs.movie_numpieces, 11)
Ejemplo n.º 16
0
    def setUpPostSession(self):
        """ override TestAsServer """
        TestAsServer.setUpPostSession(self)

        # Let Tribler start downloading an non-functioning torrent, so
        # we can talk to a normal download engine.
        self.tdef = TorrentDef()
        self.sourcefn = os.path.join(os.getcwd(), "API", "file2.wmv")
        self.tdef.add_content(self.sourcefn)
        self.tdef.set_create_merkle_torrent(True)
        self.tdef.set_tracker("http://127.0.0.1:12/announce")
        self.tdef.finalize()

        self.torrentfn = os.path.join(self.session.get_state_dir(), "gen.torrent")
        self.tdef.save(self.torrentfn)

        dscfg = self.setUpDownloadConfig()

        self.session.start_download(self.tdef, dscfg)

        self.infohash = self.tdef.get_infohash()
        self.mylistenport = 4810

        self.numpieces = (self.tdef.get_length() + self.tdef.get_piece_length() - 1) / self.tdef.get_piece_length()
        b = Bitfield(self.numpieces)
        for i in range(self.numpieces):
            b[i] = True
        self.assert_(b.complete())
        self.seederbitfieldstr = b.tostring()

        # piece_hashes = ['\x01\x02\x03\x04\x05\x06\x07\x08\x07\x06\x05\x04\x03\x02\x01\x00\x01\x02\x03\x04' ] * npieces
        # Construct Merkle tree
        tdef2 = TorrentDef()
        tdef2.add_content(self.sourcefn)
        tdef2.set_create_merkle_torrent(False)
        tdef2.set_tracker("http://127.0.0.1:12/announce")
        tdef2.set_piece_length(self.tdef.get_piece_length())
        tdef2.finalize()
        metainfo = tdef2.get_metainfo()

        piecesstr = metainfo["info"]["pieces"]
        print >> sys.stderr, "test: pieces has len", len(piecesstr)
        piece_hashes = []
        for i in range(0, len(piecesstr), 20):
            hash = piecesstr[i : i + 20]
            print >> sys.stderr, "test: piece", i / 20, "hash", repr(hash)
            piece_hashes.append(hash)

        print >> sys.stderr, "test: Putting", len(
            piece_hashes
        ), "into MerkleTree, size", self.tdef.get_piece_length(), tdef2.get_piece_length()

        self.tree = MerkleTree(self.tdef.get_piece_length(), self.tdef.get_length(), None, piece_hashes)

        f = open(self.sourcefn, "rb")
        piece1 = f.read(2 ** 18)
        piece2 = f.read(2 ** 18)
        print >> sys.stderr, "read piece1", len(piece1)
        print >> sys.stderr, "read piece2", len(piece2)
        f.close()
        hash1 = sha(piece1).digest()
        hash2 = sha(piece2).digest()
        print >> sys.stderr, "hash piece1", repr(hash1)
        print >> sys.stderr, "hash piece2", repr(hash2)
        f2 = open("piece1.bin", "wb")
        f2.write(piece2)
        f2.close()
Ejemplo n.º 17
0
class TestMagnetMiniBitTorrent(TestAsServer, MagnetHelpers):
    """
    A MiniBitTorrent instance is used to connect to BitTorrent clients
    and download the info part from the metadata.
    """
    def setUp(self):
        """ override TestAsServer """
        # listener for incoming connections from MiniBitTorrent
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.server.bind(("localhost", LISTEN_PORT))
        self.server.listen(1)

        # the metadata that we want to transfer
        self.tdef = TorrentDef()
        self.tdef.add_content(os.path.join(os.getcwd(), "API", "file.wmv"))
        self.tdef.set_tracker("http://fake.net/announce")
        # we use a small piece length to obtain multiple pieces
        self.tdef.set_piece_length(1)
        self.tdef.finalize()

        MagnetHelpers.__init__(self, self.tdef)

        # startup the client
        TestAsServer.setUp(self)
        print >> sys.stderr, "test: Giving MyLaunchMany time to startup"
        time.sleep(5)
        print >> sys.stderr, "test: MyLaunchMany should have started up"

    def create_good_url(self, infohash=None, title=None, tracker=None):
        url = "magnet:?xt=urn:btih:"
        if infohash:
            assert isinstance(infohash, str)
            url += hexlify(infohash)
        else:
            url += hexlify(self.tdef.get_infohash())
        if title:
            assert isinstance(title, str)
            url += "&dn=" + title
        if tracker:
            assert isinstance(tracker, str)
            url += "&tr=" + tracker
        return url

    def test_good_transfer(self):
        def torrentdef_retrieved(tdef):
            tags["retrieved"] = True
            tags["metainfo"] = tdef.get_metainfo()

        tags = {"retrieved": False}

        assert TorrentDef.retrieve_from_magnet(self.create_good_url(),
                                               torrentdef_retrieved)

        # supply fake addresses (regular dht obviously wont work here)
        for magnetlink in MagnetHandler.get_instance().get_magnets():
            magnetlink._swarm.add_potential_peers([("localhost", LISTEN_PORT)])

        # accept incoming connection
        self.server.settimeout(10.0)
        sock, address = self.server.accept()
        assert sock, "No incoming connection"

        # handshakes
        conn = BTConnection(address[0],
                            address[1],
                            opensock=sock,
                            user_infohash=self.tdef.get_infohash())
        conn.send(self.create_good_extend_handshake())
        conn.read_handshake_medium_rare()
        metadata_id = self.read_extend_handshake(conn)

        # serve pieces
        for counter in xrange(len(self.metadata_list)):
            piece = self.read_extend_metadata_request(conn)
            assert 0 <= piece < len(self.metadata_list)
            conn.send(
                self.create_good_extend_metadata_reply(metadata_id, piece))

        # no more metadata request may be send and the connection must
        # be closed
        self.read_extend_metadata_close(conn)

        time.sleep(5)
        assert tags["retrieved"]
        assert tags["metainfo"]["info"] == self.tdef.get_metainfo()["info"]
Ejemplo n.º 18
0
def make_meta_file(srcpaths, params, userabortflag, progressCallback,
                   torrentfilenameCallback):
    tdef = TorrentDef()

    basedir = None

    nrFiles = len([file for file in srcpaths if os.path.isfile(file)])
    if nrFiles > 1:
        #outpaths should start with a common prefix, this prefix is the swarmname of the torrent
        #if srcpaths contain c:\a\1, c:\a\2 -> basepath should be c:\ and basedir a and outpaths should be a\1 and a\2
        #if srcpaths contain c:\a\1, c:\a\2, c:\a\b\1, c:\a\b\2 -> basepath should be c:\ and outpaths should be a\1, a\2, a\b\1 and a\b\2
        basepath = os.path.abspath(os.path.commonprefix(srcpaths))
        basepath, basedir = os.path.split(basepath)
        for srcpath in srcpaths:
            if os.path.isfile(srcpath):
                outpath = os.path.relpath(srcpath, basepath)

                # h4x0r playtime
                if 'playtime' in params:
                    tdef.add_content(srcpath,
                                     outpath,
                                     playtime=params['playtime'])
                else:
                    tdef.add_content(srcpath, outpath)
    else:
        srcpaths = [file for file in srcpaths if os.path.isfile(file)]

        srcpath = srcpaths[0]
        basepath, _ = os.path.split(srcpath)
        if 'playtime' in params:
            tdef.add_content(srcpath, playtime=params['playtime'])
        else:
            tdef.add_content(srcpath)

        if params.get('urllist', False):
            tdef.set_urllist(params['urllist'])

    if params['name']:
        tdef.set_name(params['name'])
    if params['comment']:
        tdef.set_comment(params['comment'])
    if params['created by']:
        tdef.set_created_by(params['created by'])
    if params['announce']:
        tdef.set_tracker(params['announce'])
    if params['announce-list']:
        tdef.set_tracker_hierarchy(params['announce-list'])
    if params['nodes']:  # mainline DHT
        tdef.set_dht_nodesmax(params['nodes'])
    if params['httpseeds']:
        tdef.set_httpseeds(params['httpseeds'])
    if params['encoding']:
        tdef.set_encoding(params['encoding'])
    if params['piece length']:
        tdef.set_piece_length(params['piece length'])
    if params['makehash_md5']:
        print >> sys.stderr, "TorrentMaker: make MD5"
        tdef.set_add_md5hash(params['makehash_md5'])
    if params['makehash_crc32']:
        print >> sys.stderr, "TorrentMaker: make CRC32"
        tdef.set_add_crc32(params['makehash_crc32'])
    if params['makehash_sha1']:
        print >> sys.stderr, "TorrentMaker: make SHA1"
        tdef.set_add_sha1hash(params['makehash_sha1'])
    if params['createmerkletorrent']:
        tdef.set_create_merkle_torrent(params['createmerkletorrent'])
    if params['torrentsigkeypairfilename']:
        tdef.set_signature_keypair_filename(
            params['torrentsigkeypairfilename'])
    if params['thumb']:
        tdef.set_thumbnail(params['thumb'])

    tdef.finalize(userabortflag=userabortflag,
                  userprogresscallback=progressCallback)

    if params['createmerkletorrent']:
        postfix = TRIBLER_TORRENT_EXT
    else:
        postfix = '.torrent'

    if params.get('target', False):
        torrentfilename = os.path.join(
            params['target'],
            os.path.split(os.path.normpath(srcpath))[1] + postfix)
    else:
        torrentfilename = os.path.join(basepath, tdef.get_name() + postfix)
    tdef.save(torrentfilename)

    # Inform higher layer we created torrent
    torrentfilenameCallback(basepath, basedir, torrentfilename)
Ejemplo n.º 19
0
class TestMetadata(TestAsServer, MagnetHelpers):
    """
    Once we are downloading a torrent, our client should respond to
    the ut_metadata extention message.  This allows other clients to
    obtain the info part of the metadata from us.
    """
    def setUp(self):
        """ override TestAsServer """
        TestAsServer.setUp(self)
        print >> sys.stderr, "test: Giving MyLaunchMany time to startup"
        time.sleep(5)
        print >> sys.stderr, "test: MyLaunchMany should have started up"

        # the metadata that we want to transfer
        self.tdef = TorrentDef()
        self.tdef.add_content(os.path.join(os.getcwd(), "API", "file.wmv"))
        self.tdef.set_tracker(self.session.get_internal_tracker_url())
        # we use a small piece length to obtain multiple pieces
        self.tdef.set_piece_length(1)
        self.tdef.finalize()
        # self.tdef.save(os.path.join(self.session.get_state_dir(), "gen.torrent"))

        MagnetHelpers.__init__(self, self.tdef)

    def setup_seeder(self):
        self.seeder_setup_complete = False
        self.seeder_teardown_complete = False
        self.seeder_teardown = False

        self.dscfg = DownloadStartupConfig()
        self.dscfg.set_dest_dir(os.getcwd())
        self.download = self.session.start_download(self.tdef, self.dscfg)
        self.download.set_state_callback(self.seeder_state_callback)

        counter = 0
        while not self.seeder_setup_complete:
            counter += 1
            time.sleep(1)
            assert counter < 30, "timeout"

        print >> sys.stderr, "test: setup_seeder() complete"

    def teardown_seeder(self):
        self.seeder_teardown_complete = False
        self.session.remove_download(self.download)

        counter = 0
        while not self.seeder_setup_complete:
            counter += 1
            time.sleep(1)
            assert counter < 30, "timeout"

        print >> sys.stderr, "test: teardown_seeder() complete"

    def seeder_state_callback(self, ds):
        assert not self.seeder_teardown_complete
        self.seeder_setup_complete = (ds.get_status() == DLSTATUS_DOWNLOADING)
        d = ds.get_download()
        print >> sys.stderr, "test: seeder:", ` d.get_def().get_name(
        ) `, dlstatus_strings[ds.get_status()], ds.get_progress()
        if self.seeder_teardown:
            self.seeder_teardown_complete = True
        else:
            return (1.0, False)

    def test_all(self):
        self.setup_seeder()
        try:
            self.subtest_good_flood()
        finally:
            self.teardown_seeder()

        self.setup_seeder()
        try:
            self.subtest_good_request()
            self.subtest_bad_request()
        finally:
            self.teardown_seeder()

    def subtest_good_request(self):
        conn = BTConnection("localhost",
                            self.hisport,
                            user_infohash=self.tdef.get_infohash())
        conn.send(self.create_good_extend_handshake())
        conn.read_handshake_medium_rare()
        metadata_id = self.read_extend_handshake(conn)

        # request metadata block 0, 2, 3, and the last
        conn.send(self.create_good_extend_metadata_request(metadata_id, 0))
        conn.send(self.create_good_extend_metadata_request(metadata_id, 2))
        conn.send(self.create_good_extend_metadata_request(metadata_id, 3))
        conn.send(
            self.create_good_extend_metadata_request(
                metadata_id,
                len(self.metadata_list) - 1))

        self.read_extend_metadata_reply(conn, 0)
        self.read_extend_metadata_reply(conn, 2)
        self.read_extend_metadata_reply(conn, 3)
        self.read_extend_metadata_reply(conn, len(self.metadata_list) - 1)

    def subtest_good_flood(self):
        conn = BTConnection("localhost",
                            self.hisport,
                            user_infohash=self.tdef.get_infohash())
        conn.send(self.create_good_extend_handshake())
        conn.read_handshake_medium_rare()
        metadata_id = self.read_extend_handshake(conn)

        for counter in xrange(len(self.metadata_list) * 2):
            piece = counter % len(self.metadata_list)
            conn.send(
                self.create_good_extend_metadata_request(metadata_id, piece))

            if counter > len(self.metadata_list):
                self.read_extend_metadata_reject(conn, piece)
            else:
                self.read_extend_metadata_reply(conn, piece)

    def subtest_bad_request(self):
        self.bad_request_and_disconnect({
            "msg_type": 0,
            "piece": len(self.metadata_list)
        })
        self.bad_request_and_disconnect({"msg_type": 0, "piece": -1})
        self.bad_request_and_disconnect({"msg_type": 0, "piece": "1"})
        self.bad_request_and_disconnect({"msg_type": 0, "piece": [1, 2]})
        self.bad_request_and_disconnect({"msg_type": 0, "PIECE": 1})

    def bad_request_and_disconnect(self, payload):
        conn = BTConnection("localhost",
                            self.hisport,
                            user_infohash=self.tdef.get_infohash())
        conn.send(self.create_good_extend_handshake())
        conn.read_handshake_medium_rare()
        metadata_id = self.read_extend_handshake(conn)

        conn.send(EXTEND + chr(metadata_id) + bencode(payload))
        self.read_extend_metadata_close(conn)
Ejemplo n.º 20
0
class TestMetadataFakePeer(TestAsServer, MagnetHelpers):
    """
    Once we are downloading a torrent, our client should respond to
    the ut_metadata extention message.  This allows other clients to
    obtain the info part of the metadata from us.
    """
    def setUp(self):
        TestAsServer.setUp(self)

        # the metadata that we want to transfer
        self.tdef = TorrentDef()
        self.tdef.add_content(os.path.join(TESTS_API_DIR, "file.wmv"))
        self.tdef.set_tracker("http://fake.net/announce")
        # we use a small piece length to obtain multiple pieces
        self.tdef.set_piece_length(1)
        self.tdef.finalize()
        self.setup_seeder()

        MagnetHelpers.__init__(self, self.tdef)

    def setUpPreSession(self):
        TestAsServer.setUpPreSession(self)
        self.config.set_libtorrent(True)

        self.config2 = self.config.copy()
        self.config2.set_state_dir(self.getStateDir(2))

    def tearDown(self):
        self.teardown_seeder()
        TestAsServer.tearDown(self)

    def setup_seeder(self):
        self.seeder_setup_complete = threading.Event()

        self.dscfg = DownloadStartupConfig()
        self.dscfg.set_dest_dir(TESTS_API_DIR)
        self.download = self.session.start_download(self.tdef, self.dscfg)
        self.download.set_state_callback(self.seeder_state_callback)

        assert self.seeder_setup_complete.wait(30)

    def teardown_seeder(self):
        self.session.remove_download(self.download)

    def seeder_state_callback(self, ds):
        if ds.get_status() == DLSTATUS_SEEDING:
            self.seeder_setup_complete.set()

        d = ds.get_download()
        self._logger.debug("seeder: %s %s %s", repr(d.get_def().get_name()),
                           dlstatus_strings[ds.get_status()],
                           ds.get_progress())
        return 1.0, False

    def test_good_request(self):
        conn = BTConnection("localhost",
                            self.session.get_listen_port(),
                            user_infohash=self.tdef.get_infohash())
        conn.send(self.create_good_extend_handshake())
        conn.read_handshake_medium_rare()
        metadata_id = self.read_extend_handshake(conn)

        # request metadata block 0, 2, 3, and the last
        conn.send(self.create_good_extend_metadata_request(metadata_id, 0))
        conn.send(self.create_good_extend_metadata_request(metadata_id, 2))
        conn.send(self.create_good_extend_metadata_request(metadata_id, 3))
        conn.send(
            self.create_good_extend_metadata_request(
                metadata_id,
                len(self.metadata_list) - 1))

        self.read_extend_metadata_reply(conn, 0)
        self.read_extend_metadata_reply(conn, 2)
        self.read_extend_metadata_reply(conn, 3)
        self.read_extend_metadata_reply(conn, len(self.metadata_list) - 1)

    def test_good_flood(self):
        conn = BTConnection("localhost",
                            self.session.get_listen_port(),
                            user_infohash=self.tdef.get_infohash())
        conn.send(self.create_good_extend_handshake())
        conn.read_handshake_medium_rare()
        metadata_id = self.read_extend_handshake(conn)

        for counter in xrange(len(self.metadata_list) * 2):
            piece = counter % len(self.metadata_list)
            conn.send(
                self.create_good_extend_metadata_request(metadata_id, piece))

            if counter > len(self.metadata_list):
                self.read_extend_metadata_reject(conn, piece)
            else:
                self.read_extend_metadata_reply(conn, piece)

    def test_bad_request(self):
        self.bad_request_and_disconnect({
            "msg_type": 0,
            "piece": len(self.metadata_list)
        })
        self.bad_request_and_disconnect({"msg_type": 0, "piece": -1})
        self.bad_request_and_disconnect({"msg_type": 0, "piece": "1"})
        self.bad_request_and_disconnect({"msg_type": 0, "piece": [1, 2]})
        self.bad_request_and_disconnect({"msg_type": 0, "PIECE": 1})

    def bad_request_and_disconnect(self, payload):
        conn = BTConnection("localhost",
                            self.session.get_listen_port(),
                            user_infohash=self.tdef.get_infohash())
        conn.send(self.create_good_extend_handshake())
        conn.read_handshake_medium_rare()
        metadata_id = self.read_extend_handshake(conn)

        conn.send(EXTEND + chr(metadata_id) + bencode(payload))
        self.read_extend_metadata_close(conn)
Ejemplo n.º 21
0
class TestQueryReplyActive(TestAsServer):

    """  
    Testing QUERY_REPLY message of Query extension V1 

    This test checks how the Tribler code responds to good and bad 
    QUERY_REPLY messages. I.e. the Tribler client initiates
    the dialback by connecting to us and sending a QUERY and we
    reply with good and bad messages.

    This test allows authoritative answers from superpeers.

    WARNING: Each of the test_ methods should be tested by running the TestCase 
    in a separate Python interpreter to prevent problems with our singleton 
    classes, e.g. SuperPeerDB, etc.
    """

    def setUpPreSession(self):
        """ override TestAsServer """
        print >> sys.stderr,"test: Pre Tribler Init"
        TestAsServer.setUpPreSession(self)
        print >> sys.stderr,"test: Pre Tribler Init: config_path",self.config_path
        # Enable remote querying
        self.config.set_remote_query(True)

    def setUpPostSession(self):
        """ override TestAsServer """
        TestAsServer.setUpPostSession(self)
        self.hispermid = str(self.his_keypair.pub().get_der())
        self.my_permid = str(self.my_keypair.pub().get_der())

    def pretest_simple(self,keyword):
        self.pretest_q('SIMPLE',keyword)

    def pretest_simpleplustorrents(self,keyword):
        self.pretest_q('SIMPLE+METADATA',keyword)

    def pretest_q(self,queryprefix,keyword):
        
        query = queryprefix+' '+keyword
        
        self.content_name = keyword.upper()+' S22E44'
        self.tdef = TorrentDef()
        self.tdef.set_tracker('http://localhost:0/announce')
        self.tdef.set_piece_length(2 ** 15)
        self.tdef.create_live(self.content_name,2 ** 16)
        self.tdef.finalize()
        
        # 1. First connect to Tribler
        self.openconn = OLConnection(self.my_keypair,'localhost',self.hisport)
        sleep(3)
        
        # 2. Make Tribler send query
        self.query = query
        self.session.query_connected_peers(query,self.query_usercallback,max_peers_to_query=10)

    def query_usercallback(self,permid,query,hits):
        
        print >>sys.stderr,"test: query_usercallback:",`permid`,`query`,`hits`
        
        self.assert_(query == self.query)
        self.assert_(permid == self.my_permid)
        self.check_good_qreply(hits)
        
        # TODO: if SIMPLE+METADATA: check torrent now in db.
        

    #
    # Good SIMPLE QUERY, builds on TestQueryReply code
    #    
    def singtest_good_simple_reply(self):
        self.pretest_simple('hallo')
        self._test_qreply(self.create_good_simple_reply,True)

    #
    # Good SIMPLE+METADATA QUERY, builds on TestQueryReply code
    #    
    def singtest_good_simpleplustorrents_reply(self):
        self.pretest_simpleplustorrents('hallo')
        self._test_qreply(self.create_good_simpleplustorrents_reply,True)


    #
    # Good SIMPLE QUERY Unicode, builds on TestQueryReply code
    #    
    def singtest_good_simple_reply_unicode(self):
        self.pretest_simple(u'Ch\u00e8rie')
        self._test_qreply(self.create_good_simple_reply,True)

    #
    # Good SIMPLE+METADATA QUERY Unicode, builds on TestQueryReply code
    #    
    def singtest_good_simpleplustorrents_reply_unicode(self):
        self.pretest_simpleplustorrents(u'Ch\u00e8rie')
        self._test_qreply(self.create_good_simpleplustorrents_reply,True)


    #
    # Bad QUERY, builds on TestQueryReply code
    #    
    def singtest_bad_not_bdecodable(self):
        self.pretest_simple('hallo')
        self._test_qreply(self.create_not_bdecodable,False)

    #
    # Bad SIMPLE+METADATA QUERY, builds on TestQueryReply code
    #    
    def singtest_bad_not_bdecodable_torrentfile(self):
        self.pretest_simpleplustorrents('hallo')
        self._test_qreply(self.create_not_bdecodable_torrentfile,False)


    ### TODO: send different valid answers so consensus not reached

    #
    # Main test code
    #
    def _test_qreply(self,gen_qreply,good):
        print >> sys.stderr,"test: waiting for reply"
        s = self.openconn

        msg = s.recv()
        self.assert_(len(msg) > 0)
        print >> sys.stderr,"test: Received overlay message",getMessageName(msg[0])
        self.assert_(msg[0] == QUERY)
        id = self.check_rquery(msg[1:])
        
        resp = gen_qreply(id)
        print >> sys.stderr,"test: sending QUERY_REPLY"
        s.send(resp)
        if good:
            time.sleep(10)
            # the other side should not have closed the connection, as
            # this is all valid, so this should not throw an exception:
            s.send('bla')
            s.close()
        else:
            # the other side should not like this and close the connection
            self.assert_(len(s.recv())==0)
            s.close()


    def create_good_simple_reply_dict(self,id):
        r = {}
        r['content_name'] = self.content_name.encode("UTF-8")
        r['length'] = LENGTH
        r['leecher'] = LEECHERS
        r['seeder'] = SEEDERS
        r['category'] = CATEGORY
        # OLPROTO_PROTO_ELEVENTH
        # set later r['torrent_size'] = 42
        r['channel_permid'] = '$' * 83
        r['channel_name'] = 'Nitin Channel' 
        
        d2 = {}
        d2[self.tdef.get_infohash()] = r
        
        d = {}
        d['id'] = id
        d['a'] = d2
        return d
        
    def create_good_simple_reply(self,id):
        d = self.create_good_simple_reply_dict(id)
        bmetainfo = bencode(self.tdef.get_metainfo())
        d['a'][self.tdef.get_infohash()]['torrent_size'] = len(bmetainfo) 
        b = bencode(d)
        return QUERY_REPLY+b

    def create_good_simpleplustorrents_reply(self,id):
        d = self.create_good_simple_reply_dict(id)
        bmetainfo = bencode(self.tdef.get_metainfo())
        d['a'][self.tdef.get_infohash()]['torrent_size'] = len(bmetainfo)
        d['a'][self.tdef.get_infohash()]['metatype'] = 'application/x-tribler-stream' 
        d['a'][self.tdef.get_infohash()]['metadata'] = bmetainfo 
        b = bencode(d)
        return QUERY_REPLY+b

    

    def check_good_qreply(self,hits):
        self.assert_(len(hits) == 1)
        self.assert_(hits.keys()[0] == self.tdef.get_infohash())
        hit = hits[self.tdef.get_infohash()]
        self.assert_(hit['content_name'] == self.content_name)
        self.assert_(hit['length'] == LENGTH)
        self.assert_(hit['leecher'] == LEECHERS)
        self.assert_(hit['seeder'] == SEEDERS)
        self.assert_(hit['category'] ==  CATEGORY)
    
        # OLPROTO_VERSION_ELEVENTH
        bmetainfo = bencode(self.tdef.get_metainfo())
        self.assert_(hit['torrent_size'] == len(bmetainfo))
        if self.query.startswith('SIMPLE+METADATA'):
            self.assert_(hit['metadata'] == bmetainfo)

    def create_not_bdecodable(self,id):
        return QUERY_REPLY+"bla"

    def create_not_bdecodable_torrentfile(self,id):
        d = self.create_good_simple_reply_dict(id)
        d['a'][self.tdef.get_infohash()]['torrent_size'] = 3 # consistent with metadata. Should be named "metasize"
        d['a'][self.tdef.get_infohash()]['metadata'] = 'bla'
        b = bencode(d)
        return QUERY_REPLY+b

    def check_rquery(self,data):
        d = bdecode(data)
        self.assert_(type(d) == DictType)
        self.assert_(d.has_key('q'))
        q = d['q']
        self.assert_(type(q) == StringType)
        self.assert_(d.has_key('id'))
        id = d['id']
        self.assert_(type(id) == StringType)

        self.assert_(q == self.query.encode("UTF-8"))
        return d['id']
Ejemplo n.º 22
0
class TestMagnetFakePeer(TestAsServer, MagnetHelpers):

    """
    A MiniBitTorrent instance is used to connect to BitTorrent clients
    and download the info part from the metadata.
    """
    def setUp(self):
        # listener for incoming connections from MiniBitTorrent
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.bind(("", LISTEN_PORT))
        self.server.listen(5)

        TestAsServer.setUp(self)

        # the metadata that we want to transfer
        self.tdef = TorrentDef()
        self.tdef.add_content(os.path.join(BASE_DIR, "API", "file.wmv"))
        self.tdef.set_tracker("http://fake.net/announce")
        # we use a small piece length to obtain multiple pieces
        self.tdef.set_piece_length(1)
        self.tdef.finalize()

        MagnetHelpers.__init__(self, self.tdef)

    def setUpPreSession(self):
        TestAsServer.setUpPreSession(self)
        self.config.set_libtorrent(True)

    def create_good_url(self, infohash=None, title=None, tracker=None):
        url = "magnet:?xt=urn:btih:"
        if infohash:
            assert isinstance(infohash, str)
            url += hexlify(infohash)
        else:
            url += hexlify(self.tdef.get_infohash())
        if title:
            assert isinstance(title, str)
            url += "&dn=" + title
        if tracker:
            assert isinstance(tracker, str)
            url += "&tr=" + tracker
        return url

    @skip("not working, seems to return binary data")
    def test_good_transfer(self):
        def torrentdef_retrieved(tdef):
            tags["retrieved"].set()
            tags["metainfo"] = tdef.get_metainfo()

        tags = {"retrieved": threading.Event()}

        assert TorrentDef.retrieve_from_magnet(self.create_good_url(), torrentdef_retrieved, timeout=60)

        def do_supply():
            # supply fake addresses (regular dht obviously wont work here)
            ltmgr = LibtorrentMgr.getInstance()
            for infohash in ltmgr.metainfo_requests:
                handle = ltmgr.ltsession.find_torrent(lt.big_number(infohash.decode('hex')))
                handle.connect_peer(("127.0.0.1", LISTEN_PORT), 0)
        self.session.lm.rawserver.add_task(do_supply, delay=5.0)

        # accept incoming connection
        # self.server.settimeout(10.0)
        sock, address = self.server.accept()
        assert sock, "No incoming connection"

        # handshakes
        conn = BTConnection(address[0], address[1], opensock=sock, user_infohash=self.tdef.get_infohash())
        conn.send(self.create_good_extend_handshake())
        conn.read_handshake_medium_rare()
        metadata_id = self.read_extend_handshake(conn)

        # serve pieces
        for counter in xrange(len(self.metadata_list)):
            piece = self.read_extend_metadata_request(conn)
            assert 0 <= piece < len(self.metadata_list)
            conn.send(self.create_good_extend_metadata_reply(metadata_id, piece))

        # no more metadata request may be send and the connection must
        # be closed
        self.read_extend_metadata_close(conn)

        assert tags["retrieved"].wait(5)
        assert tags["metainfo"]["info"] == self.tdef.get_metainfo()["info"]
Ejemplo n.º 23
0
class TestMetadataFakePeer(TestAsServer, MagnetHelpers):

    """
    Once we are downloading a torrent, our client should respond to
    the ut_metadata extention message.  This allows other clients to
    obtain the info part of the metadata from us.
    """
    def setUp(self):
        TestAsServer.setUp(self)

        # the metadata that we want to transfer
        self.tdef = TorrentDef()
        self.tdef.add_content(os.path.join(BASE_DIR, "API", "file.wmv"))
        self.tdef.set_tracker("http://fake.net/announce")
        # we use a small piece length to obtain multiple pieces
        self.tdef.set_piece_length(1)
        self.tdef.finalize()
        self.setup_seeder()

        MagnetHelpers.__init__(self, self.tdef)

    def setUpPreSession(self):
        TestAsServer.setUpPreSession(self)
        self.config.set_libtorrent(True)

        self.config2 = self.config.copy()
        self.config2.set_state_dir(self.getStateDir(2))
        self.config2.set_listen_port(4810)

    def tearDown(self):
        self.teardown_seeder()
        TestAsServer.tearDown(self)

    def setup_seeder(self):
        self.seeder_setup_complete = threading.Event()

        self.dscfg = DownloadStartupConfig()
        self.dscfg.set_dest_dir(os.path.join(BASE_DIR, "API"))
        self.download = self.session.start_download(self.tdef, self.dscfg)
        self.download.set_state_callback(self.seeder_state_callback)

        assert self.seeder_setup_complete.wait(30)

    def teardown_seeder(self):
        self.session.remove_download(self.download)

    def seeder_state_callback(self, ds):
        if ds.get_status() == DLSTATUS_SEEDING:
            self.seeder_setup_complete.set()

        d = ds.get_download()
        print >> sys.stderr, "test: seeder:", repr(d.get_def().get_name()), dlstatus_strings[ds.get_status()], ds.get_progress()
        return (1.0, False)

    def test_good_request(self):
        conn = BTConnection("localhost", self.hisport, user_infohash=self.tdef.get_infohash())
        conn.send(self.create_good_extend_handshake())
        conn.read_handshake_medium_rare()
        metadata_id = self.read_extend_handshake(conn)

        # request metadata block 0, 2, 3, and the last
        conn.send(self.create_good_extend_metadata_request(metadata_id, 0))
        conn.send(self.create_good_extend_metadata_request(metadata_id, 2))
        conn.send(self.create_good_extend_metadata_request(metadata_id, 3))
        conn.send(self.create_good_extend_metadata_request(metadata_id, len(self.metadata_list) - 1))

        self.read_extend_metadata_reply(conn, 0)
        self.read_extend_metadata_reply(conn, 2)
        self.read_extend_metadata_reply(conn, 3)
        self.read_extend_metadata_reply(conn, len(self.metadata_list) - 1)

    def test_good_flood(self):
        conn = BTConnection("localhost", self.hisport, user_infohash=self.tdef.get_infohash())
        conn.send(self.create_good_extend_handshake())
        conn.read_handshake_medium_rare()
        metadata_id = self.read_extend_handshake(conn)

        for counter in xrange(len(self.metadata_list) * 2):
            piece = counter % len(self.metadata_list)
            conn.send(self.create_good_extend_metadata_request(metadata_id, piece))

            if counter > len(self.metadata_list):
                self.read_extend_metadata_reject(conn, piece)
            else:
                self.read_extend_metadata_reply(conn, piece)

    def test_bad_request(self):
        self.bad_request_and_disconnect({"msg_type": 0, "piece": len(self.metadata_list)})
        self.bad_request_and_disconnect({"msg_type": 0, "piece":-1})
        self.bad_request_and_disconnect({"msg_type": 0, "piece": "1"})
        self.bad_request_and_disconnect({"msg_type": 0, "piece": [1, 2]})
        self.bad_request_and_disconnect({"msg_type": 0, "PIECE": 1})

    def bad_request_and_disconnect(self, payload):
        conn = BTConnection("localhost", self.hisport, user_infohash=self.tdef.get_infohash())
        conn.send(self.create_good_extend_handshake())
        conn.read_handshake_medium_rare()
        metadata_id = self.read_extend_handshake(conn)

        conn.send(EXTEND + chr(metadata_id) + bencode(payload))
        self.read_extend_metadata_close(conn)
Ejemplo n.º 24
0
class TestMagnetMiniBitTorrent(TestAsServer, MagnetHelpers):
    """
    A MiniBitTorrent instance is used to connect to BitTorrent clients
    and download the info part from the metadata.
    """
    def setUp(self):
        """ override TestAsServer """
        # listener for incoming connections from MiniBitTorrent
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.server.bind(("localhost", LISTEN_PORT))
        self.server.listen(1)

        # the metadata that we want to transfer
        self.tdef = TorrentDef()
        self.tdef.add_content(os.path.join(os.getcwd(), "API", "file.wmv"))
        self.tdef.set_tracker("http://fake.net/announce")
        # we use a small piece length to obtain multiple pieces
        self.tdef.set_piece_length(1)
        self.tdef.finalize()

        MagnetHelpers.__init__(self, self.tdef)

        # startup the client
        TestAsServer.setUp(self)
        print >>sys.stderr,"test: Giving MyLaunchMany time to startup"
        time.sleep(5)
        print >>sys.stderr,"test: MyLaunchMany should have started up"

    def create_good_url(self, infohash=None, title=None, tracker=None):
        url = "magnet:?xt=urn:btih:"
        if infohash:
            assert isinstance(infohash, str)
            url += hexlify(infohash)
        else:
            url += hexlify(self.tdef.get_infohash())
        if title:
            assert isinstance(title, str)
            url += "&dn=" + title
        if tracker:
            assert isinstance(tracker, str)
            url += "&tr=" + tracker
        return url

    def test_good_transfer(self):
        def torrentdef_retrieved(tdef):
            tags["retrieved"] = True
            tags["metainfo"] = tdef.get_metainfo()

        tags = {"retrieved":False}

        assert TorrentDef.retrieve_from_magnet(self.create_good_url(), torrentdef_retrieved)

        # supply fake addresses (regular dht obviously wont work here)
        for magnetlink in MagnetHandler.get_instance().get_magnets():
            magnetlink._swarm.add_potential_peers([("localhost", LISTEN_PORT)])

        # accept incoming connection
        self.server.settimeout(10.0)
        sock, address = self.server.accept()
        assert sock, "No incoming connection"

        # handshakes
        conn = BTConnection(address[0], address[1], opensock=sock, user_infohash=self.tdef.get_infohash())
        conn.send(self.create_good_extend_handshake())
        conn.read_handshake_medium_rare()
        metadata_id = self.read_extend_handshake(conn)

        # serve pieces
        for counter in xrange(len(self.metadata_list)):
            piece = self.read_extend_metadata_request(conn)
            assert 0 <= piece < len(self.metadata_list)
            conn.send(self.create_good_extend_metadata_reply(metadata_id, piece))

        # no more metadata request may be send and the connection must
        # be closed
        self.read_extend_metadata_close(conn)

        time.sleep(5)
        assert tags["retrieved"]
        assert tags["metainfo"]["info"] == self.tdef.get_metainfo()["info"]
Ejemplo n.º 25
0
def make_meta_file(srcpaths, params, userabortflag, progressCallback, torrentfilenameCallback):
    tdef = TorrentDef()
    
    if len(srcpaths) > 1:
        basepath = []
        for srcpath in srcpaths:
            path, filename = os.path.split(srcpath)
            basepath.append(path)
            
        basepath, _ = os.path.split(os.path.commonprefix(basepath))
        for srcpath in srcpaths:
            outpath = os.path.relpath(srcpath, basepath)
            
            # h4x0r playtime
            if 'playtime' in params:
                tdef.add_content(srcpath, outpath, playtime=params['playtime'])
            else:
                tdef.add_content(srcpath, outpath)
    else:
        srcpath = srcpaths[0]
        basepath, _ = os.path.split(srcpath)
        if 'playtime' in params:
            tdef.add_content(srcpath,playtime=params['playtime'])
        else:
            tdef.add_content(srcpath)
            
    if params['comment']:
        tdef.set_comment(params['comment'])
    if params['created by']:
        tdef.set_created_by(params['created by'])
    if params['announce']:
        tdef.set_tracker(params['announce'])
    if params['announce-list']:
        tdef.set_tracker_hierarchy(params['announce-list'])
    if params['nodes']: # mainline DHT
        tdef.set_dht_nodesmax(params['nodes'])
    if params['httpseeds']:
        tdef.set_httpseeds(params['httpseeds'])
    if params['encoding']:
        tdef.set_encoding(params['encoding'])
    if params['piece length']:
        tdef.set_piece_length(params['piece length'])
    if params['makehash_md5']:
        print >>sys.stderr,"TorrentMaker: make MD5"
        tdef.set_add_md5hash(params['makehash_md5'])
    if params['makehash_crc32']:
        print >>sys.stderr,"TorrentMaker: make CRC32"
        tdef.set_add_crc32(params['makehash_crc32'])
    if params['makehash_sha1']:
        print >>sys.stderr,"TorrentMaker: make SHA1"
        tdef.set_add_sha1hash(params['makehash_sha1'])
    if params['createmerkletorrent']:
        tdef.set_create_merkle_torrent(params['createmerkletorrent'])
    if params['torrentsigkeypairfilename']:
        tdef.set_signature_keypair_filename(params['torrentsigkeypairfilename'])
    if params['thumb']:
        tdef.set_thumbnail(params['thumb'])
        
    tdef.finalize(userabortflag=userabortflag,userprogresscallback=progressCallback)
    
    if params['createmerkletorrent']:
        postfix = TRIBLER_TORRENT_EXT
    else:
        postfix = '.torrent'
    
    if 'target' in params and params['target']:
        torrentfilename = os.path.join(params['target'], os.path.split(os.path.normpath(srcpath))[1] + postfix)
    else:
        a, b = os.path.split(srcpaths[0])
        if b == '':
            torrentfilename = a + postfix
        else:
            torrentfilename = os.path.join(a, b + postfix)
    tdef.save(torrentfilename)
    
    # Inform higher layer we created torrent
    torrentfilenameCallback(basepath, torrentfilename)
Ejemplo n.º 26
0
class TestVideoOnDemand(TestAsServer):

    """
    Testing Merkle hashpiece messages for both:
    * Merkle BEP style
    * old Tribler <= 4.5.2 that did not use the Extention protocol (BEP 10).

    See BitTornado/BT1/Connecter.py
    """

    def setUp(self):
        """ override TestAsServer """
        TestAsServer.setUp(self)
        self.vodstarted = False

    def setUpPreSession(self):
        TestAsServer.setUpPreSession(self)
        self.config.set_libtorrent(True)

    def create_torrent(self):
        [srchandle, self.sourcefn] = mkstemp()
        self.content = Rand.rand_bytes(self.contentlen)
        os.write(srchandle, self.content)
        os.close(srchandle)

        self.tdef = TorrentDef()
        self.tdef.add_content(self.sourcefn)
        self.tdef.set_piece_length(self.piecelen)
        self.tdef.set_tracker("http://127.0.0.1:12/announce")
        self.tdef.finalize()

        self.torrentfn = os.path.join(self.session.get_state_dir(), "gen.torrent")
        self.tdef.save(self.torrentfn)

        dscfg = DownloadStartupConfig()
        destdir = os.path.dirname(self.sourcefn)
        dscfg.set_dest_dir(destdir)
        dscfg.set_video_event_callback(self.sesscb_vod_event_callback)

        self.session.set_download_states_callback(self.states_callback)
        self.session.start_download(self.tdef, dscfg)

    def states_callback(self, dslist):
        ds = dslist[0]
        d = ds.get_download()
    #    print >>sys.stderr,`d.get_def().get_name()`,dlstatus_strings[ds.get_status()],ds.get_progress(),"%",ds.get_error(),"up",ds.get_current_speed(UPLOAD),"down",ds.get_current_speed(DOWNLOAD)
        print >> sys.stderr, '%s %s %5.2f%% %s up %8.2fKB/s down %8.2fKB/s' % \
            (d.get_def().get_name(),
                dlstatus_strings[ds.get_status()],
                ds.get_progress() * 100,
                ds.get_error(),
                ds.get_current_speed(UPLOAD),
                ds.get_current_speed(DOWNLOAD))

        return (1.0, [])

    def sesscb_vod_event_callback(self, d, event, params):
        if self.vodstarted:
            return
        self.vodstarted = True

        print >> sys.stderr, "Test: vod_event_callback", event, params
        if event == VODEVENT_START:
            stream = params['stream']

            # Read last piece
            lastpieceoff = ((self.contentlen - 1) / self.piecelen) * self.piecelen
            lastpiecesize = self.contentlen - lastpieceoff
            print >> sys.stderr, "Test: stream: lastpieceoff", lastpieceoff, lastpiecesize
            self.stream_read(stream, lastpieceoff, lastpiecesize, self.piecelen)

            # Read second,3rd,4th byte, only
            secoff = 1
            secsize = 3
            blocksize = 3
            self.stream_read(stream, secoff, secsize, blocksize)

            # Read last byte
            lastoff = self.contentlen - 1
            lastsize = 1
            self.stream_read(stream, lastoff, lastsize, self.piecelen)

    def stream_read(self, stream, off, size, blocksize):
        stream.seek(off)
        data = stream.read(blocksize)
        print >> sys.stderr, "Test: stream: Got data", len(data)
        self.assertEquals(len(data), size)
        self.assertEquals(data, self.content[off:off + size])

    def test_99(self):
        self.contentlen = 99
        self.piecelen = 10
        self.create_torrent()

        print >> sys.stderr, "Test: Letting network thread create Download, sleeping"
        time.sleep(5)

        dlist = self.session.get_downloads()
        d = dlist[0]
        vs = d.get_vod_info()['status']

        if vs:
            goodrange = ((0, 0), (9, 8))
            self.assertEqual(vs.movie_range, goodrange)
            self.assertEqual(vs.first_piecelen, 10)
            self.assertEqual(vs.last_piecelen, 9)
            self.assertEqual(vs.first_piece, 0)
            self.assertEqual(vs.last_piece, 9)
            self.assertEqual(vs.movie_numpieces, 10)

    def test_100(self):
        self.contentlen = 100
        self.piecelen = 10
        self.create_torrent()

        print >> sys.stderr, "Test: Letting network thread create Download, sleeping"
        time.sleep(5)

        dlist = self.session.get_downloads()
        d = dlist[0]
        vs = d.get_vod_info()['status']

        if vs:
            goodrange = ((0, 0), (9, 9))
            self.assertEqual(vs.movie_range, goodrange)
            self.assertEqual(vs.first_piecelen, 10)
            self.assertEqual(vs.last_piecelen, 10)
            self.assertEqual(vs.first_piece, 0)
            self.assertEqual(vs.last_piece, 9)
            self.assertEqual(vs.movie_numpieces, 10)

    def test_101(self):
        self.contentlen = 101
        self.piecelen = 10
        self.create_torrent()

        print >> sys.stderr, "Test: Letting network thread create Download, sleeping"
        time.sleep(5)

        dlist = self.session.get_downloads()
        d = dlist[0]
        vs = d.get_vod_info()['status']

        if vs:
            goodrange = ((0, 0), (10, 0))
            self.assertEqual(vs.movie_range, goodrange)
            self.assertEqual(vs.first_piecelen, 10)
            self.assertEqual(vs.last_piecelen, 1)
            self.assertEqual(vs.first_piece, 0)
            self.assertEqual(vs.last_piece, 10)
            self.assertEqual(vs.movie_numpieces, 11)
Ejemplo n.º 27
0
def make_meta_file(srcpaths, params, userabortflag, progressCallback, torrentfilenameCallback):
    tdef = TorrentDef()

    basedir = None

    nrFiles = len([file for file in srcpaths if os.path.isfile(file)])
    if nrFiles > 1:
        # outpaths should start with a common prefix, this prefix is the swarmname of the torrent
        # if srcpaths contain c:\a\1, c:\a\2 -> basepath should be c:\ and basedir a and outpaths should be a\1 and a\2
        # if srcpaths contain c:\a\1, c:\a\2, c:\a\b\1, c:\a\b\2 -> basepath should be c:\ and outpaths should be a\1, a\2, a\b\1 and a\b\2
        basepath = os.path.abspath(os.path.commonprefix(srcpaths))
        basepath, basedir = os.path.split(basepath)
        for srcpath in srcpaths:
            if os.path.isfile(srcpath):
                outpath = os.path.relpath(srcpath, basepath)

                # h4x0r playtime
                if 'playtime' in params:
                    tdef.add_content(srcpath, outpath, playtime=params['playtime'])
                else:
                    tdef.add_content(srcpath, outpath)
    else:
        srcpaths = [file for file in srcpaths if os.path.isfile(file)]

        srcpath = srcpaths[0]
        basepath, _ = os.path.split(srcpath)
        if 'playtime' in params:
            tdef.add_content(srcpath, playtime=params['playtime'])
        else:
            tdef.add_content(srcpath)

        if params.get('urllist', False):
            tdef.set_urllist(params['urllist'])

    if params['name']:
        tdef.set_name(params['name'])
    if params['comment']:
        tdef.set_comment(params['comment'])
    if params['created by']:
        tdef.set_created_by(params['created by'])
    if params['announce']:
        tdef.set_tracker(params['announce'])
    if params['announce-list']:
        tdef.set_tracker_hierarchy(params['announce-list'])
    if params['nodes']:  # mainline DHT
        tdef.set_dht_nodesmax(params['nodes'])
    if params['httpseeds']:
        tdef.set_httpseeds(params['httpseeds'])
    if params['encoding']:
        tdef.set_encoding(params['encoding'])
    if params['piece length']:
        tdef.set_piece_length(params['piece length'])
    if params['makehash_md5']:
        print >> sys.stderr, "TorrentMaker: make MD5"
        tdef.set_add_md5hash(params['makehash_md5'])
    if params['makehash_crc32']:
        print >> sys.stderr, "TorrentMaker: make CRC32"
        tdef.set_add_crc32(params['makehash_crc32'])
    if params['makehash_sha1']:
        print >> sys.stderr, "TorrentMaker: make SHA1"
        tdef.set_add_sha1hash(params['makehash_sha1'])
    if params['createmerkletorrent']:
        tdef.set_create_merkle_torrent(params['createmerkletorrent'])
    if params['torrentsigkeypairfilename']:
        tdef.set_signature_keypair_filename(params['torrentsigkeypairfilename'])
    if params['thumb']:
        tdef.set_thumbnail(params['thumb'])

    tdef.finalize(userabortflag=userabortflag, userprogresscallback=progressCallback)

    if params['createmerkletorrent']:
        postfix = TRIBLER_TORRENT_EXT
    else:
        postfix = '.torrent'

    if params.get('target', False):
        torrentfilename = os.path.join(params['target'], os.path.split(os.path.normpath(srcpath))[1] + postfix)
    else:
        torrentfilename = os.path.join(basepath, tdef.get_name() + postfix)
    tdef.save(torrentfilename)

    # Inform higher layer we created torrent
    torrentfilenameCallback(basepath, basedir, torrentfilename)