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.testing;
019
020import static org.junit.jupiter.api.Assertions.assertEquals;
021import static org.junit.jupiter.api.Assertions.assertFalse;
022import static org.junit.jupiter.api.Assertions.assertThrows;
023import static org.junit.jupiter.api.Assertions.assertTrue;
024
025import java.util.Collection;
026import org.apache.hadoop.hbase.ServerName;
027import org.apache.hadoop.hbase.Waiter;
028import org.apache.hadoop.hbase.client.Admin;
029import org.apache.hadoop.hbase.client.Connection;
030import org.apache.hadoop.hbase.client.ConnectionFactory;
031import org.apache.hadoop.hbase.testclassification.LargeTests;
032import org.apache.hadoop.hbase.testclassification.MiscTests;
033import org.apache.hadoop.hbase.util.DNS;
034import org.apache.hadoop.hbase.util.DNS.ServerType;
035import org.junit.jupiter.api.AfterAll;
036import org.junit.jupiter.api.AfterEach;
037import org.junit.jupiter.api.BeforeAll;
038import org.junit.jupiter.api.BeforeEach;
039import org.junit.jupiter.api.Tag;
040import org.junit.jupiter.api.Test;
041
042import org.apache.hbase.thirdparty.com.google.common.collect.Iterables;
043import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
044
045@Tag(MiscTests.TAG)
046@Tag(LargeTests.TAG)
047public class TestTestingHBaseCluster {
048
049  private static TestingHBaseCluster CLUSTER;
050
051  private Connection conn;
052
053  private Admin admin;
054
055  @BeforeAll
056  public static void setUpBeforeClass() throws Exception {
057    CLUSTER = TestingHBaseCluster.create(TestingHBaseClusterOption.builder().numMasters(2)
058      .numRegionServers(3).numDataNodes(3).build());
059  }
060
061  @AfterAll
062  public static void tearDownAfterClass() throws Exception {
063    if (CLUSTER.isClusterRunning()) {
064      CLUSTER.stop();
065    }
066  }
067
068  @BeforeEach
069  public void setUp() throws Exception {
070    if (!CLUSTER.isClusterRunning()) {
071      CLUSTER.start();
072    }
073    if (!CLUSTER.isHBaseClusterRunning()) {
074      CLUSTER.startHBaseCluster();
075    }
076    conn = ConnectionFactory.createConnection(CLUSTER.getConf());
077    admin = conn.getAdmin();
078  }
079
080  @AfterEach
081  public void tearDown() throws Exception {
082    Closeables.close(admin, true);
083    Closeables.close(conn, true);
084    if (CLUSTER.isHBaseClusterRunning()) {
085      CLUSTER.stopHBaseCluster();
086    }
087  }
088
089  @Test
090  public void testStartStop() throws Exception {
091    assertTrue(CLUSTER.isClusterRunning());
092    assertTrue(CLUSTER.isHBaseClusterRunning());
093    assertThrows(IllegalStateException.class, () -> CLUSTER.start());
094    CLUSTER.stop();
095    assertFalse(CLUSTER.isClusterRunning());
096    assertFalse(CLUSTER.isHBaseClusterRunning());
097    assertThrows(IllegalStateException.class, () -> CLUSTER.stop());
098  }
099
100  @Test
101  public void testStartStopHBaseCluster() throws Exception {
102    assertTrue(CLUSTER.isHBaseClusterRunning());
103    assertThrows(IllegalStateException.class, () -> CLUSTER.startHBaseCluster());
104    CLUSTER.stopHBaseCluster();
105    assertTrue(CLUSTER.isClusterRunning());
106    assertFalse(CLUSTER.isHBaseClusterRunning());
107    assertThrows(IllegalStateException.class, () -> CLUSTER.stopHBaseCluster());
108  }
109
110  @Test
111  public void testStartStopMaster() throws Exception {
112    ServerName master = admin.getMaster();
113    CLUSTER.stopMaster(master).join();
114    // wait until the backup master becomes active master.
115    Waiter.waitFor(CLUSTER.getConf(), 30000, () -> {
116      try {
117        return admin.getMaster() != null;
118      } catch (Exception e) {
119        // ignore
120        return false;
121      }
122    });
123    // should have no backup master
124    assertTrue(admin.getBackupMasters().isEmpty());
125    CLUSTER.startMaster();
126    Waiter.waitFor(CLUSTER.getConf(), 30000, () -> !admin.getBackupMasters().isEmpty());
127    CLUSTER.startMaster(DNS.getHostname(CLUSTER.getConf(), ServerType.MASTER), 0);
128    Waiter.waitFor(CLUSTER.getConf(), 30000, () -> admin.getBackupMasters().size() == 2);
129  }
130
131  @Test
132  public void testStartStopRegionServer() throws Exception {
133    Collection<ServerName> regionServers = admin.getRegionServers();
134    assertEquals(3, regionServers.size());
135    CLUSTER.stopRegionServer(Iterables.get(regionServers, 0)).join();
136    Waiter.waitFor(CLUSTER.getConf(), 30000, () -> admin.getRegionServers().size() == 2);
137    CLUSTER.startRegionServer();
138    Waiter.waitFor(CLUSTER.getConf(), 30000, () -> admin.getRegionServers().size() == 3);
139    CLUSTER.startRegionServer(DNS.getHostname(CLUSTER.getConf(), ServerType.REGIONSERVER), 0);
140    Waiter.waitFor(CLUSTER.getConf(), 30000, () -> admin.getRegionServers().size() == 4);
141  }
142
143  @Test
144  public void testGetAddresses() throws Exception {
145    assertTrue(CLUSTER.getActiveMasterAddress().isPresent());
146    assertEquals(1, CLUSTER.getBackupMasterAddresses().size());
147    assertEquals(3, CLUSTER.getRegionServerAddresses().size());
148  }
149}