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.master;
019
020import static org.junit.jupiter.api.Assertions.assertNotNull;
021import static org.junit.jupiter.api.Assertions.assertTrue;
022
023import java.lang.reflect.Field;
024import java.util.ArrayList;
025import org.apache.hadoop.hbase.HBaseTestingUtil;
026import org.apache.hadoop.hbase.ScheduledChore;
027import org.apache.hadoop.hbase.StartTestingClusterOption;
028import org.apache.hadoop.hbase.master.balancer.BalancerChore;
029import org.apache.hadoop.hbase.master.balancer.ClusterStatusChore;
030import org.apache.hadoop.hbase.master.cleaner.HFileCleaner;
031import org.apache.hadoop.hbase.master.cleaner.LogCleaner;
032import org.apache.hadoop.hbase.master.cleaner.ReplicationBarrierCleaner;
033import org.apache.hadoop.hbase.master.hbck.HbckChore;
034import org.apache.hadoop.hbase.master.janitor.CatalogJanitor;
035import org.apache.hadoop.hbase.testclassification.MasterTests;
036import org.apache.hadoop.hbase.testclassification.MediumTests;
037import org.junit.jupiter.api.AfterAll;
038import org.junit.jupiter.api.BeforeAll;
039import org.junit.jupiter.api.Tag;
040import org.junit.jupiter.api.Test;
041
042/**
043 * Tests to validate if HMaster default chores are scheduled
044 */
045@Tag(MasterTests.TAG)
046@Tag(MediumTests.TAG)
047public class TestMasterChoreScheduled {
048
049  private static HMaster hMaster;
050
051  private static final HBaseTestingUtil UTIL = new HBaseTestingUtil();
052
053  @BeforeAll
054  public static void setUp() throws Exception {
055    UTIL.startMiniCluster(StartTestingClusterOption.builder().numRegionServers(1).build());
056    hMaster = UTIL.getMiniHBaseCluster().getMaster();
057  }
058
059  @AfterAll
060  public static void tearDown() throws Exception {
061    UTIL.shutdownMiniCluster();
062  }
063
064  @Test
065  public void testDefaultScheduledChores() throws Exception {
066    // test if logCleaner chore is scheduled by default in HMaster init
067    TestChoreField<LogCleaner> logCleanerTestChoreField = new TestChoreField<>();
068    LogCleaner logCleaner = logCleanerTestChoreField.getChoreObj("logCleaner");
069    logCleanerTestChoreField.testIfChoreScheduled(logCleaner);
070
071    // test if hfileCleaner chore is scheduled by default in HMaster init
072    TestChoreField<HFileCleaner> hFileCleanerTestChoreField = new TestChoreField<>();
073    Field masterField = HMaster.class.getDeclaredField("hfileCleaners");
074    masterField.setAccessible(true);
075    HFileCleaner hFileCleaner = ((ArrayList<HFileCleaner>) masterField.get(hMaster)).get(0);
076    hFileCleanerTestChoreField.testIfChoreScheduled(hFileCleaner);
077
078    // test if replicationBarrierCleaner chore is scheduled by default in HMaster init
079    TestChoreField<ReplicationBarrierCleaner> replicationBarrierCleanerTestChoreField =
080      new TestChoreField<>();
081    ReplicationBarrierCleaner replicationBarrierCleaner =
082      replicationBarrierCleanerTestChoreField.getChoreObj("replicationBarrierCleaner");
083    replicationBarrierCleanerTestChoreField.testIfChoreScheduled(replicationBarrierCleaner);
084
085    // test if clusterStatusChore chore is scheduled by default in HMaster init
086    TestChoreField<ClusterStatusChore> clusterStatusChoreTestChoreField = new TestChoreField<>();
087    ClusterStatusChore clusterStatusChore =
088      clusterStatusChoreTestChoreField.getChoreObj("clusterStatusChore");
089    clusterStatusChoreTestChoreField.testIfChoreScheduled(clusterStatusChore);
090
091    // test if balancerChore chore is scheduled by default in HMaster init
092    TestChoreField<BalancerChore> balancerChoreTestChoreField = new TestChoreField<>();
093    BalancerChore balancerChore = balancerChoreTestChoreField.getChoreObj("balancerChore");
094    balancerChoreTestChoreField.testIfChoreScheduled(balancerChore);
095
096    // test if normalizerChore chore is scheduled by default in HMaster init
097    ScheduledChore regionNormalizerChore =
098      hMaster.getRegionNormalizerManager().getRegionNormalizerChore();
099    TestChoreField<ScheduledChore> regionNormalizerChoreTestChoreField = new TestChoreField<>();
100    regionNormalizerChoreTestChoreField.testIfChoreScheduled(regionNormalizerChore);
101
102    // test if catalogJanitorChore chore is scheduled by default in HMaster init
103    TestChoreField<CatalogJanitor> catalogJanitorTestChoreField = new TestChoreField<>();
104    CatalogJanitor catalogJanitor = catalogJanitorTestChoreField.getChoreObj("catalogJanitorChore");
105    catalogJanitorTestChoreField.testIfChoreScheduled(catalogJanitor);
106
107    // test if hbckChore chore is scheduled by default in HMaster init
108    TestChoreField<HbckChore> hbckChoreTestChoreField = new TestChoreField<>();
109    HbckChore hbckChore = hbckChoreTestChoreField.getChoreObj("hbckChore");
110    hbckChoreTestChoreField.testIfChoreScheduled(hbckChore);
111  }
112
113  /**
114   * Reflect into the {@link HMaster} instance and find by field name a specified instance of
115   * {@link ScheduledChore}.
116   */
117  private static class TestChoreField<E extends ScheduledChore> {
118
119    @SuppressWarnings("unchecked")
120    private E getChoreObj(String fieldName) {
121      try {
122        Field masterField = HMaster.class.getDeclaredField(fieldName);
123        masterField.setAccessible(true);
124        return (E) masterField.get(hMaster);
125      } catch (Exception e) {
126        throw new AssertionError(
127          "Unable to retrieve field '" + fieldName + "' from HMaster instance.", e);
128      }
129    }
130
131    private void testIfChoreScheduled(E choreObj) {
132      assertNotNull(choreObj);
133      assertTrue(hMaster.getChoreService().isChoreScheduled(choreObj));
134    }
135  }
136}