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.snapshot; 019 020import static org.junit.Assert.assertFalse; 021import static org.junit.Assert.assertTrue; 022import static org.junit.Assert.fail; 023 024import java.io.IOException; 025import java.net.URI; 026import org.apache.hadoop.conf.Configuration; 027import org.apache.hadoop.fs.FileSystem; 028import org.apache.hadoop.fs.Path; 029import org.apache.hadoop.hbase.HBaseClassTestRule; 030import org.apache.hadoop.hbase.HBaseConfiguration; 031import org.apache.hadoop.hbase.HBaseTestingUtil; 032import org.apache.hadoop.hbase.HConstants; 033import org.apache.hadoop.hbase.testclassification.RegionServerTests; 034import org.apache.hadoop.hbase.testclassification.SmallTests; 035import org.apache.hadoop.hbase.util.EnvironmentEdgeManagerTestHelper; 036import org.junit.After; 037import org.junit.BeforeClass; 038import org.junit.ClassRule; 039import org.junit.Test; 040import org.junit.experimental.categories.Category; 041import org.slf4j.Logger; 042import org.slf4j.LoggerFactory; 043 044import org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos.SnapshotDescription; 045 046/** 047 * Test that the {@link SnapshotDescription} helper is helping correctly. 048 */ 049@Category({ RegionServerTests.class, SmallTests.class }) 050public class TestSnapshotDescriptionUtils { 051 052 @ClassRule 053 public static final HBaseClassTestRule CLASS_RULE = 054 HBaseClassTestRule.forClass(TestSnapshotDescriptionUtils.class); 055 056 private static final HBaseTestingUtil UTIL = new HBaseTestingUtil(); 057 private static FileSystem fs; 058 private static Path root; 059 060 @BeforeClass 061 public static void setupFS() throws Exception { 062 fs = UTIL.getTestFileSystem(); 063 root = new Path(UTIL.getDataTestDir(), "hbase"); 064 } 065 066 @After 067 public void cleanupFS() throws Exception { 068 if (fs.exists(root)) { 069 if (!fs.delete(root, true)) { 070 throw new IOException("Failed to delete root test dir: " + root); 071 } 072 if (!fs.mkdirs(root)) { 073 throw new IOException("Failed to create root test dir: " + root); 074 } 075 } 076 EnvironmentEdgeManagerTestHelper.reset(); 077 } 078 079 private static final Logger LOG = LoggerFactory.getLogger(TestSnapshotDescriptionUtils.class); 080 081 @Test 082 public void testValidateMissingTableName() throws IOException { 083 Configuration conf = new Configuration(false); 084 try { 085 SnapshotDescriptionUtils.validate(SnapshotDescription.newBuilder().setName("fail").build(), 086 conf); 087 fail("Snapshot was considered valid without a table name"); 088 } catch (IllegalArgumentException e) { 089 LOG.debug("Correctly failed when snapshot doesn't have a tablename"); 090 } 091 } 092 093 /** 094 * Test that we throw an exception if there is no working snapshot directory when we attempt to 095 * 'complete' the snapshot 096 * @throws Exception on failure 097 */ 098 @Test 099 public void testCompleteSnapshotWithNoSnapshotDirectoryFailure() throws Exception { 100 Path snapshotDir = new Path(root, HConstants.SNAPSHOT_DIR_NAME); 101 Path tmpDir = new Path(snapshotDir, ".tmp"); 102 Path workingDir = new Path(tmpDir, "not_a_snapshot"); 103 Configuration conf = new Configuration(); 104 FileSystem workingFs = workingDir.getFileSystem(conf); 105 assertFalse( 106 "Already have working snapshot dir: " + workingDir + " but shouldn't. Test file leak?", 107 fs.exists(workingDir)); 108 SnapshotDescription snapshot = SnapshotDescription.newBuilder().setName("snapshot").build(); 109 Path finishedDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(snapshot, snapshotDir); 110 111 try { 112 SnapshotDescriptionUtils.completeSnapshot(finishedDir, workingDir, fs, workingFs, conf); 113 fail("Shouldn't successfully complete move of a non-existent directory."); 114 } catch (IOException e) { 115 LOG.info("Correctly failed to move non-existant directory: " + e.getMessage()); 116 } 117 } 118 119 @Test 120 public void testIsSubDirectoryWorks() { 121 Path rootDir = new Path("hdfs://root/.hbase-snapshot/"); 122 123 assertFalse(SnapshotDescriptionUtils.isSubDirectoryOf(rootDir, rootDir)); 124 assertFalse(SnapshotDescriptionUtils 125 .isSubDirectoryOf(new Path("hdfs://root/.hbase-snapshotdir"), rootDir)); 126 assertFalse( 127 SnapshotDescriptionUtils.isSubDirectoryOf(new Path("hdfs://root/.hbase-snapshot"), rootDir)); 128 assertFalse( 129 SnapshotDescriptionUtils.isSubDirectoryOf(new Path("hdfs://.hbase-snapshot"), rootDir)); 130 assertFalse( 131 SnapshotDescriptionUtils.isSubDirectoryOf(new Path("hdfs://.hbase-snapshot/.tmp"), rootDir)); 132 assertFalse(SnapshotDescriptionUtils.isSubDirectoryOf(new Path("hdfs://root"), rootDir)); 133 assertTrue(SnapshotDescriptionUtils 134 .isSubDirectoryOf(new Path("hdfs://root/.hbase-snapshot/.tmp"), rootDir)); 135 assertTrue(SnapshotDescriptionUtils 136 .isSubDirectoryOf(new Path("hdfs://root/.hbase-snapshot/.tmp/snapshot"), rootDir)); 137 138 assertFalse( 139 SnapshotDescriptionUtils.isSubDirectoryOf(new Path("s3://root/.hbase-snapshot/"), rootDir)); 140 assertFalse(SnapshotDescriptionUtils.isSubDirectoryOf(new Path("s3://root"), rootDir)); 141 assertFalse(SnapshotDescriptionUtils 142 .isSubDirectoryOf(new Path("s3://root/.hbase-snapshot/.tmp/snapshot"), rootDir)); 143 } 144 145 @Test 146 public void testIsWithinWorkingDir() throws IOException { 147 Configuration conf = new Configuration(); 148 conf.set(HConstants.HBASE_DIR, "hdfs://localhost/root/"); 149 150 assertFalse( 151 SnapshotDescriptionUtils.isWithinDefaultWorkingDir(new Path("hdfs://localhost/root/"), conf)); 152 assertFalse(SnapshotDescriptionUtils 153 .isWithinDefaultWorkingDir(new Path("hdfs://localhost/root/.hbase-snapshotdir"), conf)); 154 assertFalse(SnapshotDescriptionUtils 155 .isWithinDefaultWorkingDir(new Path("hdfs://localhost/root/.hbase-snapshot"), conf)); 156 assertFalse(SnapshotDescriptionUtils 157 .isWithinDefaultWorkingDir(new Path("hdfs://localhost/.hbase-snapshot"), conf)); 158 assertFalse(SnapshotDescriptionUtils 159 .isWithinDefaultWorkingDir(new Path("hdfs://localhost/.hbase-snapshot/.tmp"), conf)); 160 assertFalse( 161 SnapshotDescriptionUtils.isWithinDefaultWorkingDir(new Path("hdfs://localhost/root"), conf)); 162 assertTrue(SnapshotDescriptionUtils 163 .isWithinDefaultWorkingDir(new Path("hdfs://localhost/root/.hbase-snapshot/.tmp"), conf)); 164 assertTrue(SnapshotDescriptionUtils.isWithinDefaultWorkingDir( 165 new Path("hdfs://localhost/root/.hbase-snapshot/.tmp/snapshot"), conf)); 166 167 assertFalse(SnapshotDescriptionUtils 168 .isWithinDefaultWorkingDir(new Path("s3://localhost/root/.hbase-snapshot/"), conf)); 169 assertFalse( 170 SnapshotDescriptionUtils.isWithinDefaultWorkingDir(new Path("s3://localhost/root"), conf)); 171 assertFalse(SnapshotDescriptionUtils.isWithinDefaultWorkingDir( 172 new Path("s3://localhost/root/.hbase-snapshot/.tmp/snapshot"), conf)); 173 174 // for local mode 175 conf = HBaseConfiguration.create(); 176 String hbsaeDir = conf.get(HConstants.HBASE_DIR); 177 178 assertFalse( 179 SnapshotDescriptionUtils.isWithinDefaultWorkingDir(new Path("file:" + hbsaeDir + "/"), conf)); 180 assertFalse(SnapshotDescriptionUtils 181 .isWithinDefaultWorkingDir(new Path("file:" + hbsaeDir + "/.hbase-snapshotdir"), conf)); 182 assertFalse(SnapshotDescriptionUtils 183 .isWithinDefaultWorkingDir(new Path("file:" + hbsaeDir + "/.hbase-snapshot"), conf)); 184 assertFalse( 185 SnapshotDescriptionUtils.isWithinDefaultWorkingDir(new Path("file:/.hbase-snapshot"), conf)); 186 assertFalse(SnapshotDescriptionUtils 187 .isWithinDefaultWorkingDir(new Path("file:/.hbase-snapshot/.tmp"), conf)); 188 assertFalse( 189 SnapshotDescriptionUtils.isWithinDefaultWorkingDir(new Path("file:" + hbsaeDir), conf)); 190 assertTrue(SnapshotDescriptionUtils 191 .isWithinDefaultWorkingDir(new Path("file:" + hbsaeDir + "/.hbase-snapshot/.tmp"), conf)); 192 assertTrue(SnapshotDescriptionUtils.isWithinDefaultWorkingDir( 193 new Path("file:" + hbsaeDir + "/.hbase-snapshot/.tmp/snapshot"), conf)); 194 } 195 196 @Test 197 public void testShouldSkipRenameSnapshotDirectories() { 198 URI workingDirURI = URI.create("/User/test1"); 199 URI rootDirURI = URI.create("hdfs:///User/test2"); 200 201 // should skip rename if it's not the same scheme; 202 assertTrue( 203 SnapshotDescriptionUtils.shouldSkipRenameSnapshotDirectories(workingDirURI, rootDirURI)); 204 205 workingDirURI = URI.create("/User/test1"); 206 rootDirURI = URI.create("file:///User/test2"); 207 assertTrue( 208 SnapshotDescriptionUtils.shouldSkipRenameSnapshotDirectories(workingDirURI, rootDirURI)); 209 210 // skip rename when either scheme or authority are the not same 211 workingDirURI = URI.create("hdfs://localhost:8020/User/test1"); 212 rootDirURI = URI.create("hdfs://otherhost:8020/User/test2"); 213 assertTrue( 214 SnapshotDescriptionUtils.shouldSkipRenameSnapshotDirectories(workingDirURI, rootDirURI)); 215 216 workingDirURI = URI.create("file:///User/test1"); 217 rootDirURI = URI.create("hdfs://localhost:8020/User/test2"); 218 assertTrue( 219 SnapshotDescriptionUtils.shouldSkipRenameSnapshotDirectories(workingDirURI, rootDirURI)); 220 221 workingDirURI = URI.create("hdfs:///User/test1"); 222 rootDirURI = URI.create("hdfs:///User/test2"); 223 assertFalse( 224 SnapshotDescriptionUtils.shouldSkipRenameSnapshotDirectories(workingDirURI, rootDirURI)); 225 226 workingDirURI = URI.create("hdfs://localhost:8020/User/test1"); 227 rootDirURI = URI.create("hdfs://localhost:8020/User/test2"); 228 assertFalse( 229 SnapshotDescriptionUtils.shouldSkipRenameSnapshotDirectories(workingDirURI, rootDirURI)); 230 231 workingDirURI = URI.create("hdfs://user:password@localhost:8020/User/test1"); 232 rootDirURI = URI.create("hdfs://user:password@localhost:8020/User/test2"); 233 assertFalse( 234 SnapshotDescriptionUtils.shouldSkipRenameSnapshotDirectories(workingDirURI, rootDirURI)); 235 236 // skip rename when user information is not the same 237 workingDirURI = URI.create("hdfs://user:password@localhost:8020/User/test1"); 238 rootDirURI = URI.create("hdfs://user2:password2@localhost:8020/User/test2"); 239 assertTrue( 240 SnapshotDescriptionUtils.shouldSkipRenameSnapshotDirectories(workingDirURI, rootDirURI)); 241 } 242 243}