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")
Exemplo n.º 2
0
    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()
Exemplo n.º 3
0
    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")
Exemplo n.º 6
0
    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()
Exemplo n.º 7
0
    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")
Exemplo n.º 8
0
    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()
Exemplo n.º 9
0
    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")
Exemplo n.º 10
0
def initialize_database(initial_passwords):
    database = MemcachedDatabase()
    database.initialize()

    for password in initial_passwords:
        database.add_password(password)
Exemplo n.º 11
0
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
Exemplo n.º 12
0
def initialize_database(initial_passwords):
    database = MemcachedDatabase()
    database.initialize()

    for password in initial_passwords:
        database.add_password(password)