View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
3    * agreements. See the NOTICE file distributed with this work for additional information regarding
4    * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
5    * "License"); you may not use this file except in compliance with the License. You may obtain a
6    * copy of the License at
7    * <p>
8    * http://www.apache.org/licenses/LICENSE-2.0
9    * <p>
10   * Unless required by applicable law or agreed to in writing, software distributed under the License
11   * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing permissions and limitations under
13   * the License.
14   */
15  package org.apache.hadoop.hbase.master.balancer;
16  
17  import java.io.File;
18  import java.io.IOException;
19  import java.nio.charset.Charset;
20  import java.nio.file.Files;
21  import java.nio.file.Path;
22  import java.nio.file.Paths;
23  import java.util.ArrayList;
24  import java.util.Arrays;
25  import java.util.Collections;
26  import java.util.List;
27  
28  import org.apache.hadoop.conf.Configuration;
29  import org.apache.hadoop.fs.FSDataOutputStream;
30  import org.apache.hadoop.hbase.HBaseTestingUtility;
31  import org.apache.hadoop.hbase.testclassification.SmallTests;
32  import org.apache.hadoop.hdfs.DistributedFileSystem;
33  import org.apache.hadoop.hdfs.MiniDFSCluster;
34  import org.junit.AfterClass;
35  import org.junit.Assert;
36  import org.junit.BeforeClass;
37  import org.junit.Test;
38  import org.junit.experimental.categories.Category;
39  
40  @Category({SmallTests.class})
41  public class TestStochasticLoadBalancerHeterogeneousCostRules extends BalancerTestBase {
42  
43    static final String DEFAULT_RULES_TMP_LOCATION = "/tmp/hbase-balancer.rules";
44    static Configuration conf;
45    private HeterogeneousRegionCountCostFunction costFunction;
46  
47    @BeforeClass
48    public static void beforeAllTests() throws Exception {
49      createSimpleRulesFile(new ArrayList<String>());
50      conf = new Configuration();
51      conf.set(HeterogeneousRegionCountCostFunction.HBASE_MASTER_BALANCER_HETEROGENEOUS_RULES_FILE,
52        DEFAULT_RULES_TMP_LOCATION);
53    }
54  
55    static void createSimpleRulesFile(final List<String> lines) throws IOException {
56      cleanup();
57      final Path file = Paths.get(DEFAULT_RULES_TMP_LOCATION);
58      Files.write(file, lines, Charset.forName("UTF-8"));
59    }
60  
61    protected static void cleanup() {
62      final File file = new File(DEFAULT_RULES_TMP_LOCATION);
63      file.delete();
64    }
65  
66    @AfterClass
67    public static void afterAllTests() {
68      cleanup();
69    }
70  
71    @Test
72    public void testNoRules() {
73      cleanup();
74      this.costFunction = new HeterogeneousRegionCountCostFunction(conf);
75      this.costFunction.loadRules();
76      Assert.assertEquals(0, this.costFunction.getNumberOfRulesLoaded());
77    }
78  
79    @Test
80    public void testBadFormatInRules() throws IOException {
81      createSimpleRulesFile(new ArrayList<String>());
82      this.costFunction = new HeterogeneousRegionCountCostFunction(conf);
83      this.costFunction.loadRules();
84      Assert.assertEquals(0, this.costFunction.getNumberOfRulesLoaded());
85  
86      createSimpleRulesFile(Collections.singletonList("bad rules format"));
87      this.costFunction = new HeterogeneousRegionCountCostFunction(conf);
88      this.costFunction.loadRules();
89      Assert.assertEquals(0, this.costFunction.getNumberOfRulesLoaded());
90  
91      createSimpleRulesFile(Arrays.asList("srv[1-2] 10", "bad_rules format", "a"));
92      this.costFunction = new HeterogeneousRegionCountCostFunction(conf);
93      this.costFunction.loadRules();
94      Assert.assertEquals(1, this.costFunction.getNumberOfRulesLoaded());
95    }
96  
97    @Test
98    public void testTwoRules() throws IOException {
99      createSimpleRulesFile(Arrays.asList("^server1$ 10", "^server2 21"));
100     this.costFunction = new HeterogeneousRegionCountCostFunction(conf);
101     this.costFunction.loadRules();
102     Assert.assertEquals(2, this.costFunction.getNumberOfRulesLoaded());
103   }
104 
105   @Test
106   public void testBadRegexp() throws IOException {
107     createSimpleRulesFile(Collections.singletonList("server[ 1"));
108     this.costFunction = new HeterogeneousRegionCountCostFunction(conf);
109     this.costFunction.loadRules();
110     Assert.assertEquals(0, this.costFunction.getNumberOfRulesLoaded());
111   }
112 
113   @Test
114   public void testNoOverride() throws IOException {
115     createSimpleRulesFile(Arrays.asList("^server1$ 10", "^server2 21"));
116     this.costFunction = new HeterogeneousRegionCountCostFunction(conf);
117     this.costFunction.loadRules();
118     Assert.assertEquals(2, this.costFunction.getNumberOfRulesLoaded());
119 
120     // loading malformed configuration does not overload current
121     cleanup();
122     this.costFunction.loadRules();
123     Assert.assertEquals(2, this.costFunction.getNumberOfRulesLoaded());
124   }
125 
126   @Test
127   public void testLoadingFomHDFS() throws Exception {
128 
129     HBaseTestingUtility hBaseTestingUtility = new HBaseTestingUtility();
130     hBaseTestingUtility.startMiniDFSCluster(3);
131 
132     MiniDFSCluster cluster = hBaseTestingUtility.getDFSCluster();
133     DistributedFileSystem fs = cluster.getFileSystem();
134 
135     String path = cluster.getURI() + DEFAULT_RULES_TMP_LOCATION;
136 
137     // writing file
138     FSDataOutputStream stream = fs.create(new org.apache.hadoop.fs.Path(path));
139     stream.write("server1 10".getBytes());
140     stream.flush();
141     stream.close();
142 
143     Configuration configuration = hBaseTestingUtility.getConfiguration();
144 
145     // start costFunction
146     configuration.set(
147       HeterogeneousRegionCountCostFunction.HBASE_MASTER_BALANCER_HETEROGENEOUS_RULES_FILE, path);
148     this.costFunction = new HeterogeneousRegionCountCostFunction(configuration);
149     this.costFunction.loadRules();
150     Assert.assertEquals(1, this.costFunction.getNumberOfRulesLoaded());
151 
152     hBaseTestingUtility.shutdownMiniCluster();
153   }
154 }