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.regionserver;
019
020import static junit.framework.TestCase.assertFalse;
021import static junit.framework.TestCase.assertTrue;
022import static org.junit.Assert.assertEquals;
023import static org.junit.Assert.assertNotNull;
024
025import java.net.HttpURLConnection;
026import java.net.URL;
027import java.util.regex.Matcher;
028import java.util.regex.Pattern;
029import org.apache.hadoop.conf.Configuration;
030import org.apache.hadoop.hbase.HBaseClassTestRule;
031import org.apache.hadoop.hbase.HBaseTestingUtility;
032import org.apache.hadoop.hbase.HConstants;
033import org.apache.hadoop.hbase.testclassification.MetricsTests;
034import org.apache.hadoop.hbase.testclassification.SmallTests;
035import org.apache.hadoop.hbase.util.Pair;
036import org.apache.http.client.methods.CloseableHttpResponse;
037import org.apache.http.client.methods.HttpGet;
038import org.apache.http.impl.client.CloseableHttpClient;
039import org.apache.http.impl.client.HttpClients;
040import org.apache.http.util.EntityUtils;
041import org.junit.AfterClass;
042import org.junit.BeforeClass;
043import org.junit.ClassRule;
044import org.junit.Test;
045import org.junit.experimental.categories.Category;
046
047@Category({ MetricsTests.class, SmallTests.class })
048public class TestMetricsJvm {
049  @ClassRule
050  public static final HBaseClassTestRule CLASS_RULE =
051    HBaseClassTestRule.forClass(TestMetricsJvm.class);
052
053  private final static HBaseTestingUtility UTIL = new HBaseTestingUtility();
054  private static Configuration conf;
055
056  @BeforeClass
057  public static void before() throws Exception {
058    conf = UTIL.getConfiguration();
059    // The master info server does not run in tests by default.
060    // Set it to ephemeral port so that it will start
061    conf.setInt(HConstants.MASTER_INFO_PORT, 0);
062    UTIL.startMiniCluster();
063  }
064
065  @AfterClass
066  public static void after() throws Exception {
067    UTIL.shutdownMiniCluster();
068  }
069
070  @Test
071  public void testJvmMetrics() throws Exception {
072    final Pair<Integer, String> jmxPage = getJmxPage("?qry=Hadoop:service=HBase,name=JvmMetrics*");
073    assertNotNull(jmxPage);
074
075    final Integer responseCode = jmxPage.getFirst();
076    final String responseBody = jmxPage.getSecond();
077
078    assertEquals(HttpURLConnection.HTTP_OK, responseCode.intValue());
079    assertNotNull(responseBody);
080
081    assertNotFind("\"tag.ProcessName\"\\s*:\\s*\"IO\"", responseBody);
082    assertReFind("\"tag.ProcessName\"\\s*:\\s*\"Master\"", responseBody);
083  }
084
085  private Pair<Integer, String> getJmxPage(String query) throws Exception {
086    URL url = new URL("http://localhost:"
087      + UTIL.getHBaseCluster().getMaster().getInfoServer().getPort() + "/jmx" + query);
088    return getUrlContent(url);
089  }
090
091  private Pair<Integer, String> getUrlContent(URL url) throws Exception {
092    try (CloseableHttpClient client = HttpClients.createDefault()) {
093      CloseableHttpResponse resp = client.execute(new HttpGet(url.toURI()));
094      int code = resp.getStatusLine().getStatusCode();
095      if (code == HttpURLConnection.HTTP_OK) {
096        return new Pair<>(code, EntityUtils.toString(resp.getEntity()));
097      }
098      return new Pair<>(code, null);
099    }
100  }
101
102  private void assertReFind(String re, String value) {
103    Pattern p = Pattern.compile(re);
104    Matcher m = p.matcher(value);
105    assertTrue("'" + p + "' does not match " + value, m.find());
106  }
107
108  private void assertNotFind(String re, String value) {
109    Pattern p = Pattern.compile(re);
110    Matcher m = p.matcher(value);
111    assertFalse("'" + p + "' should not match " + value, m.find());
112  }
113}