def setUp(self):
     super(GaleraClusterTasksTest, self).setUp()
     util.init_db()
     self.cluster_id = "1232"
     self.cluster_name = "Cluster-1234"
     self.tenant_id = "6789"
     self.db_cluster = DBCluster(ClusterTaskStatus.NONE,
                                 id=self.cluster_id,
                                 created=str(datetime.date),
                                 updated=str(datetime.date),
                                 name=self.cluster_name,
                                 task_id=ClusterTaskStatus.NONE._code,
                                 tenant_id=self.tenant_id,
                                 datastore_version_id="1",
                                 deleted=False)
     self.dbinst1 = DBInstance(InstanceTasks.NONE, id="1", name="member1",
                               compute_instance_id="compute-1",
                               task_id=InstanceTasks.NONE._code,
                               task_description=InstanceTasks.NONE._db_text,
                               volume_id="volume-1",
                               datastore_version_id="1",
                               cluster_id=self.cluster_id,
                               type="member")
     self.dbinst2 = DBInstance(InstanceTasks.NONE, id="2", name="member2",
                               compute_instance_id="compute-2",
                               task_id=InstanceTasks.NONE._code,
                               task_description=InstanceTasks.NONE._db_text,
                               volume_id="volume-2",
                               datastore_version_id="1",
                               cluster_id=self.cluster_id,
                               type="member")
     self.dbinst3 = DBInstance(InstanceTasks.NONE, id="3", name="member3",
                               compute_instance_id="compute-3",
                               task_id=InstanceTasks.NONE._code,
                               task_description=InstanceTasks.NONE._db_text,
                               volume_id="volume-3",
                               datastore_version_id="1",
                               cluster_id=self.cluster_id,
                               type="member")
     mock_ds1 = Mock()
     mock_ds1.name = 'pxc'
     mock_dv1 = Mock()
     mock_dv1.name = '7.1'
     self.clustertasks = GaleraCommonClusterTasks(
         Mock(), self.db_cluster, datastore=mock_ds1,
         datastore_version=mock_dv1)
     self.cluster_context = {
         'replication_user': {
             'name': "name",
             'password': "******",
         },
         'cluster_name': self.cluster_name,
         'admin_password': "******"
     }
 def setUp(self):
     super(GaleraClusterTasksTest, self).setUp()
     util.init_db()
     self.cluster_id = "1232"
     self.cluster_name = "Cluster-1234"
     self.tenant_id = "6789"
     self.db_cluster = DBCluster(ClusterTaskStatus.NONE,
                                 id=self.cluster_id,
                                 created=str(datetime.date),
                                 updated=str(datetime.date),
                                 name=self.cluster_name,
                                 task_id=ClusterTaskStatus.NONE._code,
                                 tenant_id=self.tenant_id,
                                 datastore_version_id="1",
                                 deleted=False)
     self.dbinst1 = DBInstance(InstanceTasks.NONE,
                               id="1",
                               name="member1",
                               compute_instance_id="compute-1",
                               task_id=InstanceTasks.NONE._code,
                               task_description=InstanceTasks.NONE._db_text,
                               volume_id="volume-1",
                               datastore_version_id="1",
                               cluster_id=self.cluster_id,
                               type="member")
     self.dbinst2 = DBInstance(InstanceTasks.NONE,
                               id="2",
                               name="member2",
                               compute_instance_id="compute-2",
                               task_id=InstanceTasks.NONE._code,
                               task_description=InstanceTasks.NONE._db_text,
                               volume_id="volume-2",
                               datastore_version_id="1",
                               cluster_id=self.cluster_id,
                               type="member")
     self.dbinst3 = DBInstance(InstanceTasks.NONE,
                               id="3",
                               name="member3",
                               compute_instance_id="compute-3",
                               task_id=InstanceTasks.NONE._code,
                               task_description=InstanceTasks.NONE._db_text,
                               volume_id="volume-3",
                               datastore_version_id="1",
                               cluster_id=self.cluster_id,
                               type="member")
     mock_ds1 = Mock()
     mock_ds1.name = 'pxc'
     mock_dv1 = Mock()
     mock_dv1.name = '7.1'
     self.clustertasks = GaleraCommonClusterTasks(
         Mock(),
         self.db_cluster,
         datastore=mock_ds1,
         datastore_version=mock_dv1)
     self.cluster_context = {
         'replication_user': {
             'name': "name",
             'password': "******",
         },
         'cluster_name': self.cluster_name,
         'admin_password': "******"
     }
