def test_multi_page(self): def nums(*numbers): return list([page_numbers[n] for n in numbers]) page_max = bitfield.get_all_sizes()["PAGE_MAX"] page_numbers = [5 + (page_max * i) for i in range(10)] a = bitfield.Bitfield(nums(0, 2)) b = bitfield.Bitfield(nums(1, 3)) self._test_methods(a, b) self._test_methods(b, a)
def test_creating_large_field(self): # This is a strange test, the idea is to create a large set, then do something with it # provided the test completes in a 'reasonable' timescale, then it should be fine one_million = 1000000 size = one_million * 1000 field1 = bitfield.Bitfield([[0, size]]) field2 = bitfield.Bitfield([[size, size * 2]]) self.assertEqual(len(field1), size) self.assertEqual(len(field2), size) self.assertEqual(len(field1 | field2), size * 2)
def test_merging(self): a = bitfield.Bitfield() b = bitfield.Bitfield() a.add(0) b.add(0) a.update(b) self.assertEqual(list(a), [0]) a.add(1000) b.add(1000000) b.update(a) self.assertEqual(list(b), [0, 1000, 1000000])
def __init__(self, peer_dict, torrent, my_id): self.ip = peer_dict['ip'] self.port = peer_dict['port'] self.id = peer_dict.get('id') or peer_dict.get('peer id') if not self.id: print "No ID found. Not a valid peer." self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.torrent = torrent self.my_id = my_id self.bitfield = bitfield.Bitfield(self.torrent) self.bitfield.initialize_bitfield() self.handshake = False self.choked = True self.downloading = False self.requesting = False self.complete = False self.connecting = False self.interested = False self.message_incomplete = False self.incomplete_data = '' self.incomplete_message_id = -1 self.data_length = -1 self.piece_data = '' self.have = -1 self.pieces_i_have = 0 self.last_piece_index = (self.torrent.no_of_subpieces - 1)
def test_add_remove(self): b = bitfield.Bitfield() self.assertEqual(list(b), []) for i in xrange(0, 1000000, 881): b.add(i) self.assertEqual(list(b), [i]) b.remove(i)
def assemble(self, torrent): self.m_id = 5 bitfield_to_send = bitfield.Bitfield(torrent).pack_bitfield() bit_length = int(math.ceil(torrent.no_of_subpieces / 8.0)) message = pack(self.prefix + '%ds' % bit_length, bit_length + 1, self.m_id, bitfield_to_send) return message
def test_count(self): b = bitfield.Bitfield() self.assertEqual(b.count, 0) b.add(0) self.assertEqual(b.count, 1) b.add(10000) self.assertEqual(b.count, 2) self.assertEqual(len(b), 2)
def test_membership(self): b = bitfield.Bitfield() b.add(0) b.add(1) b.add(2) self.assertTrue(1 in b) self.assertFalse(3 in b) self.assertEqual(list(b), [0, 1, 2])
def test_repr_eval(self): b = bitfield.Bitfield() b.add(100) c = eval(repr(b)) self.assertEqual(b, c) for i in range(0, 1000, 13): b.add(i) c = eval(repr(b)) self.assertEqual(b, c)
def test_clone(self): a = bitfield.Bitfield() a.add(1) a.add(10) a.add(5000000) b = a.clone() self.assertEqual(a, b) b.add(45) self.assertNotEqual(a, b)
def assemble(self, torrent): """Formats to send over the network""" self.m_id = 5 bitfield_to_send = bitfield.Bitfield(torrent).pack_bitfield() bit_length = int(math.ceil(torrent.no_of_subpieces / 8.0)) message = pack(self.prefix+'%ds' % bit_length, bit_length+1, self.m_id, bitfield_to_send) # print "Bitfield assembled to send off: ", unpack("!IB%ds" % bit_length, message) return message
def test_mutating_while_iterating(self): b = bitfield.Bitfield([[0, 1000]]) count = len(b) for num in b: self.assertIn(num, b) b.remove(num) count -= 1 self.assertEqual(len(b), count) self.assertNotIn(num, b) self.assertEqual(count, 0)
def test_in(self): a = bitfield.Bitfield() for i in range(0, 100, 13): a.add(i) self.assertIn(13, a) self.assertIn(0, a) self.assertIn(26, a) self.assertNotIn(27, a) self.assertIn(39, a) self.assertNotIn(1000000, a) a.add(1000000) self.assertIn(1000000, a)
def test_empty(self): self._test_methods(bitfield.Bitfield(), bitfield.Bitfield())
def message_received(self, length, msg): try: if length == 0: protocol.parse_keep_alive(msg) return id = msg[0] if not self.ready() and id != protocol.BITFIELD: self._haves = bitfield.Bitfield(self._pieces) elif self.ready() and id == protocol.BITFIELD: raise ValueError(\ "Already received BITFIELD from peer %s" % self) if id == protocol.CHOKE: # If we are downloading, stop - DONE protocol.parse_choke(msg) self._choked = True del self._outstanding_requests[:] elif id == protocol.UNCHOKE: # If we are interested start downloading - DONE protocol.parse_unchoke(msg) self._choked = False self._request_piece() elif id == protocol.INTERESTED: protocol.parse_interested(msg) self._interested = True self._manager.interested_received(self) elif id == protocol.NOT_INTERESTED: protocol.parse_not_interested(msg) self._interested = False elif id == protocol.HAVE: # Check with coordinator if we are interested - DONE have = protocol.parse_have(msg) self._haves.set(have.piece) self.interested(self._manager.have_received(have.piece)) elif id == protocol.BITFIELD: # Only receive bitfield once after handshake - DONE # Check with coordinator if we are interested - DONE field = protocol.parse_bitfield(msg, self._pieces) self._haves = field.bitfield self.interested(\ self._manager.bitfield_received(field.bitfield)) elif id == protocol.REQUEST: req = protocol.parse_request(msg) if not self._choking and self._interested: piece = self._manager.request_received(req.index) if piece: data = piece.block(req.offset, req.length) self.piece(req.index, req.offset, data) # If we are choking this peer ignore - DONE # Else get piece from storage and send via out - DONE elif id == protocol.PIECE: piece = protocol.parse_piece(msg) #self.task.piece_received(piece, self._request) self._piece(piece) self._request_piece() # Tell coordinator we received a piece - DONE elif id == protocol.CANCEL: cancel = protocol.parse_cancel(msg) self._out.cancel_piece(cancel.index, \ cancel.offset, cancel.length) elif id == protocol.PORT: # Not supported. Ignore. pass else: raise ValueError(\ "Message with unknown id %d received" % id) except (ValueError, TypeError, IndexError, struct.error) as err: # Invalid message recevied from peer. Close connection? _logger.info(\ "Invalid message recevied from peer %s: %s" % (self, err)) #raise self._request_piece()
return self._block def payload(self): pre = super(piece_message, self).payload() return pre + struct.pack('!2I', self._index, self._offset) +\ self._block def cancel_message(index, offset, length): req = request_message(index, offset, length) req._id = CANCEL return req if __name__ == '__main__': import bitfield m = Message(CHOKE, 1) print(m.id) m = have_message(123) print(m.len) print(m.piece) print(m.payload()) n = have_message(122) print(m == n) field = bitfield.Bitfield(10) field.set(5) field.set(6) m = bitfield_message(field) print(m.payload())
def __init__(self, torrent, root_dir=DEFAULT_ROOT_DIR): self._torrent = torrent self._haves = bitfield.Bitfield(torrent.number_of_pieces) _logger.info("Creating/opening files") self._create_files(torrent, root_dir)
def test_init_with_small_ranges(self): a = bitfield.Bitfield(((0, 1), (3, 10),),) self.assertSequenceEqual(list(a), [0, 3, 4, 5, 6, 7, 8, 9])
def test_init_with_large_ranges(self): a = bitfield.Bitfield(((0, 20000), (30000, 100000))) self.assertEqual(len(a), 90000) self.assertEqual(max(a), 99999) self.assertEqual(min(a), 0)
self._torrent = t def has(self, piece): return False def completed(self): return False def piece(self, index): return storage.Piece.create_empty_piece(\ index, 256000, self._torrent.piece_hash(index)) def write_piece(self, piece): print("Writting piece ", piece) manager = PeerManager(peer_id, t, None, None, StorageMock(t)) peer = peer.handshake(sock, addr, peer_id, t, manager) field = bitfield.Bitfield(t.number_of_pieces) #for i in range(len(field)): # if random.random() < 0.5: # field.set(i) field.set(8) peer.bitfield(field) peer.choke(True) peer.choke(False) peer.have(9) time.sleep(5) peer.close()
def test_empty_full(self): page_max = bitfield.get_all_sizes()["PAGE_MAX"] a = bitfield.Bitfield([[0, page_max]]) b = bitfield.Bitfield() self._test_methods(a, b) self._test_methods(b, a)
import bitfield import sys if __name__ == "__main__": one_million = 1000000 size = one_million * 1000 field1 = bitfield.Bitfield([[0, size]]) field2 = bitfield.Bitfield([[size, size * 2]]) assert len(field1) == size assert len(field2) == size field3 = field1 | field2 assert len(field3) == size * 2
def test_simple(self): self._test_methods(bitfield.Bitfield([1, 2, 3]), bitfield.Bitfield([1, 2, 3])) self._test_methods(bitfield.Bitfield([1, 2, 3]), bitfield.Bitfield([1, 2])) self._test_methods(bitfield.Bitfield([1, 2, 3]), bitfield.Bitfield([3, 4, 5])) self._test_methods(bitfield.Bitfield([1]), bitfield.Bitfield([1, 3, 4, 5]))
def __init__(self, addr, peer_id, num_pieces): self.addr = addr self.peer_id = peer_id self.bitfield = bitfield.Bitfield(num_pieces)
def create_bitfield(self): self.bitfield = bitfield.Bitfield(self.info.num_pieces) for i in range(self.info.num_pieces): self.verify_piece(i, False)