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.client;
019
020import static org.junit.Assert.fail;
021
022import java.io.IOException;
023import java.util.Arrays;
024import java.util.List;
025import java.util.function.Consumer;
026import org.apache.hadoop.hbase.HBaseClassTestRule;
027import org.apache.hadoop.hbase.HColumnDescriptor;
028import org.apache.hadoop.hbase.HTableDescriptor;
029import org.apache.hadoop.hbase.TableName;
030import org.apache.hadoop.hbase.testclassification.ClientTests;
031import org.apache.hadoop.hbase.testclassification.SmallTests;
032import org.apache.hadoop.hbase.util.BuilderStyleTest;
033import org.apache.hadoop.hbase.util.Bytes;
034import org.junit.ClassRule;
035import org.junit.Rule;
036import org.junit.Test;
037import org.junit.experimental.categories.Category;
038import org.junit.rules.TestName;
039
040@Category({ClientTests.class, SmallTests.class})
041public class TestImmutableHTableDescriptor {
042
043  @ClassRule
044  public static final HBaseClassTestRule CLASS_RULE =
045      HBaseClassTestRule.forClass(TestImmutableHTableDescriptor.class);
046
047  @Rule
048  public TestName name = new TestName();
049  private static final List<Consumer<ImmutableHTableDescriptor>> TEST_FUNCTION = Arrays.asList(
050    htd -> htd.setValue("a", "a"),
051    htd -> htd.setValue(Bytes.toBytes("a"), Bytes.toBytes("a")),
052    htd -> htd.setValue(new Bytes(Bytes.toBytes("a")), new Bytes(Bytes.toBytes("a"))),
053    htd -> htd.setCompactionEnabled(false),
054    htd -> htd.setConfiguration("aaa", "ccc"),
055    htd -> htd.setDurability(Durability.USE_DEFAULT),
056    htd -> htd.setFlushPolicyClassName("class"),
057    htd -> htd.setMaxFileSize(123),
058    htd -> htd.setMemStoreFlushSize(123123123),
059    htd -> htd.setNormalizationEnabled(false),
060    htd -> htd.setPriority(123),
061    htd -> htd.setReadOnly(true),
062    htd -> htd.setRegionMemstoreReplication(true),
063    htd -> htd.setRegionReplication(123),
064    htd -> htd.setRegionSplitPolicyClassName("class"),
065    htd -> htd.addFamily(new HColumnDescriptor(Bytes.toBytes("fm"))),
066    htd -> htd.remove(new Bytes(Bytes.toBytes("aaa"))),
067    htd -> htd.remove("aaa"),
068    htd -> htd.remove(Bytes.toBytes("aaa")),
069    htd -> htd.removeConfiguration("xxx"),
070    htd -> htd.removeFamily(Bytes.toBytes("fm")),
071    htd -> {
072      try {
073        htd.addCoprocessor("xxx");
074      } catch (IOException e) {
075        throw new RuntimeException(e);
076      }
077    }
078  );
079
080  @Test
081  public void testImmutable() {
082    HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(name.getMethodName()));
083    ImmutableHTableDescriptor immutableHtd = new ImmutableHTableDescriptor(htd);
084    TEST_FUNCTION.forEach(f -> {
085      try {
086        f.accept(immutableHtd);
087        fail("ImmutableHTableDescriptor can't be modified!!!");
088      } catch (UnsupportedOperationException e) {
089      }
090    });
091  }
092
093  @Test
094  public void testImmutableHColumnDescriptor() {
095    HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(name.getMethodName()));
096    htd.addFamily(new HColumnDescriptor(Bytes.toBytes("family")));
097    ImmutableHTableDescriptor immutableHtd = new ImmutableHTableDescriptor(htd);
098    for (HColumnDescriptor hcd : immutableHtd.getColumnFamilies()) {
099      assertReadOnly(hcd);
100    }
101    for (HColumnDescriptor hcd : immutableHtd.getFamilies()) {
102      assertReadOnly(hcd);
103    }
104  }
105
106  private void assertReadOnly(HColumnDescriptor hcd) {
107    try {
108      hcd.setBlocksize(10);
109      fail("ImmutableHColumnDescriptor can't be modified!!!");
110    } catch (UnsupportedOperationException e) {
111    }
112  }
113
114  @Test
115  public void testClassMethodsAreBuilderStyle() {
116  /* ImmutableHTableDescriptor should have a builder style setup where setXXX/addXXX methods
117   * can be chainable together:
118   * . For example:
119   * ImmutableHTableDescriptor d
120   *   = new ImmutableHTableDescriptor()
121   *     .setFoo(foo)
122   *     .setBar(bar)
123   *     .setBuz(buz)
124   *
125   * This test ensures that all methods starting with "set" returns the declaring object
126   */
127
128      BuilderStyleTest.assertClassesAreBuilderStyle(ImmutableHTableDescriptor.class);
129  }
130}