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.balancer; 019 020import static org.apache.hadoop.hbase.master.balancer.HeterogeneousCostRulesTestHelper.DEFAULT_RULES_FILE_NAME; 021import static org.apache.hadoop.hbase.master.balancer.HeterogeneousCostRulesTestHelper.cleanup; 022import static org.apache.hadoop.hbase.master.balancer.HeterogeneousCostRulesTestHelper.createRulesFile; 023import static org.junit.jupiter.api.Assertions.assertEquals; 024 025import java.io.IOException; 026import java.util.Arrays; 027import java.util.Collections; 028import org.apache.hadoop.hbase.HBaseCommonTestingUtil; 029import org.apache.hadoop.hbase.testclassification.MasterTests; 030import org.apache.hadoop.hbase.testclassification.MediumTests; 031import org.junit.jupiter.api.BeforeAll; 032import org.junit.jupiter.api.BeforeEach; 033import org.junit.jupiter.api.Tag; 034import org.junit.jupiter.api.Test; 035import org.junit.jupiter.api.TestInfo; 036 037@Tag(MasterTests.TAG) 038@Tag(MediumTests.TAG) 039public class TestStochasticLoadBalancerHeterogeneousCostRules extends StochasticBalancerTestBase { 040 041 private HeterogeneousRegionCountCostFunction costFunction; 042 private static final HBaseCommonTestingUtil HTU = new HBaseCommonTestingUtil(); 043 044 /** 045 * Make a file for rules that is inside a temporary test dir named for the method so it doesn't 046 * clash w/ other rule files. 047 */ 048 private String rulesFilename; 049 050 @BeforeAll 051 public static void beforeClass() throws IOException { 052 // Ensure test dir is created 053 HTU.getDataTestDir().getFileSystem(HTU.getConfiguration()).mkdirs(HTU.getDataTestDir()); 054 } 055 056 @BeforeEach 057 public void before(TestInfo testInfo) throws IOException { 058 // New rules file name per test. 059 this.rulesFilename = 060 HTU.getDataTestDir(testInfo.getTestMethod().get().getName() + "." + DEFAULT_RULES_FILE_NAME) 061 .toString(); 062 // Set the created rules filename into the configuration. 063 HTU.getConfiguration().set( 064 HeterogeneousRegionCountCostFunction.HBASE_MASTER_BALANCER_HETEROGENEOUS_RULES_FILE, 065 this.rulesFilename); 066 } 067 068 @Test 069 public void testNoRules() throws IOException { 070 // Override what is in the configuration with the name of a non-existent file! 071 HTU.getConfiguration().set( 072 HeterogeneousRegionCountCostFunction.HBASE_MASTER_BALANCER_HETEROGENEOUS_RULES_FILE, 073 "non-existent-file!"); 074 this.costFunction = new HeterogeneousRegionCountCostFunction(HTU.getConfiguration()); 075 this.costFunction.loadRules(); 076 assertEquals(0, this.costFunction.getNumberOfRulesLoaded()); 077 } 078 079 @Test 080 public void testBadFormatInRules() throws IOException { 081 // See {@link #before} above. It sets this.rulesFilename, and 082 // HeterogeneousRegionCountCostFunction.HBASE_MASTER_BALANCER_HETEROGENEOUS_RULES_FILE, 083 // in the configuration. 084 this.costFunction = new HeterogeneousRegionCountCostFunction(HTU.getConfiguration()); 085 this.costFunction.loadRules(); 086 assertEquals(0, this.costFunction.getNumberOfRulesLoaded()); 087 088 createRulesFile(this.rulesFilename, Collections.singletonList("bad rules format")); 089 this.costFunction = new HeterogeneousRegionCountCostFunction(HTU.getConfiguration()); 090 this.costFunction.loadRules(); 091 assertEquals(0, this.costFunction.getNumberOfRulesLoaded()); 092 093 createRulesFile(this.rulesFilename, Arrays.asList("srv[1-2] 10", "bad_rules format", "a")); 094 this.costFunction = new HeterogeneousRegionCountCostFunction(HTU.getConfiguration()); 095 this.costFunction.loadRules(); 096 assertEquals(1, this.costFunction.getNumberOfRulesLoaded()); 097 } 098 099 @Test 100 public void testTwoRules() throws IOException { 101 // See {@link #before} above. It sets this.rulesFilename, and 102 // HeterogeneousRegionCountCostFunction.HBASE_MASTER_BALANCER_HETEROGENEOUS_RULES_FILE, 103 // in the configuration. 104 // See {@link #before} above. It sets 105 // HeterogeneousRegionCountCostFunction.HBASE_MASTER_BALANCER_HETEROGENEOUS_RULES_FILE, 106 // in the configuration. 107 createRulesFile(this.rulesFilename, Arrays.asList("^server1$ 10", "^server2 21")); 108 this.costFunction = new HeterogeneousRegionCountCostFunction(HTU.getConfiguration()); 109 this.costFunction.loadRules(); 110 assertEquals(2, this.costFunction.getNumberOfRulesLoaded()); 111 } 112 113 @Test 114 public void testBadRegexp() throws IOException { 115 // See {@link #before} above. It sets this.rulesFilename, and 116 // HeterogeneousRegionCountCostFunction.HBASE_MASTER_BALANCER_HETEROGENEOUS_RULES_FILE, 117 // in the configuration. 118 // See {@link #before} above. It sets 119 // HeterogeneousRegionCountCostFunction.HBASE_MASTER_BALANCER_HETEROGENEOUS_RULES_FILE, 120 // in the configuration. 121 createRulesFile(this.rulesFilename, Collections.singletonList("server[ 1")); 122 this.costFunction = new HeterogeneousRegionCountCostFunction(HTU.getConfiguration()); 123 this.costFunction.loadRules(); 124 assertEquals(0, this.costFunction.getNumberOfRulesLoaded()); 125 } 126 127 @Test 128 public void testNoOverride() throws IOException { 129 // See {@link #before} above. It sets this.rulesFilename, and 130 // HeterogeneousRegionCountCostFunction.HBASE_MASTER_BALANCER_HETEROGENEOUS_RULES_FILE, 131 // in the configuration. 132 createRulesFile(this.rulesFilename, Arrays.asList("^server1$ 10", "^server2 21")); 133 this.costFunction = new HeterogeneousRegionCountCostFunction(HTU.getConfiguration()); 134 this.costFunction.loadRules(); 135 assertEquals(2, this.costFunction.getNumberOfRulesLoaded()); 136 137 // loading malformed configuration does not overload current 138 cleanup(this.rulesFilename); 139 this.costFunction.loadRules(); 140 assertEquals(2, this.costFunction.getNumberOfRulesLoaded()); 141 } 142}