def test_water_level(self): '''Tests if water level increases after watering.''' database = MemcachedDatabase() world = World() robot = Robot("198.1287.fkdfjei", "123") robot.set_location((5, 0)) robot.set_has_water(True) plant = Plant() plant.set_water_level(30) world.plant(plant, (5, 0)) database.commit() action = WaterAction() action.do_action(robot, ["198.1287.fkdfjei"]) database.commit() updated_square = world.get_square((5, 0)) plant = updated_square.get_plant() # Checking if honor increased. self.assertEqual(robot.get_honor(), 1) self.assertEqual(plant.get_water_level(), 100) self.assertFalse(robot.get_has_water())
def setUpClass(cls): # Creating a robot that all the tests will use. database = MemcachedDatabase() world = World() robot = Robot(TestGiveBirth.ROBOT_ID, "123") world.add_robot(robot, (0, 14)) database.commit()
def setUpClass(cls): # Creating a robot that all the tests will use. database = MemcachedDatabase() world = World() robot = Robot(TestGiveBirth.ROBOT_ID, "123") world.add_robot(robot, (0, 14)) database.commit()
class Communicator(Singleton): '''Interface between listeners and the application.''' def _initialize(self): self._database = MemcachedDatabase() self._action_manager = ActionManager() self._population_control = PopulationControl() self._admin_handler = AdminHandler() def execute_command(self, password, command, args): '''Execute client's command.''' try: if command in ["born", "give_birth"]: result = self._population_control.execute_command(password, command, args) elif command == "map_data": result = self._admin_handler.execute_command(password, command, args) else: result = self._action_manager.do_action(password, command, args) # Committing or rollbacking all changes after the completion of execution. self._database.commit() return result except Exception: self._database.rollback() raise
def test_specific_point(self): '''Gets information of a specific point, and check its result.''' database = MemcachedDatabase() new_robot = Robot("oie982736hhjf", "lo098173635") new_robot.set_location((9, 4)) database.add_robot(new_robot, (9, 4)) database.commit() action_manager = ActionManager() info = action_manager.do_action(new_robot.get_password(), "sense", [new_robot.get_id()]) self.assertEqual(len(info), 9) self.assertEqual(info["9,4"], {"surface_type": MapSquareTypes.SOIL, "robot": True, "plant": None}) self.assertEqual(info["9,3"], {"surface_type": MapSquareTypes.WATER, "robot": False, "plant": None}) self.assertEqual(info["10,5"], {"surface_type": MapSquareTypes.SOIL, "robot": False, "plant": None}) self.assertEqual(info["8,4"], {"surface_type": MapSquareTypes.SOIL, "robot": False, "plant": None})
def setUpClass(cls): row = [MapSquare(MapSquareTypes.WATER, (0, 18)), MapSquare(MapSquareTypes.SOIL, (1, 18)), MapSquare(MapSquareTypes.SAND, (2, 18))] database = MemcachedDatabase() database.add_square_row(row)
def test_no_plant(self): '''Tests when there's no plant to eat.''' action_manager = ActionManager() database = MemcachedDatabase() with self.assertRaises(NoPlantToEat): action_manager.do_action("123", "eat", [TestEatAction.ROBOT_ID]) database.rollback()
def test_invalid_location(self): '''Tests adding a robot to an invalid location.''' database = MemcachedDatabase() robot = Robot("invalid_location_robot_1863", "123") with self.assertRaises(InvalidLocationError): self._world.add_robot(robot, (19872, 1190)) database.commit()
def test_duplicate_password(self): '''Adds a password twice. Should raise an exception.''' database = MemcachedDatabase() database.add_password("test_duplicate_8172") with self.assertRaises(DuplicatedPasswordError): database.add_password("test_duplicate_8172")
def test_no_plant(self): '''Tests when there's no plant to eat.''' action_manager = ActionManager() database = MemcachedDatabase() with self.assertRaises(NoPlantToEat): action_manager.do_action("123", "eat", [TestEatAction.ROBOT_ID]) database.rollback()
class AdminHandler: '''Handles the requests related to GUI.''' def __init__(self): self._authenticator = Authenticator() self._database = MemcachedDatabase() def execute_command(self, password, command, args): '''Executes the specified command.''' if not isinstance(password, str): raise InvalidArgumentsError( "Expected {0} as password, found {1}.".format( type(str), type(password))) self._authenticator.authenticate_admin(password) if command == "map_data": return self._get_map_data(args) def _get_map_data(self, args): '''Returns the information about the world's map. @args: Should be a list of locations. Each location is a string in the form of "x,y". ''' squares = self._database.get_squares(args) result = {} for location, square in squares.items(): robot_id = square.get_robot_id() if robot_id is not None: robot = self._database.get_robot(robot_id) robot_info = { 'name': robot.get_name(), 'has_water': robot.get_has_water(), 'energy': robot.get_energy(), 'life': robot.get_life(), 'honor': robot.get_honor() } else: robot_info = None plant = square.get_plant() if plant is not None: plant_info = { 'water_level': plant.get_water_level(), 'matured': plant.is_matured(), 'age': plant.get_age() } else: plant_info = None result[location] = { 'surface_type': square.get_type(), 'plant': plant_info, 'robot': robot_info } return result
def setUpClass(cls): # Addin a robot to the world. All the tests would use this robot. robot = Robot(cls.ROBOT_ID, "123") world = World() world.add_robot(robot, cls.LOCATION) database = MemcachedDatabase() database.commit()
def setUpClass(cls): row = [ MapSquare(MapSquareTypes.WATER, (0, 18)), MapSquare(MapSquareTypes.SOIL, (1, 18)), MapSquare(MapSquareTypes.SAND, (2, 18)) ] database = MemcachedDatabase() database.add_square_row(row)
def setUpClass(cls): # Addin a robot to the world. All the tests would use this robot. robot = Robot(cls.ROBOT_ID, "123") world = World() world.add_robot(robot, cls.LOCATION) database = MemcachedDatabase() database.commit()
def test_invalid_location(self): '''Tests if database checks for invalid locations.''' database = MemcachedDatabase() new_robot = Robot("test_invalid_location_19887", "123") with self.assertRaises(InvalidLocationError): database.add_robot(new_robot, (91872, 16652)) database.commit()
def test_locked(self): '''Tests with a locked square.''' action_manager = ActionManager() database = MemcachedDatabase() database.get_square(TestEatAction.LOCATION, for_update=True) with self.assertRaises(LockAlreadyAquiredError): action_manager.do_action("123", "eat", [TestEatAction.ROBOT_ID]) database.rollback()
def test_locked_robot(self): '''Tests with a locked robot.''' population_control = PopulationControl() database = MemcachedDatabase() database.get_robot(TestGiveBirth.ROBOT_ID, for_update=True) with self.assertRaises(LockAlreadyAquiredError): population_control.execute_command("123", "give_birth", [TestGiveBirth.ROBOT_ID]) database.rollback()
def test_bad_argument(self): '''Tests when sending bad arguments to the action.''' action_manager = ActionManager() database = MemcachedDatabase() with self.assertRaises(InvalidArgumentsError): action_manager.do_action("123", "eat", [TestEatAction.ROBOT_ID, None]) database.rollback() with self.assertRaises(InvalidArgumentsError): action_manager.do_action("123", "eat", [TestEatAction.ROBOT_ID, "", 9]) database.rollback()
def test_rollback(self): '''Tests if calling rollback works correctly.''' database = MemcachedDatabase() new_robot = Robot("test_rollback_87162", "123") database.add_robot(new_robot, (1, 1)) database.rollback() database.commit() with self.assertRaises(RobotNotFoundError): database.get_robot("test_rollback_87162")
def test_duplicate_add(self): '''Adding two robots with same ID. Should be failed.''' database = MemcachedDatabase() new_robot = Robot("test_duplicate_add_", "123") database.add_robot(new_robot, (1, 1)) database.commit() robot2 = Robot("test_duplicate_add_", "123") with self.assertRaises(CannotAddObjectError): database.add_robot(robot2, (1, 2)) database.commit()
def test_blocked_location(self): '''Tests adding the robot to a blocked square.''' database = MemcachedDatabase() robot = Robot("test_blocked_location_91882", "123") # There's a rock here. self._world.add_robot(robot, (6, 1)) database.commit() received_robot = database.get_robot(robot.get_id()) self.assertNotEqual(received_robot.get_location(), (6, 1))
def test_ok(self): '''Tests a good scenario.''' row = [MapSquare(MapSquareTypes.SOIL, (0, 17))] database = MemcachedDatabase() database.add_square_row(row) plant_action = PlantAction() robot = Robot("18873.182873.1123", "123") robot.set_location((0, 17)) plant_action.do_action(robot, ["18873.182873.1123"])
def test_ok(self): '''Tests a good scenario.''' row = [MapSquare(MapSquareTypes.SOIL, (0, 17))] database = MemcachedDatabase() database.add_square_row(row) plant_action = PlantAction() robot = Robot("18873.182873.1123", "123") robot.set_location((0, 17)) plant_action.do_action(robot, ["18873.182873.1123"])
def test_corner(self): '''Tests getting a corner of the map.''' database = MemcachedDatabase() new_robot = Robot("0981kdjieu871", "oie987163") new_robot.set_location((0, 1)) database.add_robot(new_robot, (0, 1)) database.commit() action_manager = ActionManager() info = action_manager.do_action(new_robot.get_password(), "sense", [new_robot.get_id()]) self.assertEqual(len(info), 6)
def test_duplicate(self): '''Tests adding duplicate robot.''' database = MemcachedDatabase() robot = Robot("world_duplicate_robot_8722", "123") self._world.add_robot(robot, (5, 1)) database.commit() robot_2 = Robot("world_duplicate_robot_8722", "1236") with self.assertRaises(CannotAddObjectError): self._world.add_robot(robot_2, (5, 2)) database.commit()
def test_blind_point(self): '''Gets information of a point, but don't care about the result.''' database = MemcachedDatabase() new_robot = Robot("1873yudhNCbueio", "ueijdnchiop") new_robot.set_location((9, 7)) database.add_robot(new_robot, (9, 7)) database.commit() action_manager = ActionManager() info = action_manager.do_action(new_robot.get_password(), "sense", [new_robot.get_id()]) self.assertEqual(len(info), 9)
def test_blocking_object(self): '''Tests moving toward a blocking object.''' robot_id = "test_invalid_location_8765112" robot = Robot(robot_id, "123") world = World() action_manager = ActionManager() database = MemcachedDatabase() world.add_robot(robot, (11, 6)) database.commit() with self.assertRaises(LocationIsBlockedError): action_manager.do_action("123", "move", [robot_id, "W"])
class AdminHandler: '''Handles the requests related to GUI.''' def __init__(self): self._authenticator = Authenticator() self._database = MemcachedDatabase() def execute_command(self, password, command, args): '''Executes the specified command.''' if not isinstance(password, str): raise InvalidArgumentsError("Expected {0} as password, found {1}.".format(type(str), type(password))) self._authenticator.authenticate_admin(password) if command == "map_data": return self._get_map_data(args) def _get_map_data(self, args): '''Returns the information about the world's map. @args: Should be a list of locations. Each location is a string in the form of "x,y". ''' squares = self._database.get_squares(args) result = {} for location, square in squares.items(): robot_id = square.get_robot_id() if robot_id is not None: robot = self._database.get_robot(robot_id) robot_info = {'name': robot.get_name(), 'has_water': robot.get_has_water(), 'energy': robot.get_energy(), 'life': robot.get_life(), 'honor': robot.get_honor()} else: robot_info = None plant = square.get_plant() if plant is not None: plant_info = {'water_level': plant.get_water_level(), 'matured': plant.is_matured(), 'age': plant.get_age()} else: plant_info = None result[location] = {'surface_type': square.get_type(), 'plant': plant_info, 'robot': robot_info} return result
def test_with_parent(self): '''Tests borning a robot with a parent.''' population_control = PopulationControl() database = MemcachedDatabase() database.add_password("oijdnnh76153WEd") robot = Robot("test_with_parent_18873", "123") database.add_robot(robot, (14, 1)) database.commit() population_control.execute_command( "oijdnnh76153WEd", "born", ["test_with_parent_18873", "My Child"]) database.rollback()
def test_ok(self): '''Adds a good robot object to the world.''' database = MemcachedDatabase() robot = Robot("world_ok_robot_38364", "123") self._world.add_robot(robot, (5, 0)) database.commit() gotted_robot = database.get_robot(robot.get_id()) self.assertEqual(gotted_robot.get_alive(), robot.get_alive()) all_robots = database.get_all_robot_ids() self.assertIn(robot.get_id(), all_robots)
def __init__(self): self._authenticator = Authenticator() self._database = MemcachedDatabase() configs = Configs() self._robots_action_delay = configs.get_robots_actions_delay() / 1000 self._actions = {'status': StatusAction(), 'sense': SenseAction(), 'move': MoveAction(), 'plant': PlantAction(), 'pick_water': PickWaterAction(), 'info': InfoAction(), 'eat': EatAction(), 'water': WaterAction()}
def test_out_of_water(self): '''Tests if plant die after running out of water.''' plant = Plant() world = World() database = MemcachedDatabase() world.plant(plant, (4, 8)) database.commit() # Waiting for 11 cycles. time.sleep(11 * 0.03) square = world.get_square((4, 8), for_update=False) self.assertIsNone(square.get_plant())
def test_moving_outside(self): '''Tests moving a robot to outside of the world.''' robot_id = "test_moving_outside_981165" robot = Robot(robot_id, "123") world = World() action_manager = ActionManager() database = MemcachedDatabase() world.add_robot(robot, (14, 2)) database.commit() with self.assertRaises(InvalidLocationError): action_manager.do_action("123", "move", [robot_id, "E"]) database.rollback()
def test_out_of_water(self): '''Tests if plant die after running out of water.''' plant = Plant() world = World() database = MemcachedDatabase() world.plant(plant, (4, 8)) database.commit() # Waiting for 11 cycles. time.sleep(11 * 0.03) square = world.get_square((4, 8), for_update=False) self.assertIsNone(square.get_plant())
def test_bad_arguments(self): '''Calls the action with invalid arguments.''' action = InfoAction() database = MemcachedDatabase() robot = Robot("test_info_action_1293", "123") with self.assertRaises(InvalidArgumentsError): action.do_action(robot, [robot.get_id(), None]) database.rollback() with self.assertRaises(InvalidArgumentsError): action.do_action(robot, [robot.get_id(), "", "09"]) database.rollback() with self.assertRaises(InvalidArgumentsError): action.do_action(robot, [robot.get_id(), []])
def test_locked(self): '''Tests with a locked square.''' database = MemcachedDatabase() world = World() robot = Robot("test_locked_robot_190083", "123") # Setting the energy to zero, so the updater tries to update the square too. robot.set_energy(0) world.add_robot(robot, (5, 9)) database.commit() world.get_square((5, 9), for_update=True) with self.assertRaises(LockAlreadyAquiredError): database.get_robot(robot.get_id(), for_update=True)
def test_out_of_energy_robot(self): '''Tests when a robot ran out of energy.''' database = MemcachedDatabase() world = World() robot = Robot("test_out_of_energy_robot_18773", "123") robot.set_energy(0) world.add_robot(robot, (1, 9)) database.commit() got_robot = database.get_robot("test_out_of_energy_robot_18773", for_update=False) self.assertFalse(got_robot.get_alive()) square = world.get_square((1, 9)) self.assertIsNone(square.get_robot_id())
def test_out_of_life_robot(self): '''Tests when a robot ran out of life.''' database = MemcachedDatabase() world = World() robot = Robot("test_out_of_life_robot_9022", "123") robot.set_life(0) world.add_robot(robot, (0, 9)) database.commit() received_robot = database.get_robot("test_out_of_life_robot_9022", for_update=False) self.assertFalse(received_robot.get_alive()) square = world.get_square((0, 9)) self.assertIsNone(square.get_robot_id())
def test_locked_square(self): '''Tests updating a locked square.''' plant = Plant() world = World() database = MemcachedDatabase() world.plant(plant, (7, 8)) database.commit() # Locking the square. world.get_square((7, 8), for_update=True) # Sleeping one cycle. time.sleep(0.031) with self.assertRaises(LockAlreadyAquiredError): world.get_square((7, 8), for_update=False)
def test_out_of_energy_robot(self): '''Tests when a robot ran out of energy.''' database = MemcachedDatabase() world = World() robot = Robot("test_out_of_energy_robot_18773", "123") robot.set_energy(0) world.add_robot(robot, (1, 9)) database.commit() got_robot = database.get_robot("test_out_of_energy_robot_18773", for_update=False) self.assertFalse(got_robot.get_alive()) square = world.get_square((1, 9)) self.assertIsNone(square.get_robot_id())
def test_out_of_life_robot(self): '''Tests when a robot ran out of life.''' database = MemcachedDatabase() world = World() robot = Robot("test_out_of_life_robot_9022", "123") robot.set_life(0) world.add_robot(robot, (0, 9)) database.commit() received_robot = database.get_robot("test_out_of_life_robot_9022", for_update=False) self.assertFalse(received_robot.get_alive()) square = world.get_square((0, 9)) self.assertIsNone(square.get_robot_id())
def test_no_plant_square(self): '''Tests watering a square without any plant.''' database = MemcachedDatabase() robot = Robot("098kk.ski87.99", "123") robot.set_location((6, 0)) robot.set_has_water(True) action = WaterAction() action.do_action(robot, ["098kk.ski87.99"]) self.assertFalse(robot.get_has_water()) # Honor shouldn't increase because this robot didn't really watered a plant. self.assertEqual(robot.get_honor(), 0) database.rollback()
def test_double_pop(self): '''Tries to pop a password twice. Should raise an exception.''' database = MemcachedDatabase() database.add_password("test_double_pop_9864") database.pop_password("test_double_pop_9864") with self.assertRaises(InvalidPasswordError): database.pop_password("test_double_pop_9864")
def test_one_cycle(self): '''Tests if plant updates correctly after one cycle.''' plant = Plant() world = World() database = MemcachedDatabase() world.plant(plant, (3, 8)) database.commit() # Sleeping one cycle. time.sleep(0.031) square = world.get_square((3, 8), for_update=False) plant = square.get_plant() self.assertEqual(plant.get_age(), 1) self.assertEqual(plant.get_water_level(), 90)
def initialize_process( ): # pragma: no cover - This will be mocked in the tests an never runs. '''Initializes the newly forked process''' config_file_path = os.environ.get("BINARY_SKY_CONFIG_FILE") logging_config_path = os.environ.get("BINARY_SKY_LOGGING_FILE") Configs().load_configs(config_file_path) Logger().load_configs(logging_config_path) MemcachedDatabase().initialize()
def test_rollback(self): '''Tests if database rolls back the changes correctly.''' database = MemcachedDatabase() square = database.get_square((6, 2), for_update=True) square.set_robot_id("iuwuyehdmn990198283") database.rollback() database.commit() new_square = database.get_square((6, 2)) self.assertNotEqual(square.get_robot_id(), new_square.get_robot_id())
class Authenticator: def __init__(self): self._database = MemcachedDatabase() self._configs = Configs() def authenticate_robot(self, robot_object, password): '''Authenticate the robot access and its password.''' # Ensuring that password is a string. if not isinstance(password, str): raise AuthenticationFailedError("Wrong password for Robot {0}".format(robot_object.get_id())) if password != robot_object.get_password(): raise AuthenticationFailedError("Wrong password for Robot {0}".format(robot_object.get_id())) if not robot_object.get_alive(): raise AuthenticationFailedError("Robot {0} is dead!".format(robot_object.get_id())) def authenticate_new_robot(self, password): '''Authenticate if this password is valid for a new robot to join the game (e.g. born). It remove the password from the database. i.e. the password can use for only one born. @raise InvalidPasswordError: If password wasn't valid. ''' self._database.pop_password(password) def authenticate_admin(self, password): '''Authenticates an admin. Admins are the ones who can see things like world statistics. ''' admin_password = self._configs.get_server_admin_password() if admin_password is None or admin_password.isspace(): raise AuthenticationFailedError("Invalid Admin password.") if not isinstance(password, str): raise AuthenticationFailedError("Invalid Admin password.") if admin_password != password: raise AuthenticationFailedError("Invalid Admin password.")
def test_eating_not_matured(self): '''Tests when robot eat a non matured plant.''' world = World() database = MemcachedDatabase() action_manager = ActionManager() plant = Plant() plant.set_age(1) world.plant(plant, TestEatAction.LOCATION) database.commit() robot = database.get_robot(TestEatAction.ROBOT_ID, for_update=True) robot.set_energy(10) database.commit() action_manager.do_action("123", "eat", [TestEatAction.ROBOT_ID]) database.commit() updated_robot = database.get_robot(TestEatAction.ROBOT_ID) self.assertEqual(updated_robot.get_energy(), robot.get_energy() - 1)
def test_duplicate(self): '''Tests planting twice on a location.''' world = World() new_plant = Plant() world.plant(new_plant, (4, 16)) MemcachedDatabase().commit() with self.assertRaises(AlreadyPlantError): world.plant(new_plant, (4, 16))
def test_water_level(self): '''Tests if water level increases after watering.''' database = MemcachedDatabase() world = World() robot = Robot("198.1287.fkdfjei", "123") robot.set_location((5, 0)) robot.set_has_water(True) plant = Plant() plant.set_water_level(30) world.plant(plant, (5, 0)) database.commit() action = WaterAction() action.do_action(robot, ["198.1287.fkdfjei"]) database.commit() updated_square = world.get_square((5, 0)) plant = updated_square.get_plant() # Checking if honor increased. self.assertEqual(robot.get_honor(), 1) self.assertEqual(plant.get_water_level(), 100) self.assertFalse(robot.get_has_water())
def test_plant(self): '''Tests sensing a plant.''' world = World() database = MemcachedDatabase() new_robot = Robot("poeiekfm98871", "123") plant = Plant() plant.set_age(12) plant.set_water_level(60) world.plant(plant, (11, 4)) database.commit() world.add_robot(new_robot, (11, 4)) database.commit() action_manager = ActionManager() info = action_manager.do_action(new_robot.get_password(), "sense", [new_robot.get_id()]) self.assertEqual( info["11,4"], { "surface_type": MapSquareTypes.SOIL, "robot": True, "plant": { "age": 12, "water_level": 60, "matured": True } })
def test_specific_point(self): '''Gets information of a specific point, and check its result.''' database = MemcachedDatabase() new_robot = Robot("oie982736hhjf", "lo098173635") new_robot.set_location((9, 4)) database.add_robot(new_robot, (9, 4)) database.commit() action_manager = ActionManager() info = action_manager.do_action(new_robot.get_password(), "sense", [new_robot.get_id()]) self.assertEqual(len(info), 9) self.assertEqual(info["9,4"], { "surface_type": MapSquareTypes.SOIL, "robot": True, "plant": None }) self.assertEqual(info["9,3"], { "surface_type": MapSquareTypes.WATER, "robot": False, "plant": None }) self.assertEqual(info["10,5"], { "surface_type": MapSquareTypes.SOIL, "robot": False, "plant": None }) self.assertEqual(info["8,4"], { "surface_type": MapSquareTypes.SOIL, "robot": False, "plant": None })
def test_add_and_pop(self): '''Adds a password and pops it again.''' database = MemcachedDatabase() database.add_password("test_add_and_pop_8341") database.pop_password("test_add_and_pop_8341")
def test_no_cycle_passed(self): '''Tests if plant not changed if no cycle passed.''' world = World() database = MemcachedDatabase() plant = Plant() plant.set_age(2) plant.set_water_level(70) world.plant(plant, (6, 8)) database.commit() # Waiting just a little. time.sleep(0.01) square = world.get_square((6, 8), for_update=False) received_plant = square.get_plant() self.assertEqual(received_plant.get_age(), plant.get_age()) self.assertEqual(received_plant.get_water_level(), plant.get_water_level()) self.assertEqual(received_plant.get_last_update(), plant.get_last_update())