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