class GaleraClusterTasksTest(trove_testtools.TestCase):
    def setUp(self):
        super(GaleraClusterTasksTest, self).setUp()
        util.init_db()
        self.cluster_id = "1232"
        self.cluster_name = "Cluster-1234"
        self.tenant_id = "6789"
        self.db_cluster = DBCluster(ClusterTaskStatus.NONE,
                                    id=self.cluster_id,
                                    created=str(datetime.date),
                                    updated=str(datetime.date),
                                    name=self.cluster_name,
                                    task_id=ClusterTaskStatus.NONE._code,
                                    tenant_id=self.tenant_id,
                                    datastore_version_id="1",
                                    deleted=False)
        self.dbinst1 = DBInstance(InstanceTasks.NONE, id="1", name="member1",
                                  compute_instance_id="compute-1",
                                  task_id=InstanceTasks.NONE._code,
                                  task_description=InstanceTasks.NONE._db_text,
                                  volume_id="volume-1",
                                  datastore_version_id="1",
                                  cluster_id=self.cluster_id,
                                  type="member")
        self.dbinst2 = DBInstance(InstanceTasks.NONE, id="2", name="member2",
                                  compute_instance_id="compute-2",
                                  task_id=InstanceTasks.NONE._code,
                                  task_description=InstanceTasks.NONE._db_text,
                                  volume_id="volume-2",
                                  datastore_version_id="1",
                                  cluster_id=self.cluster_id,
                                  type="member")
        self.dbinst3 = DBInstance(InstanceTasks.NONE, id="3", name="member3",
                                  compute_instance_id="compute-3",
                                  task_id=InstanceTasks.NONE._code,
                                  task_description=InstanceTasks.NONE._db_text,
                                  volume_id="volume-3",
                                  datastore_version_id="1",
                                  cluster_id=self.cluster_id,
                                  type="member")
        mock_ds1 = Mock()
        mock_ds1.name = 'pxc'
        mock_dv1 = Mock()
        mock_dv1.name = '7.1'
        self.clustertasks = GaleraCommonClusterTasks(
            Mock(), self.db_cluster, datastore=mock_ds1,
            datastore_version=mock_dv1)
        self.cluster_context = {
            'replication_user': {
                'name': "name",
                'password': "******",
            },
            'cluster_name': self.cluster_name,
            'admin_password': "******"
        }

    @patch.object(GaleraCommonClusterTasks, 'update_statuses_on_failure')
    @patch.object(InstanceServiceStatus, 'find_by')
    @patch('trove.taskmanager.models.LOG')
    def test_all_instances_ready_bad_status(self, mock_logging,
                                            mock_find, mock_update):
        (mock_find.return_value.
         get_status.return_value) = ServiceStatuses.FAILED
        ret_val = self.clustertasks._all_instances_ready(["1", "2", "3", "4"],
                                                         self.cluster_id)
        mock_update.assert_called_with(self.cluster_id, None)
        self.assertFalse(ret_val)

    @patch.object(InstanceServiceStatus, 'find_by')
    def test_all_instances_ready(self, mock_find):
        (mock_find.return_value.
         get_status.return_value) = ServiceStatuses.INSTANCE_READY
        ret_val = self.clustertasks._all_instances_ready(["1", "2", "3", "4"],
                                                         self.cluster_id)
        self.assertTrue(ret_val)

    @patch.object(GaleraCommonClusterTasks, 'update_statuses_on_failure')
    @patch.object(GaleraCommonClusterTasks, '_all_instances_ready',
                  return_value=False)
    @patch.object(Instance, 'load')
    @patch.object(DBInstance, 'find_all')
    @patch.object(datastore_models.Datastore, 'load')
    @patch.object(datastore_models.DatastoreVersion, 'load_by_uuid')
    @patch('trove.common.strategies.cluster.experimental.galera_common.'
           'taskmanager.LOG')
    def test_create_cluster_instance_not_ready(self, mock_logging, mock_dv,
                                               mock_ds, mock_find_all,
                                               mock_load, mock_ready,
                                               mock_update):
        mock_find_all.return_value.all.return_value = [self.dbinst1]
        mock_load.return_value = BaseInstance(Mock(),
                                              self.dbinst1, Mock(),
                                              InstanceServiceStatus(
                                                  ServiceStatuses.NEW))
        self.clustertasks.create_cluster(Mock(), self.cluster_id)
        mock_update.assert_called_with(self.cluster_id)

    @patch.object(GaleraCommonClusterTasks, 'update_statuses_on_failure')
    @patch.object(GaleraCommonClusterTasks, 'reset_task')
    @patch.object(GaleraCommonClusterTasks, 'get_ip')
    @patch.object(GaleraCommonClusterTasks, '_all_instances_ready')
    @patch.object(Instance, 'load')
    @patch.object(DBInstance, 'find_all')
    @patch.object(datastore_models.Datastore, 'load')
    @patch.object(datastore_models.DatastoreVersion, 'load_by_uuid')
    @patch('trove.common.strategies.cluster.experimental.galera_common.'
           'taskmanager.LOG')
    def test_create_cluster_fail(self, mock_logging, mock_dv, mock_ds,
                                 mock_find_all, mock_load, mock_ready, mock_ip,
                                 mock_reset_task, mock_update_status):
        mock_find_all.return_value.all.return_value = [self.dbinst1]
        mock_load.return_value = BaseInstance(Mock(),
                                              self.dbinst1, Mock(),
                                              InstanceServiceStatus(
                                                  ServiceStatuses.NEW))
        mock_ip.return_value = "10.0.0.2"
        guest_client = Mock()
        guest_client.install_cluster = Mock(side_effect=GuestError("Error"))
        with patch.object(GaleraCommonClusterTasks, 'get_guest',
                          return_value=guest_client):
            self.clustertasks.create_cluster(Mock(), self.cluster_id)
            mock_update_status.assert_called_with('1232')
            mock_reset_task.assert_called_with()

    @patch.object(GaleraCommonClusterTasks, 'update_statuses_on_failure')
    @patch('trove.common.strategies.cluster.experimental.galera_common.'
           'taskmanager.LOG')
    def test_grow_cluster_does_not_exist(self, mock_logging,
                                         mock_update_status):
        context = Mock()
        bad_cluster_id = '1234'
        new_instances = [Mock(), Mock()]
        self.clustertasks.grow_cluster(context, bad_cluster_id, new_instances)
        mock_update_status.assert_called_with(
            '1234',
            status=InstanceTasks.GROWING_ERROR)

    @patch.object(GaleraCommonClusterTasks, '_check_cluster_for_root')
    @patch.object(GaleraCommonClusterTasks, 'reset_task')
    @patch.object(GaleraCommonClusterTasks, '_render_cluster_config')
    @patch.object(GaleraCommonClusterTasks, 'get_ip')
    @patch.object(GaleraCommonClusterTasks, 'get_guest')
    @patch.object(GaleraCommonClusterTasks, '_all_instances_ready',
                  return_value=True)
    @patch.object(Instance, 'load')
    @patch.object(DBInstance, 'find_all')
    @patch.object(datastore_models.Datastore, 'load')
    @patch.object(datastore_models.DatastoreVersion, 'load_by_uuid')
    def test_grow_cluster_successs(self, mock_dv, mock_ds, mock_find_all,
                                   mock_load, mock_ready, mock_guest, mock_ip,
                                   mock_render, mock_reset_task,
                                   mock_check_root):
        mock_find_all.return_value.all.return_value = [self.dbinst1]

        mock_ip.return_value = "10.0.0.2"
        context = Mock()
        new_instances = [Mock(), Mock()]
        mock_guest.get_cluster_context = Mock(
            return_value=self.cluster_context)
        mock_guest.reset_admin_password = Mock()
        self.clustertasks.grow_cluster(context, self.cluster_id,
                                       new_instances)
        mock_reset_task.assert_called_with()

    @patch.object(GaleraCommonClusterTasks, 'reset_task')
    @patch.object(Instance, 'load')
    @patch.object(Instance, 'delete')
    @patch.object(DBInstance, 'find_all')
    @patch.object(GaleraCommonClusterTasks, 'get_guest')
    @patch.object(GaleraCommonClusterTasks, 'get_ip')
    @patch.object(GaleraCommonClusterTasks, '_render_cluster_config')
    def test_shrink_cluster_success(self, mock_render, mock_ip, mock_guest,
                                    mock_find_all, mock_delete, mock_load,
                                    mock_reset_task):
        mock_find_all.return_value.all.return_value = [self.dbinst1]
        context = Mock()
        remove_instances = [Mock()]
        mock_ip.return_value = "10.0.0.2"
        mock_guest.get_cluster_context = Mock(
            return_value=self.cluster_context)
        self.clustertasks.shrink_cluster(context, self.cluster_id,
                                         remove_instances)
        mock_reset_task.assert_called_with()

    @patch.object(Instance, 'load')
    @patch.object(GaleraCommonClusterTasks, 'update_statuses_on_failure')
    @patch('trove.common.strategies.cluster.experimental.galera_common.'
           'taskmanager.LOG')
    def test_shrink_cluster_does_not_exist(self, mock_logging,
                                           mock_update_status,
                                           mock_load):
        context = Mock()
        bad_cluster_id = '1234'
        remove_instances = [Mock()]
        self.clustertasks.shrink_cluster(context, bad_cluster_id,
                                         remove_instances)
        mock_update_status.assert_called_with(
            '1234',
            status=InstanceTasks.SHRINKING_ERROR)
