001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.backup; 019 020import static org.junit.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertTrue; 022import static org.junit.jupiter.api.Assertions.fail; 023 024import java.io.ByteArrayOutputStream; 025import java.io.PrintStream; 026import java.util.List; 027import org.apache.hadoop.fs.FileSystem; 028import org.apache.hadoop.fs.Path; 029import org.apache.hadoop.hbase.TableName; 030import org.apache.hadoop.hbase.backup.impl.BackupSystemTable; 031import org.apache.hadoop.hbase.testclassification.LargeTests; 032import org.apache.hadoop.hbase.util.EnvironmentEdge; 033import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 034import org.apache.hadoop.util.ToolRunner; 035import org.junit.jupiter.api.Tag; 036import org.junit.jupiter.api.Test; 037import org.slf4j.Logger; 038import org.slf4j.LoggerFactory; 039 040import org.apache.hbase.thirdparty.com.google.common.collect.Lists; 041import org.apache.hbase.thirdparty.com.google.common.collect.Sets; 042 043@Tag(LargeTests.TAG) 044public class TestBackupDelete extends TestBackupBase { 045 046 private static final Logger LOG = LoggerFactory.getLogger(TestBackupDelete.class); 047 048 /** 049 * Verify that full backup is created on a single table with data correctly. Verify that history 050 * works as expected. 051 * @throws Exception if doing the backup or an operation on the tables fails 052 */ 053 @Test 054 public void testBackupDelete() throws Exception { 055 LOG.info("test backup delete on a single table with data"); 056 List<TableName> tableList = Lists.newArrayList(table1); 057 String backupId = fullTableBackup(tableList); 058 assertTrue(checkSucceeded(backupId)); 059 LOG.info("backup complete"); 060 String[] backupIds = new String[] { backupId }; 061 BackupSystemTable table = new BackupSystemTable(TEST_UTIL.getConnection()); 062 BackupInfo info = table.readBackupInfo(backupId); 063 Path path = new Path(info.getBackupRootDir(), backupId); 064 FileSystem fs = FileSystem.get(path.toUri(), conf1); 065 assertTrue(fs.exists(path)); 066 int deleted = getBackupAdmin().deleteBackups(backupIds); 067 068 assertTrue(!fs.exists(path)); 069 assertTrue(fs.exists(new Path(info.getBackupRootDir()))); 070 assertTrue(1 == deleted); 071 table.close(); 072 LOG.info("delete_backup"); 073 } 074 075 /** 076 * Verify that full backup is created on a single table with data correctly. Verify that history 077 * works as expected. 078 * @throws Exception if doing the backup or an operation on the tables fails 079 */ 080 @Test 081 public void testBackupDeleteCommand() throws Exception { 082 LOG.info("test backup delete on a single table with data: command-line"); 083 List<TableName> tableList = Lists.newArrayList(table1); 084 String backupId = fullTableBackup(tableList); 085 assertTrue(checkSucceeded(backupId)); 086 LOG.info("backup complete"); 087 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 088 System.setOut(new PrintStream(baos)); 089 090 String[] args = new String[] { "delete", "-l", backupId }; 091 // Run backup 092 093 try { 094 int ret = ToolRunner.run(conf1, new BackupDriver(), args); 095 assertTrue(ret == 0); 096 } catch (Exception e) { 097 LOG.error("failed", e); 098 } 099 LOG.info("delete_backup"); 100 String output = baos.toString(); 101 LOG.info(baos.toString()); 102 assertTrue(output.indexOf("Deleted 1 backups") >= 0); 103 } 104 105 @Test 106 public void testBackupPurgeOldBackupsCommand() throws Exception { 107 LOG.info("test backup delete (purge old backups) on a single table with data: command-line"); 108 List<TableName> tableList = Lists.newArrayList(table1); 109 EnvironmentEdgeManager.injectEdge(new EnvironmentEdge() { 110 // time - 2 days 111 @Override 112 public long currentTime() { 113 return System.currentTimeMillis() - 2 * 24 * 3600 * 1000; 114 } 115 }); 116 String backupId = fullTableBackup(tableList); 117 assertTrue(checkSucceeded(backupId)); 118 119 EnvironmentEdgeManager.reset(); 120 121 LOG.info("backup complete"); 122 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 123 System.setOut(new PrintStream(baos)); 124 125 // Purge all backups which are older than 3 days 126 // Must return 0 (no backups were purged) 127 String[] args = new String[] { "delete", "-k", "3" }; 128 // Run backup 129 130 try { 131 int ret = ToolRunner.run(conf1, new BackupDriver(), args); 132 assertTrue(ret == 0); 133 } catch (Exception e) { 134 LOG.error("failed", e); 135 fail(e.getMessage()); 136 } 137 String output = baos.toString(); 138 LOG.info(baos.toString()); 139 assertTrue(output.indexOf("Deleted 0 backups") >= 0); 140 141 // Purge all backups which are older than 1 days 142 // Must return 1 deleted backup 143 args = new String[] { "delete", "-k", "1" }; 144 // Run backup 145 baos.reset(); 146 try { 147 int ret = ToolRunner.run(conf1, new BackupDriver(), args); 148 assertTrue(ret == 0); 149 } catch (Exception e) { 150 LOG.error("failed", e); 151 fail(e.getMessage()); 152 } 153 output = baos.toString(); 154 LOG.info(baos.toString()); 155 assertTrue(output.indexOf("Deleted 1 backups") >= 0); 156 } 157 158 /** 159 * Verify that backup deletion updates the incremental-backup-set. 160 */ 161 @Test 162 public void testBackupDeleteUpdatesIncrementalBackupSet() throws Exception { 163 LOG.info("Test backup delete updates the incremental backup set"); 164 BackupSystemTable backupSystemTable = new BackupSystemTable(TEST_UTIL.getConnection()); 165 166 String backupId1 = fullTableBackup(Lists.newArrayList(table1, table2)); 167 assertTrue(checkSucceeded(backupId1)); 168 assertEquals(Sets.newHashSet(table1, table2), 169 backupSystemTable.getIncrementalBackupTableSet(BACKUP_ROOT_DIR)); 170 171 String backupId2 = fullTableBackup(Lists.newArrayList(table3)); 172 assertTrue(checkSucceeded(backupId2)); 173 assertEquals(Sets.newHashSet(table1, table2, table3), 174 backupSystemTable.getIncrementalBackupTableSet(BACKUP_ROOT_DIR)); 175 176 getBackupAdmin().deleteBackups(new String[] { backupId1 }); 177 assertEquals(Sets.newHashSet(table3), 178 backupSystemTable.getIncrementalBackupTableSet(BACKUP_ROOT_DIR)); 179 } 180}