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