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.http;
019
020import static org.hamcrest.MatcherAssert.assertThat;
021import static org.hamcrest.Matchers.contains;
022import static org.hamcrest.Matchers.containsInAnyOrder;
023import static org.junit.Assert.assertEquals;
024import static org.junit.Assert.assertNull;
025import javax.servlet.http.HttpServletRequest;
026import org.apache.hadoop.hbase.HBaseClassTestRule;
027import org.apache.hadoop.hbase.TableName;
028import org.apache.hadoop.hbase.client.AsyncConnection;
029import org.apache.hadoop.hbase.master.RegionState;
030import org.apache.hadoop.hbase.master.http.TestMetaBrowser.MockRequestBuilder;
031import org.apache.hadoop.hbase.testclassification.MasterTests;
032import org.apache.hadoop.hbase.testclassification.SmallTests;
033import org.junit.Before;
034import org.junit.ClassRule;
035import org.junit.Test;
036import org.junit.experimental.categories.Category;
037import org.mockito.Mock;
038import org.mockito.MockitoAnnotations;
039
040/**
041 * Cluster-backed correctness tests for the functionality provided by {@link MetaBrowser}.
042 */
043@Category({ MasterTests.class, SmallTests.class})
044public class TestMetaBrowserNoCluster {
045
046  @ClassRule
047  public static final HBaseClassTestRule testRule =
048    HBaseClassTestRule.forClass(TestMetaBrowserNoCluster.class);
049
050  @Mock
051  private AsyncConnection connection;
052
053  @Before
054  public void before() {
055    MockitoAnnotations.initMocks(this);
056  }
057
058  @Test
059  public void buildFirstPageQueryStringNoParams() {
060    final HttpServletRequest request = new MockRequestBuilder().build();
061    final MetaBrowser metaBrowser = new MetaBrowser(connection, request);
062
063    assertEquals("hbase:meta", metaBrowser.getName());
064    assertNull(metaBrowser.getScanLimit());
065    assertNull(metaBrowser.getScanRegionState());
066    assertNull(metaBrowser.getScanStart());
067    assertNull(metaBrowser.getScanTable());
068    assertEquals("/table.jsp?name=hbase%3Ameta", metaBrowser.buildFirstPageUrl());
069  }
070
071  @Test
072  public void buildFirstPageQueryStringNonNullParams() {
073    final HttpServletRequest request = new MockRequestBuilder()
074      .setLimit(50)
075      .setRegionState(RegionState.State.ABNORMALLY_CLOSED)
076      .setTable("foo%3Abar")
077      .build();
078    final MetaBrowser metaBrowser = new MetaBrowser(connection, request);
079
080    assertEquals(50, metaBrowser.getScanLimit().intValue());
081    assertEquals(RegionState.State.ABNORMALLY_CLOSED, metaBrowser.getScanRegionState());
082    assertEquals(TableName.valueOf("foo", "bar"), metaBrowser.getScanTable());
083    assertEquals(
084      "/table.jsp?name=hbase%3Ameta"
085        + "&scan_limit=50"
086        + "&scan_region_state=ABNORMALLY_CLOSED"
087        + "&scan_table=foo%3Abar",
088      metaBrowser.buildNextPageUrl(null));
089  }
090
091  @Test
092  public void buildNextPageQueryString() {
093    final HttpServletRequest request = new MockRequestBuilder().build();
094    final MetaBrowser metaBrowser = new MetaBrowser(connection, request);
095
096    assertEquals(
097      "/table.jsp?name=hbase%3Ameta&scan_start=%255Cx80%255Cx00%255Cx7F",
098      metaBrowser.buildNextPageUrl(new byte[] { Byte.MIN_VALUE, (byte) 0, Byte.MAX_VALUE }));
099  }
100
101  @Test
102  public void unparseableLimitParam() {
103    final HttpServletRequest request = new MockRequestBuilder()
104      .setLimit("foo")
105      .build();
106    final MetaBrowser metaBrowser = new MetaBrowser(connection, request);
107    assertNull(metaBrowser.getScanLimit());
108    assertThat(metaBrowser.getErrorMessages(), contains(
109      "Requested SCAN_LIMIT value 'foo' cannot be parsed as an integer."));
110  }
111
112  @Test
113  public void zeroLimitParam() {
114    final HttpServletRequest request = new MockRequestBuilder()
115      .setLimit(0)
116      .build();
117    final MetaBrowser metaBrowser = new MetaBrowser(connection, request);
118    assertEquals(MetaBrowser.SCAN_LIMIT_DEFAULT, metaBrowser.getScanLimit().intValue());
119    assertThat(metaBrowser.getErrorMessages(), contains(
120      "Requested SCAN_LIMIT value 0 is <= 0."));
121  }
122
123  @Test
124  public void negativeLimitParam() {
125    final HttpServletRequest request = new MockRequestBuilder()
126      .setLimit(-10)
127      .build();
128    final MetaBrowser metaBrowser = new MetaBrowser(connection, request);
129    assertEquals(MetaBrowser.SCAN_LIMIT_DEFAULT, metaBrowser.getScanLimit().intValue());
130    assertThat(metaBrowser.getErrorMessages(), contains(
131      "Requested SCAN_LIMIT value -10 is <= 0."));
132  }
133
134  @Test
135  public void excessiveLimitParam() {
136    final HttpServletRequest request = new MockRequestBuilder()
137      .setLimit(10_001)
138      .build();
139    final MetaBrowser metaBrowser = new MetaBrowser(connection, request);
140    assertEquals(MetaBrowser.SCAN_LIMIT_MAX, metaBrowser.getScanLimit().intValue());
141    assertThat(metaBrowser.getErrorMessages(), contains(
142      "Requested SCAN_LIMIT value 10001 exceeds maximum value 10000."));
143  }
144
145  @Test
146  public void invalidRegionStateParam() {
147    final HttpServletRequest request = new MockRequestBuilder()
148      .setRegionState("foo")
149      .build();
150    final MetaBrowser metaBrowser = new MetaBrowser(connection, request);
151    assertNull(metaBrowser.getScanRegionState());
152    assertThat(metaBrowser.getErrorMessages(), contains(
153      "Requested SCAN_REGION_STATE value 'foo' cannot be parsed as a RegionState."));
154  }
155
156  @Test
157  public void multipleErrorMessages() {
158    final HttpServletRequest request = new MockRequestBuilder()
159      .setLimit("foo")
160      .setRegionState("bar")
161      .build();
162    final MetaBrowser metaBrowser = new MetaBrowser(connection, request);
163    assertThat(metaBrowser.getErrorMessages(), containsInAnyOrder(
164      "Requested SCAN_LIMIT value 'foo' cannot be parsed as an integer.",
165      "Requested SCAN_REGION_STATE value 'bar' cannot be parsed as a RegionState."
166    ));
167  }
168}