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_bad_name(self): '''Tries to born a robot with an invalid name. Should be fail.''' population_control = PopulationControl() database = MemcachedDatabase() database.add_password("OIkdj981HJDJHcnm_1") database.add_password("OIkdj981HJDJHcnm_2") database.add_password("OIkdj981HJDJHcnm_3") database.add_password("OIkdj981HJDJHcnm_4") database.commit() long_name = "n" * (MAX_ROBOT_NAME + 1) with self.assertRaises(LongRobotNameError): population_control.execute_command("OIkdj981HJDJHcnm_1", "born", [None, long_name]) database.rollback() with self.assertRaises(LongRobotNameError): population_control.execute_command("OIkdj981HJDJHcnm_2", "born", [None, None]) database.rollback() with self.assertRaises(LongRobotNameError): population_control.execute_command("OIkdj981HJDJHcnm_3", "born", [None, b"some bytes"]) database.rollback() with self.assertRaises(LongRobotNameError): population_control.execute_command("OIkdj981HJDJHcnm_4", "born", [None, database]) database.rollback()
def test_bad_name(self): '''Tries to born a robot with an invalid name. Should be fail.''' population_control = PopulationControl() database = MemcachedDatabase() database.add_password("OIkdj981HJDJHcnm_1") database.add_password("OIkdj981HJDJHcnm_2") database.add_password("OIkdj981HJDJHcnm_3") database.add_password("OIkdj981HJDJHcnm_4") database.commit() long_name = "n" * (MAX_ROBOT_NAME + 1) with self.assertRaises(LongRobotNameError): population_control.execute_command("OIkdj981HJDJHcnm_1", "born", [None, long_name]) database.rollback() with self.assertRaises(LongRobotNameError): population_control.execute_command("OIkdj981HJDJHcnm_2", "born", [None, None]) database.rollback() with self.assertRaises(LongRobotNameError): population_control.execute_command("OIkdj981HJDJHcnm_3", "born", [None, b"some bytes"]) database.rollback() with self.assertRaises(LongRobotNameError): population_control.execute_command("OIkdj981HJDJHcnm_4", "born", [None, database]) database.rollback()
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_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_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): '''Tests a good scenario.''' population_control = PopulationControl() database = MemcachedDatabase() database.add_password("iujeh87UYh6512ewQ") robot_info = population_control.execute_command("iujeh87UYh6512ewQ", "born", [None, "RDaniel"]) database.commit() gotted_robot = database.get_robot(robot_info['robot_id']) self.assertEqual(gotted_robot.get_name(), "RDaniel")
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): '''Tests a good scenario.''' population_control = PopulationControl() database = MemcachedDatabase() database.add_password("iujeh87UYh6512ewQ") robot_info = population_control.execute_command( "iujeh87UYh6512ewQ", "born", [None, "RDaniel"]) database.commit() gotted_robot = database.get_robot(robot_info['robot_id']) self.assertEqual(gotted_robot.get_name(), "RDaniel")
def initialize_database(initial_passwords): database = MemcachedDatabase() database.initialize() for password in initial_passwords: database.add_password(password)
class PopulationControl: '''Controls the population of the world. i.e. controlling if a robot can have a child, or gives birth to new robots. ''' def __init__(self): self._authenticator = Authenticator() self._database = MemcachedDatabase() self._world = World() self._id_generator = IDGenerator() self._configs = Configs() 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))) if command == "born": return self._born(password, args) elif command == "give_birth": return self._give_birth(password, args) def _born(self, password, args): '''Gives birth to a robot for the first time. @param args: List of arguments. The first argument can be a parent robot. If provided, the new robot will be born software near its parent. If not, it will be born on a random place. ''' parent_robot_id = None if len(args) > 0: parent_robot_id = args[0] if parent_robot_id is not None: if not isinstance(parent_robot_id, str): raise InvalidArgumentsError( "`parent_robot_id' must be `str', not {0}".format( type(parent_robot_id))) parent_robot = self._database.get_robot(parent_robot_id) born_location = parent_robot.get_location() else: world_size = self._world.get_size() born_location = (random.randint(0, world_size[0] - 1), random.randint(0, world_size[1] - 1)) robot_name = "" if len(args) == 2: robot_name = args[1] self._authenticator.authenticate_new_robot(password) new_robot = Robot(self._id_generator.get_robot_id(), self._id_generator.get_password(), name=robot_name) self._world.add_robot(new_robot, (born_location[0], born_location[1])) return { 'robot_id': new_robot.get_id(), 'password': new_robot.get_password() } def _give_birth(self, password, args): '''Checks if robot has the permission to give birth to a child. If so, it generates and returns a new password. ''' if len(args) != 1: raise InvalidArgumentsError( "`give_birth' takes exactly one argument.") robot_id = args[0] if not isinstance(robot_id, str): raise InvalidArgumentsError( "Expected {0} as robot_id, found {1}".format( type(str), type(args[0]))) robot = self._database.get_robot(robot_id, for_update=True) required_honor = self._configs.get_robots_birth_required_honor() if robot.get_honor() < required_honor: raise NotEnoughHonorError( "Robot needs {0} honor to give birth, but has {1}.".format( required_honor, robot.get_honor())) robot.set_honor(robot.get_honor() - required_honor) # This while is exists, to prevent generating duplicated passwords. while True: try: new_password = self._id_generator.get_password() self._database.add_password(new_password) break except DuplicatedPasswordError: # pragma: no cover continue return new_password
def initialize_database(initial_passwords): database = MemcachedDatabase() database.initialize() for password in initial_passwords: database.add_password(password)