def test_add_content_dir_and_file(self): """ Add a single dir and single file to a TorrentDef """ t = TorrentDef() dn = os.path.join(TESTS_DATA_DIR, "contentdir") t.add_content(dn, "dirintorrent") fn = os.path.join(TESTS_DATA_DIR, self.VIDEO_FILE_NAME) t.add_content(fn, os.path.join("dirintorrent", self.VIDEO_FILE_NAME)) t.set_tracker(TRACKER) t.finalize() # Check exps = os.path.getsize(fn) for f in os.listdir(dn): if f.startswith('.'): continue p = os.path.join(dn, f) exps += os.path.getsize(p) metainfo = t.get_metainfo() self.general_check(metainfo) self.assertEqual(metainfo['info']['name'], 'dirintorrent') reals = 0 for file in metainfo['info']['files']: reals += file['length'] self.assertEqual(exps, reals)
def test_add_content_file_and_copy(self): """ Add a single file to a TorrentDef """ t = TorrentDef() fn = os.path.join(TESTS_DATA_DIR, self.VIDEO_FILE_NAME) t.add_content(fn) t.set_tracker(TRACKER) t.finalize() s = os.path.getsize(fn) metainfo = t.get_metainfo() self.general_check(metainfo) self.assertEqual(metainfo['info']['name'], self.VIDEO_FILE_NAME) self.assertEqual(metainfo['info']['length'], s) self.assertTrue(t.get_pieces()) self.assertEqual(len(t.get_infohash()), INFOHASH_LENGTH) self.assertTrue(t.get_name()) # test copy constructor nt = TorrentDef(t.input, t.metainfo, t.infohash) self.assertEqual(nt.input, t.input) self.assertEqual(nt.metainfo, t.metainfo) self.assertEqual(nt.infohash, t.infohash) # test removing content nt.remove_content("/test123") self.assertEqual(len(nt.input['files']), 1) nt.remove_content(unicode(fn)) self.assertEqual(len(nt.input['files']), 0) nt.remove_content(unicode(fn))
def subtest_add_content_dir_and_file(self): """ Add a single dir and single file to a TorrentDef """ t = TorrentDef() dn = os.path.join(TESTS_API_DIR, "contentdir") t.add_content(dn, "dirintorrent") fn = os.path.join(TESTS_API_DIR, "video.avi") t.add_content(fn, os.path.join("dirintorrent", "video.avi")) t.set_tracker(TRACKER) t.finalize() # Check exps = os.path.getsize(fn) for f in os.listdir(dn): if f.startswith('.'): continue p = os.path.join(dn, f) exps += os.path.getsize(p) metainfo = t.get_metainfo() self.general_check(metainfo) self.assert_(metainfo['info']['name'] == 'dirintorrent') reals = 0 for file in metainfo['info']['files']: reals += file['length'] self.assert_(exps == reals)
def test_add_content_dir(self): """ Add a single dir to a TorrentDef """ t = TorrentDef() dn = os.path.join(TESTS_DATA_DIR, "contentdir") t.add_content(dn, "dirintorrent") t.set_tracker(TRACKER) t.finalize() exps = 0 for f in os.listdir(dn): if f.startswith('.'): continue p = os.path.join(dn, f) s = os.path.getsize(p) exps += s self._logger.debug("Expected size %s %d", f, s) self._logger.debug("Expected total size of files in torrent %d", exps) metainfo = t.get_metainfo() self.general_check(metainfo) self.assertEqual(metainfo['info']['name'], 'dirintorrent') reals = 0 for file in metainfo['info']['files']: s = file['length'] self._logger.debug("real size %s %d", file['path'], s) reals += s self._logger.debug("Real size of files in torrent %d", reals) self.assertEqual(exps, reals)
def subtest_add_content_dir(self): """ Add a single dir to a TorrentDef """ t = TorrentDef() dn = os.path.join(TESTS_API_DIR, "contentdir") t.add_content(dn, "dirintorrent") t.set_tracker(TRACKER) t.finalize() exps = 0 for f in os.listdir(dn): if f.startswith('.'): continue p = os.path.join(dn, f) s = os.path.getsize(p) exps += s print "test: expected size", f, s print "test: expected total size of files in torrent", exps metainfo = t.get_metainfo() self.general_check(metainfo) self.assert_(metainfo['info']['name'] == 'dirintorrent') reals = 0 for file in metainfo['info']['files']: s = file['length'] print "test: real size", file['path'], s reals += s print "test: real size of files in torrent", reals self.assert_(exps == reals)
def test_add_single_file(self): """ Test whether adding a single file to a torrent is working correctly """ t = TorrentDef() torrent_dir = os.path.join(TESTS_DATA_DIR, "contentdir") t.add_content(os.path.join(torrent_dir, "file.txt")) t.save() metainfo = t.get_metainfo() self.assertEqual(metainfo['info']['name'], 'file.txt')
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)
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)
def test_add_content_dir(self): """ Test whether adding a single content directory with two files is working correctly """ t = TorrentDef() torrent_dir = os.path.join(TESTS_DATA_DIR, "contentdir") t.add_content(os.path.join(torrent_dir, "file.txt")) t.add_content(os.path.join(torrent_dir, "otherfile.txt")) t.save() metainfo = t.get_metainfo() self.assertEqual(len(metainfo['info']['files']), 2)
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)
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)
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)
def subtest_add_content_httpseeds(self): """ Add a single file with BitTornado httpseeds to a TorrentDef """ t = TorrentDef() fn = os.path.join(TESTS_API_DIR, "video.avi") t.add_content(fn) t.set_tracker(TRACKER) expseeds = ['http://www.cs.vu.nl/index.html', 'http://www.st.ewi.tudelft.nl/index.html'] t.set_httpseeds(expseeds) t.finalize() metainfo = t.get_metainfo() self.general_check(metainfo) realseeds = metainfo['httpseeds'] self.assert_(realseeds == expseeds)
def subtest_add_content_file(self): """ Add a single file to a TorrentDef """ t = TorrentDef() fn = os.path.join(TESTS_API_DIR, "video.avi") t.add_content(fn) t.set_tracker(TRACKER) t.finalize() s = os.path.getsize(fn) metainfo = t.get_metainfo() self.general_check(metainfo) self.assert_(metainfo['info']['name'] == "video.avi") self.assert_(metainfo['info']['length'] == s)
def subtest_add_content_announce_list(self): """ Add a single file with announce-list to a TorrentDef """ t = TorrentDef() fn = os.path.join(TESTS_API_DIR, "video.avi") t.add_content(fn) t.set_tracker(TRACKER) exphier = [[TRACKER], ['http://tracker1.tribler.org:6969/announce', 'http://tracker2.tribler.org:7070/ann'], ['http://www.cs.vu.nl', 'http://www.st.ewi.tudelft.nl', 'http://www.vuze.com']] t.set_tracker_hierarchy(exphier) t.finalize() metainfo = t.get_metainfo() self.general_check(metainfo) realhier = metainfo['announce-list'] self.assert_(realhier == exphier)
def test_add_content_httpseeds(self): """ Add a single file with BitTornado httpseeds to a TorrentDef """ t = TorrentDef() fn = os.path.join(TESTS_DATA_DIR, self.VIDEO_FILE_NAME) t.add_content(fn) t.set_tracker(TRACKER) expseeds = [ 'http://www.cs.vu.nl/index.html', 'http://www.st.ewi.tudelft.nl/index.html' ] t.set_httpseeds(expseeds) t.finalize() metainfo = t.get_metainfo() self.general_check(metainfo) realseeds = metainfo['httpseeds'] self.assertEqual(realseeds, expseeds)
def test_add_content_file_save(self): """ Add a single file to a TorrentDef and save the latter""" t = TorrentDef() fn = os.path.join(TESTS_DATA_DIR, self.VIDEO_FILE_NAME) t.add_content(fn) t.set_tracker(TRACKER) t.finalize() tfn = os.path.join(os.getcwd(), "gen.torrent") t.save(tfn) f = open(tfn, "rb") bdata = f.read() f.close() os.remove(tfn) data = bdecode(bdata) metainfo = t.get_metainfo() self.general_check(metainfo) self.assertEqual(metainfo, data)
def subtest_add_content_file_save(self): """ Add a single file to a TorrentDef and save the latter""" t = TorrentDef() fn = os.path.join(TESTS_API_DIR, "video.avi") t.add_content(fn) t.set_tracker(TRACKER) t.finalize() tfn = os.path.join(os.getcwd(), "gen.torrent") t.save(tfn) f = open(tfn, "rb") bdata = f.read() f.close() os.remove(tfn) data = bdecode(bdata) metainfo = t.get_metainfo() self.general_check(metainfo) self.assert_(metainfo == data)
def test_add_content_announce_list(self): """ Add a single file with announce-list to a TorrentDef """ t = TorrentDef() fn = os.path.join(TESTS_DATA_DIR, self.VIDEO_FILE_NAME) t.add_content(fn) t.set_tracker(TRACKER) exphier = [[TRACKER], [ 'http://tracker1.tribler.org:6969/announce', 'http://tracker2.tribler.org:7070/ann' ], [ 'http://www.cs.vu.nl', 'http://www.st.ewi.tudelft.nl', 'http://www.vuze.com' ]] t.set_tracker_hierarchy(exphier) t.finalize() metainfo = t.get_metainfo() self.general_check(metainfo) realhier = metainfo['announce-list'] self.assertEqual(realhier, exphier)
def test_no_valid_metainfo(self): t = TorrentDef() t.get_metainfo()
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()
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"]
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']
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"]
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"]
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"]
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()