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.Assert.assertTrue; 021import static org.junit.Assert.fail; 022 023import java.io.IOException; 024import java.util.concurrent.atomic.AtomicLongArray; 025import org.apache.hadoop.conf.Configuration; 026import org.apache.hadoop.hbase.HBaseClassTestRule; 027import org.apache.hadoop.hbase.HBaseTestingUtility; 028import org.apache.hadoop.hbase.MiniHBaseCluster; 029import org.apache.hadoop.hbase.backup.impl.BackupManager; 030import org.apache.hadoop.hbase.client.Connection; 031import org.apache.hadoop.hbase.testclassification.MediumTests; 032import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 033import org.junit.After; 034import org.junit.AfterClass; 035import org.junit.Before; 036import org.junit.BeforeClass; 037import org.junit.ClassRule; 038import org.junit.Test; 039import org.junit.experimental.categories.Category; 040import org.slf4j.Logger; 041import org.slf4j.LoggerFactory; 042 043import org.apache.hbase.thirdparty.com.google.common.util.concurrent.Uninterruptibles; 044 045@Category(MediumTests.class) 046public class TestBackupManager { 047 048 private static final Logger LOG = LoggerFactory.getLogger(TestBackupManager.class); 049 050 @ClassRule 051 public static final HBaseClassTestRule CLASS_RULE = 052 HBaseClassTestRule.forClass(TestBackupManager.class); 053 054 private static final HBaseTestingUtility UTIL = new HBaseTestingUtility(); 055 protected static Configuration conf = UTIL.getConfiguration(); 056 protected static MiniHBaseCluster cluster; 057 protected static Connection conn; 058 protected BackupManager backupManager; 059 060 @BeforeClass 061 public static void setUp() throws Exception { 062 conf.setBoolean(BackupRestoreConstants.BACKUP_ENABLE_KEY, true); 063 BackupManager.decorateMasterConfiguration(conf); 064 BackupManager.decorateRegionServerConfiguration(conf); 065 cluster = UTIL.startMiniCluster(); 066 conn = UTIL.getConnection(); 067 } 068 069 @AfterClass 070 public static void tearDown() throws IOException { 071 if (cluster != null) { 072 cluster.shutdown(); 073 } 074 } 075 076 @Before 077 public void before() throws IOException { 078 backupManager = new BackupManager(conn, conn.getConfiguration()); 079 } 080 081 @After 082 public void after() { 083 backupManager.close(); 084 } 085 086 AtomicLongArray startTimes = new AtomicLongArray(2); 087 AtomicLongArray stopTimes = new AtomicLongArray(2); 088 089 @Test 090 public void testStartBackupExclusiveOperation() { 091 092 long sleepTime = 2000; 093 Runnable r = new Runnable() { 094 @Override 095 public void run() { 096 try { 097 backupManager.startBackupSession(); 098 boolean result = startTimes.compareAndSet(0, 0, EnvironmentEdgeManager.currentTime()); 099 if (!result) { 100 result = startTimes.compareAndSet(1, 0, EnvironmentEdgeManager.currentTime()); 101 if (!result) { 102 throw new IOException("PANIC! Unreachable code"); 103 } 104 } 105 Thread.sleep(sleepTime); 106 result = stopTimes.compareAndSet(0, 0, EnvironmentEdgeManager.currentTime()); 107 if (!result) { 108 result = stopTimes.compareAndSet(1, 0, EnvironmentEdgeManager.currentTime()); 109 if (!result) { 110 throw new IOException("PANIC! Unreachable code"); 111 } 112 } 113 backupManager.finishBackupSession(); 114 } catch (IOException | InterruptedException e) { 115 fail("Unexpected exception: " + e.getMessage()); 116 } 117 } 118 }; 119 120 Thread[] workers = new Thread[2]; 121 for (int i = 0; i < workers.length; i++) { 122 workers[i] = new Thread(r); 123 workers[i].start(); 124 } 125 126 for (int i = 0; i < workers.length; i++) { 127 Uninterruptibles.joinUninterruptibly(workers[i]); 128 } 129 LOG.info("Diff start time=" + (startTimes.get(1) - startTimes.get(0)) + "ms"); 130 LOG.info("Diff finish time=" + (stopTimes.get(1) - stopTimes.get(0)) + "ms"); 131 assertTrue(startTimes.get(1) - startTimes.get(0) >= sleepTime); 132 assertTrue(stopTimes.get(1) - stopTimes.get(0) >= sleepTime); 133 134 } 135 136}