class GaleraClusterTasksTest(trove_testtools.TestCase):
    def setUp(self):
        super(GaleraClusterTasksTest, self).setUp()
        util.init_db()
        self.cluster_id = "1232"
        self.cluster_name = "Cluster-1234"
        self.tenant_id = "6789"
        self.db_cluster = DBCluster(ClusterTaskStatus.NONE,
                                    id=self.cluster_id,
                                    created=str(datetime.date),
                                    updated=str(datetime.date),
                                    name=self.cluster_name,
                                    task_id=ClusterTaskStatus.NONE._code,
                                    tenant_id=self.tenant_id,
                                    datastore_version_id="1",
                                    deleted=False)
        self.dbinst1 = DBInstance(InstanceTasks.NONE,
                                  id="1",
                                  name="member1",
                                  compute_instance_id="compute-1",
                                  task_id=InstanceTasks.NONE._code,
                                  task_description=InstanceTasks.NONE._db_text,
                                  volume_id="volume-1",
                                  datastore_version_id="1",
                                  cluster_id=self.cluster_id,
                                  type="member")
        self.dbinst2 = DBInstance(InstanceTasks.NONE,
                                  id="2",
                                  name="member2",
                                  compute_instance_id="compute-2",
                                  task_id=InstanceTasks.NONE._code,
                                  task_description=InstanceTasks.NONE._db_text,
                                  volume_id="volume-2",
                                  datastore_version_id="1",
                                  cluster_id=self.cluster_id,
                                  type="member")
        self.dbinst3 = DBInstance(InstanceTasks.NONE,
                                  id="3",
                                  name="member3",
                                  compute_instance_id="compute-3",
                                  task_id=InstanceTasks.NONE._code,
                                  task_description=InstanceTasks.NONE._db_text,
                                  volume_id="volume-3",
                                  datastore_version_id="1",
                                  cluster_id=self.cluster_id,
                                  type="member")
        mock_ds1 = Mock()
        mock_ds1.name = 'pxc'
        mock_dv1 = Mock()
        mock_dv1.name = '7.1'
        self.clustertasks = GaleraCommonClusterTasks(
            Mock(),
            self.db_cluster,
            datastore=mock_ds1,
            datastore_version=mock_dv1)
        self.cluster_context = {
            'replication_user': {
                'name': "name",
                'password': "******",
            },
            'cluster_name': self.cluster_name,
            'admin_password': "******"
        }

    @patch.object(GaleraCommonClusterTasks, 'update_statuses_on_failure')
    @patch.object(DBInstance, 'find_by')
    @patch.object(InstanceServiceStatus, 'find_by')
    @patch('trove.taskmanager.models.LOG')
    def test_all_instances_ready_with_server_error(self, mock_logging,
                                                   mock_find, mock_db_find,
                                                   mock_update):
        (mock_find.return_value.get_status.return_value) = ServiceStatuses.NEW
        (mock_db_find.return_value.get_task_status.return_value
         ) = InstanceTasks.BUILDING_ERROR_SERVER
        ret_val = self.clustertasks._all_instances_ready(["1", "2", "3", "4"],
                                                         self.cluster_id)
        mock_update.assert_called_with(self.cluster_id, None)
        self.assertFalse(ret_val)

    @patch.object(GaleraCommonClusterTasks, 'update_statuses_on_failure')
    @patch.object(DBInstance, 'find_by')
    @patch.object(InstanceServiceStatus, 'find_by')
    @patch('trove.taskmanager.models.LOG')
    def test_all_instances_ready_bad_status(self, mock_logging, mock_find,
                                            mock_db_find, mock_update):
        (mock_find.return_value.get_status.return_value
         ) = ServiceStatuses.FAILED
        (mock_db_find.return_value.get_task_status.return_value
         ) = InstanceTasks.NONE
        ret_val = self.clustertasks._all_instances_ready(["1", "2", "3", "4"],
                                                         self.cluster_id)
        mock_update.assert_called_with(self.cluster_id, None)
        self.assertFalse(ret_val)

    @patch.object(DBInstance, 'find_by')
    @patch.object(InstanceServiceStatus, 'find_by')
    def test_all_instances_ready(self, mock_find, mock_db_find):
        (mock_find.return_value.get_status.return_value
         ) = ServiceStatuses.INSTANCE_READY
        (mock_db_find.return_value.get_task_status.return_value
         ) = InstanceTasks.NONE
        ret_val = self.clustertasks._all_instances_ready(["1", "2", "3", "4"],
                                                         self.cluster_id)
        self.assertTrue(ret_val)

    @patch.object(GaleraCommonClusterTasks, 'update_statuses_on_failure')
    @patch.object(GaleraCommonClusterTasks,
                  '_all_instances_ready',
                  return_value=False)
    @patch.object(Instance, 'load')
    @patch.object(DBInstance, 'find_all')
    @patch.object(datastore_models.Datastore, 'load')
    @patch.object(datastore_models.DatastoreVersion, 'load_by_uuid')
    @patch('trove.common.strategies.cluster.experimental.galera_common.'
           'taskmanager.LOG')
    def test_create_cluster_instance_not_ready(self, mock_logging, mock_dv,
                                               mock_ds, mock_find_all,
                                               mock_load, mock_ready,
                                               mock_update):
        mock_find_all.return_value.all.return_value = [self.dbinst1]
        mock_load.return_value = BaseInstance(
            Mock(), self.dbinst1, Mock(),
            InstanceServiceStatus(ServiceStatuses.NEW))
        self.clustertasks.create_cluster(Mock(), self.cluster_id)
        mock_update.assert_called_with(self.cluster_id)

    @patch.object(GaleraCommonClusterTasks, 'update_statuses_on_failure')
    @patch.object(GaleraCommonClusterTasks, 'reset_task')
    @patch.object(GaleraCommonClusterTasks, 'get_ip')
    @patch.object(GaleraCommonClusterTasks, '_all_instances_ready')
    @patch.object(Instance, 'load')
    @patch.object(DBInstance, 'find_all')
    @patch.object(datastore_models.Datastore, 'load')
    @patch.object(datastore_models.DatastoreVersion, 'load_by_uuid')
    @patch('trove.common.strategies.cluster.experimental.galera_common.'
           'taskmanager.LOG')
    def test_create_cluster_fail(self, mock_logging, mock_dv, mock_ds,
                                 mock_find_all, mock_load, mock_ready, mock_ip,
                                 mock_reset_task, mock_update_status):
        mock_find_all.return_value.all.return_value = [self.dbinst1]
        mock_load.return_value = BaseInstance(
            Mock(), self.dbinst1, Mock(),
            InstanceServiceStatus(ServiceStatuses.NEW))
        mock_ip.return_value = "10.0.0.2"
        guest_client = Mock()
        guest_client.install_cluster = Mock(side_effect=GuestError("Error"))
        with patch.object(GaleraCommonClusterTasks,
                          'get_guest',
                          return_value=guest_client):
            self.clustertasks.create_cluster(Mock(), self.cluster_id)
            mock_update_status.assert_called_with('1232')
            mock_reset_task.assert_called_with()

    @patch.object(GaleraCommonClusterTasks, 'update_statuses_on_failure')
    @patch('trove.common.strategies.cluster.experimental.galera_common.'
           'taskmanager.LOG')
    def test_grow_cluster_does_not_exist(self, mock_logging,
                                         mock_update_status):
        context = Mock()
        bad_cluster_id = '1234'
        new_instances = [Mock(), Mock()]
        self.clustertasks.grow_cluster(context, bad_cluster_id, new_instances)
        mock_update_status.assert_called_with(
            '1234', status=InstanceTasks.GROWING_ERROR)

    @patch.object(GaleraCommonClusterTasks, '_check_cluster_for_root')
    @patch.object(GaleraCommonClusterTasks, 'reset_task')
    @patch.object(GaleraCommonClusterTasks, '_render_cluster_config')
    @patch.object(GaleraCommonClusterTasks, 'get_ip')
    @patch.object(GaleraCommonClusterTasks, 'get_guest')
    @patch.object(GaleraCommonClusterTasks,
                  '_all_instances_ready',
                  return_value=True)
    @patch.object(Instance, 'load')
    @patch.object(DBInstance, 'find_all')
    @patch.object(datastore_models.Datastore, 'load')
    @patch.object(datastore_models.DatastoreVersion, 'load_by_uuid')
    def test_grow_cluster_successs(self, mock_dv, mock_ds, mock_find_all,
                                   mock_load, mock_ready, mock_guest, mock_ip,
                                   mock_render, mock_reset_task,
                                   mock_check_root):
        mock_find_all.return_value.all.return_value = [self.dbinst1]

        mock_ip.return_value = "10.0.0.2"
        context = Mock()
        new_instances = [Mock(), Mock()]
        mock_guest.get_cluster_context = Mock(
            return_value=self.cluster_context)
        mock_guest.reset_admin_password = Mock()
        self.clustertasks.grow_cluster(context, self.cluster_id, new_instances)
        mock_reset_task.assert_called_with()

    @patch.object(GaleraCommonClusterTasks, 'reset_task')
    @patch.object(Instance, 'load')
    @patch.object(Instance, 'delete')
    @patch.object(DBInstance, 'find_all')
    @patch.object(GaleraCommonClusterTasks, 'get_guest')
    @patch.object(GaleraCommonClusterTasks, 'get_ip')
    @patch.object(GaleraCommonClusterTasks, '_render_cluster_config')
    def test_shrink_cluster_success(self, mock_render, mock_ip, mock_guest,
                                    mock_find_all, mock_delete, mock_load,
                                    mock_reset_task):
        mock_find_all.return_value.all.return_value = [self.dbinst1]
        context = Mock()
        remove_instances = [Mock()]
        mock_ip.return_value = "10.0.0.2"
        mock_guest.get_cluster_context = Mock(
            return_value=self.cluster_context)
        self.clustertasks.shrink_cluster(context, self.cluster_id,
                                         remove_instances)
        mock_reset_task.assert_called_with()

    @patch.object(Instance, 'load')
    @patch.object(GaleraCommonClusterTasks, 'update_statuses_on_failure')
    @patch('trove.common.strategies.cluster.experimental.galera_common.'
           'taskmanager.LOG')
    def test_shrink_cluster_does_not_exist(self, mock_logging,
                                           mock_update_status, mock_load):
        context = Mock()
        bad_cluster_id = '1234'
        remove_instances = [Mock()]
        self.clustertasks.shrink_cluster(context, bad_cluster_id,
                                         remove_instances)
        mock_update_status.assert_called_with(
            '1234', status=InstanceTasks.SHRINKING_ERROR)