def test_buidling_updates(self): """ Test performance of building update messages for many players""" connections = list for i in range(100): connection = Connection(self.world, self.cache) connection.get_frame() self.pr.enable() self.clock.advance(1) self.pr.disable() print self.process_stats('test_buidling_updates.txt')
def test_get_update(self): """ Test raw execution performance of the 'get_update'""" self.connection = Connection(self.world, self.cache) archers = list() for i in range(50): archer = Archer(self.world, reactor=self.clock) archer.spawn(self.spawn_point) archer.want_move(directions['south']) archers.append(archer) self.pr.enable() for i in range(100): self.connection.get_update() self.pr.disable() print self.process_stats('test_get_update.txt')
def setUp(self): super(TestInterface, self).setUp() path = os.path.dirname(os.path.os.path.realpath(__file__)) path = os.path.join(path, 'assets/test1.tmx') self.world = World(path) self.spawn_point = self.world.get_object_by_name('spawn1') self.world_update_task = task.LoopingCall(self.world.processing_step) self.world_update_task.clock = self.clock self.world_update_task.start(1.0 / 30) self.networking_task = task.LoopingCall(self.world.networking_step) self.networking_task.clock = self.clock self.networking_task.start(1.0 / 30) self.connection = Connection(self.world) self.last_callback_data = None
def onWantPlay(self): self.interface = Connection(self.factory.world, self.factory.cache) self.interface.on('update', self.send_messages) self.interface.on('frame', self.send_messages) self.interface.on('remove', self.send_messages) self.interface.on('meta', self.broadcast_meta_update) self.factory.register(self) #force initial full update self.interface.trigger('step') #then send all meta, probably should live somewhere else for conn in self.factory.clients: msg = simplejson.dumps(conn.interface.meta, separators=(',', ':')) self.sendMessage(msg) #finally send 'weclome msg', at this point game should be playable on the client-side welcome_pack = { "id": self.interface.archer.id, "session_id": self.interface.session_id.hex } self.sendMessage(simplejson.dumps(welcome_pack, separators=(',', ':')))
def setUp(self): super(TestInterface, self).setUp() path = os.path.dirname(os.path.os.path.realpath(__file__)) path = os.path.join(path, 'assets/test1.tmx') self.world = World(path) self.spawn_point = self.world.get_object_by_name('spawn1') self.world_update_task = task.LoopingCall(self.world.processing_step) self.world_update_task.clock = self.clock self.world_update_task.start(1.0/30) self.networking_task = task.LoopingCall(self.world.networking_step) self.networking_task.clock = self.clock self.networking_task.start(1.0/30) self.connection = Connection(self.world) self.last_callback_data = None
class ProfileInterface(BaseTestCase): def setUp(self): super(ProfileInterface, self).setUp() self.pr = cProfile.Profile() self.path = os.path.dirname(os.path.os.path.realpath(__file__)) path = os.path.join(self.path, '../../resources/map.tmx') self.world = World(path) self.cache = MessageCache(self.world) self.spawn_point = self.world.get_object_by_name('spawn1') self.world_update_task = task.LoopingCall(self.world.processing_step) self.world_update_task.clock = self.clock self.world_update_task.start(1.0/30) self.networking_task = task.LoopingCall(self.world.networking_step) self.networking_task.clock = self.clock self.networking_task.start(1.0/30) def process_stats(self, filename): self.ps = pstats.Stats(self.pr) f = open(os.path.join(self.path, 'data', filename), 'w') pstats.Stats(self.pr, stream=f).strip_dirs().sort_stats('cumulative').print_stats() f.close() return "%i calls" % self.ps.total_calls, "%.3f sec" % self.ps.total_tt def test_get_frame(self): """ Test raw execution performance of the 'get_frame'""" self.connection = Connection(self.world, self.cache) archers = list() for i in range(50): archer = Archer(self.world, reactor=self.clock) archer.spawn(self.spawn_point) archer.want_move(directions['south']) archers.append(archer) self.pr.enable() for i in range(100): self.connection.get_frame() self.pr.disable() print self.process_stats('test_get_frame.txt') def test_building_frames(self): """ Test performance of building frame for many players """ connections = list for i in range(100): connection = Connection(self.world, self.cache) connection.get_update() self.pr.enable() self.clock.advance(1) self.pr.disable() print self.process_stats('test_building_frames.txt') def test_get_update(self): """ Test raw execution performance of the 'get_update'""" self.connection = Connection(self.world, self.cache) archers = list() for i in range(50): archer = Archer(self.world, reactor=self.clock) archer.spawn(self.spawn_point) archer.want_move(directions['south']) archers.append(archer) self.pr.enable() for i in range(100): self.connection.get_update() self.pr.disable() print self.process_stats('test_get_update.txt') def test_buidling_updates(self): """ Test performance of building update messages for many players""" connections = list for i in range(100): connection = Connection(self.world, self.cache) connection.get_frame() self.pr.enable() self.clock.advance(1) self.pr.disable() print self.process_stats('test_buidling_updates.txt')
class UserCommunication(WebSocketServerProtocol): # def __init__(self, world, *args, **kwargs): # self.world = world # # WebSocketServerProtocol.__init__(self) def onMessage(self, msg, binary): if (binary): messages = unpack_mesages(msg) if (not hasattr(self, "interface")): try: if (messages[0]['action'] == 'init'): self.onWantPlay() except (IndexError, KeyError): logging.warning( "Got garbage message {}, discarding".format(msg)) else: for msg in messages: self.interface.trigger('useraction', msg) else: try: msg = simplejson.loads(msg) self.interface.trigger('usermsg', msg) except Exception: #ping pong if (msg == "?"): self.sendMessage("!") else: logging.warning( "Unable to decode meta msg %s coming from the client" % msg) def onOpen(self): server_pack = { "players": len(self.factory.clients), "location": self.factory.game.config['location'], "maxPlayers": self.factory.game.config['maxplayers'], "map": self.factory.world.map.properties['name'] } self.sendMessage(simplejson.dumps(server_pack, separators=(',', ':'))) def onWantPlay(self): self.interface = Connection(self.factory.world, self.factory.cache) self.interface.on('update', self.send_messages) self.interface.on('frame', self.send_messages) self.interface.on('remove', self.send_messages) self.interface.on('meta', self.broadcast_meta_update) self.factory.register(self) #force initial full update self.interface.trigger('step') #then send all meta, probably should live somewhere else for conn in self.factory.clients: msg = simplejson.dumps(conn.interface.meta, separators=(',', ':')) self.sendMessage(msg) #finally send 'weclome msg', at this point game should be playable on the client-side welcome_pack = { "id": self.interface.archer.id, "session_id": self.interface.session_id.hex } self.sendMessage(simplejson.dumps(welcome_pack, separators=(',', ':'))) def connectionLost(self, reason): WebSocketServerProtocol.connectionLost(self, reason) self.factory.unregister(self) def onClose(self, wasClean, code, reason): if (hasattr(self, 'interface')): self.interface.trigger('disconnect') def send_messages(self, messages): if (len(messages)): self.sendMessage(pack_messages(messages), True) def broadcast_meta_update(self, meta): msg = simplejson.dumps(meta, separators=(',', ':')) self.factory.broadcast(msg)
class UserCommunication(WebSocketServerProtocol): # def __init__(self, world, *args, **kwargs): # self.world = world # # WebSocketServerProtocol.__init__(self) def onMessage(self, msg, binary): if(binary): messages = unpack_mesages(msg) if(not hasattr(self, "interface")): try: if(messages[0]['action'] == 'init'): self.onWantPlay() except (IndexError, KeyError): logging.warning("Got garbage message {}, discarding".format(msg)) else: for msg in messages: self.interface.trigger('useraction', msg) else: try: msg = simplejson.loads(msg) self.interface.trigger('usermsg', msg) except Exception: #ping pong if(msg == "?"): self.sendMessage("!") else: logging.warning("Unable to decode meta msg %s coming from the client" % msg) def onOpen(self): server_pack = { "players": len(self.factory.clients), "location": self.factory.game.config['location'], "maxPlayers": self.factory.game.config['maxplayers'], "map": self.factory.world.map.properties['name'] } self.sendMessage(simplejson.dumps(server_pack, separators=(',', ':'))) def onWantPlay(self): self.interface = Connection(self.factory.world, self.factory.cache) self.interface.on('update', self.send_messages) self.interface.on('frame', self.send_messages) self.interface.on('remove', self.send_messages) self.interface.on('meta', self.broadcast_meta_update) self.factory.register(self) #force initial full update self.interface.trigger('step') #then send all meta, probably should live somewhere else for conn in self.factory.clients: msg = simplejson.dumps(conn.interface.meta, separators=(',', ':')) self.sendMessage(msg) #finally send 'weclome msg', at this point game should be playable on the client-side welcome_pack = { "id": self.interface.archer.id, "session_id": self.interface.session_id.hex } self.sendMessage(simplejson.dumps(welcome_pack, separators=(',', ':'))) def connectionLost(self, reason): WebSocketServerProtocol.connectionLost(self, reason) self.factory.unregister(self) def onClose(self, wasClean, code, reason): if(hasattr(self, 'interface')): self.interface.trigger('disconnect') def send_messages(self, messages): if(len(messages)): self.sendMessage(pack_messages(messages), True) def broadcast_meta_update(self, meta): msg = simplejson.dumps(meta, separators=(',', ':')) self.factory.broadcast(msg)
class TestInterface(BaseTestCase): def setUp(self): super(TestInterface, self).setUp() path = os.path.dirname(os.path.os.path.realpath(__file__)) path = os.path.join(path, 'assets/test1.tmx') self.world = World(path) self.spawn_point = self.world.get_object_by_name('spawn1') self.world_update_task = task.LoopingCall(self.world.processing_step) self.world_update_task.clock = self.clock self.world_update_task.start(1.0/30) self.networking_task = task.LoopingCall(self.world.networking_step) self.networking_task.clock = self.clock self.networking_task.start(1.0/30) self.connection = Connection(self.world) self.last_callback_data = None def tearDown(self): self.world_update_task.stop() self.networking_task.stop() def get_items_expected(self, expected_attr): # items_expected = self.world.object_lookup_by_name items_expected = self.world.object_index items_expected = {k: v for k, v in items_expected.items() if hasattr(v, expected_attr)} return items_expected def callback(self, *args, **kwargs): self.last_callback_data = list(*args) def get_last_callback_arguments(self): tmp = self.last_callback_data self.last_callback_data = None return tmp def test_get_frame(self): self.archer = Archer(self.world, reactor=self.clock) self.archer.spawn(self.spawn_point) self.connection.on('frame', self.callback) self.clock.advance(1) frame = self.get_last_callback_arguments() items_expected = self.get_items_expected('get_frame_message') self.assertEqual(len(frame), len(items_expected)) for message in frame: matching_expected_item = items_expected.pop(message['id']) self.assertEqual(message['x'], int(settings.PPM*matching_expected_item.get_position()['x'])) self.assertEqual(message['y'], int(settings.PPM*matching_expected_item.get_position()['y'])) self.assertEqual(message['direction'], matching_expected_item.get_direction()) self.assertEqual(len(items_expected), 0) self.clock.advance(1) frame = self.get_last_callback_arguments() # Nothing has changed! self.assertEqual(len(frame), 0) self.archer.want_move(directions['south']) self.advance_clock(1) frame = self.get_last_callback_arguments() self.assertEqual(len(frame), 1) message = frame.pop() self.assertEqual(message['x'], int(settings.PPM*self.archer.get_position()['x'])) self.assertEqual(message['y'], int(settings.PPM*self.archer.get_position()['y'])) self.assertEqual(message['direction'], self.archer.get_direction()) def test_get_update(self): self.connection.on('update', self.callback) self.clock.advance(1) items_expected = self.get_items_expected('get_update_message') update = self.get_last_callback_arguments() self.assertEqual(len(update), len(items_expected)) for message in update: self.assertIsInstance(message, UpdateMessage) matching_expected_item = items_expected.pop(message['id']) self.assertEqual(message['id'], matching_expected_item.id) # self.assertEqual(message['center'], False) #TEST MORE self.assertEqual(len(items_expected), 0) self.clock.advance(1) update = self.get_last_callback_arguments() self.assertIsNone(update) self.archer = Archer(self.world, reactor=self.clock) self.archer.spawn(self.spawn_point) self.clock.advance(1) update = self.get_last_callback_arguments() self.assertEqual(len(update), 1) def get_fake_msg(self, x=1, y=3.33, direction=directions['south']): msg = FakeMessage() msg['x'] = x msg['y'] = y msg['direction'] = direction return msg def test_packing(self): msg = self.get_fake_msg() packed = msg.pack() self.assertEqual(packed[0:4], struct.pack('!I', 1)) self.assertEqual(packed[4:8], struct.pack('!f', 3.33)) self.assertEqual(packed[8:9], struct.pack('!B', DirectionMessageMixin.direction_lookup[directions['south']])) def test_dehydration(self): x = 12 y = 4.44 dir = DirectionMessageMixin.direction_lookup[directions['west']] dehydrated_item = [x, y, dir] msg = FakeMessage.from_dehydrated(dehydrated_item) self.assertEqual(msg['x'], x) self.assertEqual(msg['y'], y) self.assertEqual(msg['direction'], directions['west']) def test_unpacking(self): # packed = '\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x02\x02\n' x = 12 y = 7.77 dir = DirectionMessageMixin.direction_lookup[directions['west']] packed = struct.pack("!I", x) + struct.pack("!f", y) + struct.pack("!B", dir) + "\n" msg = FakeMessage.from_packed(packed) self.assertEqual(msg['x'], x) self.assertAlmostEqual(msg['y'], y, places=4) self.assertEqual(msg['direction'], directions['west']) def test_message_packing(self): msg = self.get_fake_msg() msg2 = self.get_fake_msg(x=5, direction=directions['east']) result = pack_messages([msg, msg2]) expected_byte_length = 1 + 2 * msg.get_byte_length() self.assertEqual(len(result), expected_byte_length) def test_message_unpacking(self): x1 = 12 y1 = 4.44 dir1 = DirectionMessageMixin.direction_lookup[directions['west']] packed = struct.pack("!I", x1) + struct.pack("!f", y1) + struct.pack("!B", dir1) x2 = 42 y2 = 9.987654 dir2 = DirectionMessageMixin.direction_lookup[directions['north']] packed = packed + struct.pack("!I", x2) + struct.pack("!f", y2) + struct.pack("!B", dir2) + "\n" packed = struct.pack("!B", 255) + packed messages = unpack_mesages(packed, message_types=message_types) self.assertEqual(len(messages), 2) self.assertEqual(messages[0]['x'], x1) self.assertAlmostEqual(messages[0]['y'], y1, places=4) self.assertEqual(messages[0]['direction'], directions['west']) self.assertEqual(messages[1]['x'], x2) self.assertAlmostEqual(messages[1]['y'], y2, places=4) self.assertEqual(messages[1]['direction'], directions['north']) def test_eating_own_dog_food(self): msg = self.get_fake_msg(y=1.0) packed = msg.pack() unpacked = FakeMessage.from_packed(packed) self.assertEqual(msg, unpacked)
class TestInterface(BaseTestCase): def setUp(self): super(TestInterface, self).setUp() path = os.path.dirname(os.path.os.path.realpath(__file__)) path = os.path.join(path, 'assets/test1.tmx') self.world = World(path) self.spawn_point = self.world.get_object_by_name('spawn1') self.world_update_task = task.LoopingCall(self.world.processing_step) self.world_update_task.clock = self.clock self.world_update_task.start(1.0 / 30) self.networking_task = task.LoopingCall(self.world.networking_step) self.networking_task.clock = self.clock self.networking_task.start(1.0 / 30) self.connection = Connection(self.world) self.last_callback_data = None def tearDown(self): self.world_update_task.stop() self.networking_task.stop() def get_items_expected(self, expected_attr): # items_expected = self.world.object_lookup_by_name items_expected = self.world.object_index items_expected = { k: v for k, v in items_expected.items() if hasattr(v, expected_attr) } return items_expected def callback(self, *args, **kwargs): self.last_callback_data = list(*args) def get_last_callback_arguments(self): tmp = self.last_callback_data self.last_callback_data = None return tmp def test_get_frame(self): self.archer = Archer(self.world, reactor=self.clock) self.archer.spawn(self.spawn_point) self.connection.on('frame', self.callback) self.clock.advance(1) frame = self.get_last_callback_arguments() items_expected = self.get_items_expected('get_frame_message') self.assertEqual(len(frame), len(items_expected)) for message in frame: matching_expected_item = items_expected.pop(message['id']) self.assertEqual( message['x'], int(settings.PPM * matching_expected_item.get_position()['x'])) self.assertEqual( message['y'], int(settings.PPM * matching_expected_item.get_position()['y'])) self.assertEqual(message['direction'], matching_expected_item.get_direction()) self.assertEqual(len(items_expected), 0) self.clock.advance(1) frame = self.get_last_callback_arguments() # Nothing has changed! self.assertEqual(len(frame), 0) self.archer.want_move(directions['south']) self.advance_clock(1) frame = self.get_last_callback_arguments() self.assertEqual(len(frame), 1) message = frame.pop() self.assertEqual(message['x'], int(settings.PPM * self.archer.get_position()['x'])) self.assertEqual(message['y'], int(settings.PPM * self.archer.get_position()['y'])) self.assertEqual(message['direction'], self.archer.get_direction()) def test_get_update(self): self.connection.on('update', self.callback) self.clock.advance(1) items_expected = self.get_items_expected('get_update_message') update = self.get_last_callback_arguments() self.assertEqual(len(update), len(items_expected)) for message in update: self.assertIsInstance(message, UpdateMessage) matching_expected_item = items_expected.pop(message['id']) self.assertEqual(message['id'], matching_expected_item.id) # self.assertEqual(message['center'], False) #TEST MORE self.assertEqual(len(items_expected), 0) self.clock.advance(1) update = self.get_last_callback_arguments() self.assertIsNone(update) self.archer = Archer(self.world, reactor=self.clock) self.archer.spawn(self.spawn_point) self.clock.advance(1) update = self.get_last_callback_arguments() self.assertEqual(len(update), 1) def get_fake_msg(self, x=1, y=3.33, direction=directions['south']): msg = FakeMessage() msg['x'] = x msg['y'] = y msg['direction'] = direction return msg def test_packing(self): msg = self.get_fake_msg() packed = msg.pack() self.assertEqual(packed[0:4], struct.pack('!I', 1)) self.assertEqual(packed[4:8], struct.pack('!f', 3.33)) self.assertEqual( packed[8:9], struct.pack( '!B', DirectionMessageMixin.direction_lookup[directions['south']])) def test_dehydration(self): x = 12 y = 4.44 dir = DirectionMessageMixin.direction_lookup[directions['west']] dehydrated_item = [x, y, dir] msg = FakeMessage.from_dehydrated(dehydrated_item) self.assertEqual(msg['x'], x) self.assertEqual(msg['y'], y) self.assertEqual(msg['direction'], directions['west']) def test_unpacking(self): # packed = '\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x02\x02\n' x = 12 y = 7.77 dir = DirectionMessageMixin.direction_lookup[directions['west']] packed = struct.pack("!I", x) + struct.pack("!f", y) + struct.pack( "!B", dir) + "\n" msg = FakeMessage.from_packed(packed) self.assertEqual(msg['x'], x) self.assertAlmostEqual(msg['y'], y, places=4) self.assertEqual(msg['direction'], directions['west']) def test_message_packing(self): msg = self.get_fake_msg() msg2 = self.get_fake_msg(x=5, direction=directions['east']) result = pack_messages([msg, msg2]) expected_byte_length = 1 + 2 * msg.get_byte_length() self.assertEqual(len(result), expected_byte_length) def test_message_unpacking(self): x1 = 12 y1 = 4.44 dir1 = DirectionMessageMixin.direction_lookup[directions['west']] packed = struct.pack("!I", x1) + struct.pack("!f", y1) + struct.pack( "!B", dir1) x2 = 42 y2 = 9.987654 dir2 = DirectionMessageMixin.direction_lookup[directions['north']] packed = packed + struct.pack("!I", x2) + struct.pack( "!f", y2) + struct.pack("!B", dir2) + "\n" packed = struct.pack("!B", 255) + packed messages = unpack_mesages(packed, message_types=message_types) self.assertEqual(len(messages), 2) self.assertEqual(messages[0]['x'], x1) self.assertAlmostEqual(messages[0]['y'], y1, places=4) self.assertEqual(messages[0]['direction'], directions['west']) self.assertEqual(messages[1]['x'], x2) self.assertAlmostEqual(messages[1]['y'], y2, places=4) self.assertEqual(messages[1]['direction'], directions['north']) def test_eating_own_dog_food(self): msg = self.get_fake_msg(y=1.0) packed = msg.pack() unpacked = FakeMessage.from_packed(packed) self.assertEqual(msg, unpacked)