def test_restore_data_non_empty_index_list(
            self, mock_put_kv, mock_cleanup_bucket_list_entries,
            mock_cleanup_bucket_metadata_entries):
        # Test 'restore_data' when dict: 'list_result' & 'metadata_result' is not empty
        mockS3RecoverCorruption = S3RecoverCorruption()

        mockS3RecoverCorruption.metadata_result = {r'123/key3': 'value3'}
        mockS3RecoverCorruption.list_result = {
            'key1': 'value1',
            'key2': 'value2'
        }
        mockS3RecoverCorruption.common_keys = ['key1', 'key3']

        mock_put_kv.return_value = None
        mock_cleanup_bucket_list_entries.return_value = None
        mock_cleanup_bucket_metadata_entries.return_value = None

        mockS3RecoverCorruption.restore_data('global_list_index_id',
                                             'replica_list_index_id',
                                             'global_metadata_index_id',
                                             'replica_metadata_index_id')

        self.assertEqual(
            mock_put_kv.call_count,
            2)  # 1 put_kv call each to CORTXS3KVApi::put, for key1 and key3
        self.assertEqual(mock_cleanup_bucket_list_entries.call_count, 2)
        self.assertEqual(mock_cleanup_bucket_metadata_entries.call_count, 4)
示例#2
0
    def run(self):
        parser = argparse.ArgumentParser(
            description='S3-Metadata recovery tool', add_help=False)
        parser.add_argument('-h',
                            '--help',
                            action='help',
                            default=argparse.SUPPRESS,
                            help='Show this help message and exit')
        parser.add_argument("--dry_run",
                            help="Dry run of S3-Metadata corruption recovery",
                            action="store_true")
        parser.add_argument("--recover",
                            help="Recover S3-Metadata corruption (Silent)",
                            action="store_true")
        args = parser.parse_args()

        if args.dry_run:
            action = S3RecoveryDryRun()
            action.start()
        else:
            pass

        if args.recover:
            action = S3RecoverCorruption()
            action.start()
        else:
            pass
    def test_restore_data_none_index_list(self, mock_put):
        # Test 'restore_data' when list: 'list_result' is None
        mockS3RecoverCorruption = S3RecoverCorruption()
        mockS3RecoverCorruption.list_result = None

        mockS3RecoverCorruption.restore_data('global_list_index_id',
                                             'replica_list_index_id',
                                             'global_metadata_index_id',
                                             'replica_metadata_index_id')
        self.assertEqual(mock_put.call_count, 0)
    def test_inconsistent_data_entries(self):
        # Tests to check consistency check works for empty indexes
        mockS3RecoverCorruption = S3RecoverCorruption()
        mockS3RecoverCorruption.list_result = {
            "key1": "value1",
        }
        mockS3RecoverCorruption.metadata_result = {
            "617326/key2": "value2",
        }

        mockS3RecoverCorruption.check_consistency()

        # Assert inconsistent data should not be recovered
        self.assertEqual(len(mockS3RecoverCorruption.common_keys), 0)
        self.assertEqual(mockS3RecoverCorruption.common_keys, [])
    def test_consistent_data_entries(self):
        # Tests to check consistent data is recovered during recovery
        mockS3RecoverCorruption = S3RecoverCorruption()
        mockS3RecoverCorruption.list_result = {
            "key1": "value1",
            "key2": "value2"
        }
        mockS3RecoverCorruption.metadata_result = {
            "617326/key1": "value1",
            "617326/key2": "value2"
        }

        mockS3RecoverCorruption.check_consistency()

        # Assert for data to be recovered
        self.assertEqual(len(mockS3RecoverCorruption.common_keys), 2)
        self.assertEqual(mockS3RecoverCorruption.common_keys, ["key1", "key2"])
    def test_partial_inconsistent_data_entries(self):
        # Tests to check isconsistent data is not recovered during recovery
        mockS3RecoverCorruption = S3RecoverCorruption()
        mockS3RecoverCorruption.list_result = {
            "key1": "value1",
            "key2": "value2",
            "key3": "value3"
        }
        mockS3RecoverCorruption.metadata_result = {
            "617326/key3": "value3",
            "617326/key4": "value4",
            "617326/key5": "value5"
        }

        mockS3RecoverCorruption.check_consistency()

        # Assert inconsistent data should not be recovered
        self.assertEqual(len(mockS3RecoverCorruption.common_keys), 1)
        self.assertEqual(mockS3RecoverCorruption.common_keys, ["key3"])
    def test_check_restore_for_recover(self, mock_initiate, mock_dry_run,
                                       mock_restore_data):
        # Tests to check restore (PutKV) is used during recover option
        mockS3RecoverCorruption = S3RecoverCorruption()
        mock_initiate.return_value = None
        mock_dry_run.return_value = {}
        mock_restore_data.return_value = None
        mockS3RecoverCorruption.recover_corruption(
            "Global bucket index", Config.global_bucket_index_id,
            Config.global_bucket_index_id_replica, "Bucket metadata index",
            Config.bucket_metadata_index_id,
            Config.bucket_metadata_index_id_replica)

        self.assertTrue(mock_initiate.called)
        self.assertTrue(mock_dry_run.called)
        self.assertTrue(mock_restore_data.called)

        # Assert PutKV and other mock calls
        self.assertEqual(S3RecoveryBase.initiate.call_count, 2)
        self.assertEqual(S3RecoveryBase.dry_run.call_count, 2)
        self.assertEqual(S3RecoverCorruption.restore_data.call_count, 1)