def testAddRoleToPrimarySuccess(self):
        """Test manager can add a role to a primary server successfully.

        Confirm that actions needs to be taken, e.g., restart scheduler for
        new drone to be added.
        """
        server_models.validate(role=server_models.ServerRole.ROLE.DRONE)
        server_manager_utils.check_server(mox.IgnoreArg(),
                                          mox.IgnoreArg()).AndReturn(True)
        server_manager_utils.use_server_db().MultipleTimes().AndReturn(True)
        self.mox.StubOutWithMock(self.PRIMARY_SCHEDULER, 'get_role_names')
        self.PRIMARY_SCHEDULER.get_role_names().AndReturn(
            [server_models.ServerRole.ROLE.SCHEDULER])
        server_models.ServerRole.objects.create(
            server=self.PRIMARY_SCHEDULER,
            role=server_models.ServerRole.ROLE.DRONE).AndReturn(
                self.DRONE_ROLE)
        server_models.Server.objects.filter(
            roles__role=server_models.ServerRole.ROLE.SCHEDULER,
            status=server_models.Server.STATUS.PRIMARY).AndReturn(
                [self.PRIMARY_SCHEDULER])
        infra.execute_command(mox.IgnoreArg(), mox.IgnoreArg())
        self.mox.ReplayAll()
        server_manager._add_role(self.PRIMARY_SCHEDULER,
                                 server_models.ServerRole.ROLE.DRONE,
                                 action=True)
 def testAddRoleToBackupFail_CheckServerFail(self):
     """Test manager fails to add a role to a backup server if check_server
     is failed.
     """
     server_manager_utils.check_server(mox.IgnoreArg(),
                                       mox.IgnoreArg()).AndReturn(False)
     server_models.validate(role=server_models.ServerRole.ROLE.DRONE)
     self.mox.StubOutWithMock(self.BACKUP_DRONE, 'get_role_names')
     self.BACKUP_DRONE.get_role_names().MultipleTimes().AndReturn(
         [server_models.ServerRole.ROLE.DRONE])
     self.mox.ReplayAll()
     self.assertRaises(server_manager_utils.ServerActionError,
                       server_manager._add_role,
                       server=self.BACKUP_DRONE,
                       role=server_models.ServerRole.ROLE.SCHEDULER,
                       action=True)
    def testAddRoleToBackupSuccess(self):
        """Test manager can add a role to a backup server successfully.

        Confirm that database call is made, and no action is taken, e.g.,
        restart scheduler to activate a new devserver.
        """
        server_models.validate(role=server_models.ServerRole.ROLE.DEVSERVER)
        server_manager_utils.check_server(mox.IgnoreArg(),
                                          mox.IgnoreArg()).AndReturn(True)
        server_manager_utils.use_server_db().MultipleTimes().AndReturn(True)
        self.mox.StubOutWithMock(self.BACKUP_DRONE, 'get_role_names')
        self.BACKUP_DRONE.get_role_names().AndReturn(
            [server_models.ServerRole.ROLE.DRONE])
        server_models.ServerRole.objects.create(
            server=mox.IgnoreArg(),
            role=server_models.ServerRole.ROLE.DEVSERVER).AndReturn(
                self.DRONE_ROLE)
        self.mox.ReplayAll()
        server_manager._add_role(server=self.BACKUP_DRONE,
                                 role=server_models.ServerRole.ROLE.DEVSERVER,
                                 action=True)
def _add_role(server, role, action):
    """Add a role to the server.

    @param server: An object of server_models.Server.
    @param role: Role to be added to the server.
    @param action: Execute actions after role or status is changed. Default to
                   False.

    @raise ServerActionError: If role is failed to be added.
    """
    server_models.validate(role=role)
    if role in server.get_role_names():
        raise server_manager_utils.ServerActionError(
            'Server %s already has role %s.' % (server.hostname, role))

    # Verify server
    if not server_manager_utils.check_server(server.hostname, role):
        raise server_manager_utils.ServerActionError(
            'Server %s is not ready for role %s.' % (server.hostname, role))

    if (role in server_models.ServerRole.ROLES_REQUIRE_UNIQUE_INSTANCE
            and server.status == server_models.Server.STATUS.PRIMARY):
        servers = server_models.Server.objects.filter(
            roles__role=role, status=server_models.Server.STATUS.PRIMARY)
        if len(servers) >= 1:
            raise server_manager_utils.ServerActionError(
                'Role %s must be unique. Server %s already has role %s.' %
                (role, servers[0].hostname, role))

    server_models.ServerRole.objects.create(server=server, role=role)

    # If needed, apply actions to enable the role for the server.
    server_manager_actions.try_execute(server, [role],
                                       enable=True,
                                       post_change=True,
                                       do_action=action)

    print 'Role %s is added to server %s.' % (role, server.hostname)