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;
019
020import static org.junit.jupiter.api.Assertions.assertEquals;
021
022import java.io.IOException;
023import org.apache.hadoop.fs.Path;
024import org.apache.hadoop.hbase.client.Admin;
025import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
026import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
027import org.apache.hadoop.hbase.client.TableDescriptor;
028import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
029import org.apache.hadoop.hbase.master.MasterFileSystem;
030import org.apache.hadoop.hbase.testclassification.MediumTests;
031import org.apache.hadoop.hbase.testclassification.MiscTests;
032import org.apache.hadoop.hbase.util.Bytes;
033import org.apache.hadoop.hbase.util.CommonFSUtils;
034import org.apache.hadoop.hbase.util.FSTableDescriptors;
035import org.junit.jupiter.api.AfterAll;
036import org.junit.jupiter.api.BeforeAll;
037import org.junit.jupiter.api.BeforeEach;
038import org.junit.jupiter.api.Tag;
039import org.junit.jupiter.api.Test;
040import org.junit.jupiter.api.TestInfo;
041
042/**
043 * Verify that the ColumnFamilyDescriptor version is set correctly by default, hbase-site.xml, and
044 * user input
045 */
046@Tag(MiscTests.TAG)
047@Tag(MediumTests.TAG)
048public class TestColumnFamilyDescriptorDefaultVersions {
049
050  private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
051  private static TableName TABLE_NAME = null;
052  private static final byte[] FAMILY = Bytes.toBytes("cf0");
053
054  /**
055   * Start up a mini cluster and put a small table of empty regions into it.
056   */
057  @BeforeAll
058  public static void beforeAllTests() throws Exception {
059    TEST_UTIL.startMiniCluster(1);
060  }
061
062  @BeforeEach
063  public void setup(TestInfo testInfo) {
064    TABLE_NAME = TableName.valueOf(testInfo.getTestMethod().get().getName());
065
066  }
067
068  @AfterAll
069  public static void afterAllTests() throws Exception {
070    TEST_UTIL.shutdownMiniCluster();
071  }
072
073  @Test
074  public void testCreateTableWithDefault() throws IOException {
075    Admin admin = TEST_UTIL.getAdmin();
076    // Create a table with one family
077    TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(TABLE_NAME)
078      .setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAMILY)).build();
079    admin.createTable(tableDescriptor);
080    admin.disableTable(TABLE_NAME);
081    try {
082      // Verify the column descriptor
083      verifyHColumnDescriptor(1, TABLE_NAME, FAMILY);
084    } finally {
085      admin.deleteTable(TABLE_NAME);
086    }
087  }
088
089  @Test
090  public void testCreateTableWithDefaultFromConf() throws Exception {
091    TEST_UTIL.shutdownMiniCluster();
092    TEST_UTIL.getConfiguration().setInt("hbase.column.max.version", 3);
093    TEST_UTIL.startMiniCluster(1);
094
095    Admin admin = TEST_UTIL.getAdmin();
096    // Create a table with one family
097    TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(TABLE_NAME)
098      .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(FAMILY)
099        .setMaxVersions(TEST_UTIL.getConfiguration().getInt("hbase.column.max.version", 1)).build())
100      .build();
101    admin.createTable(tableDescriptor);
102    admin.disableTable(TABLE_NAME);
103    try {
104      // Verify the column descriptor
105      verifyHColumnDescriptor(3, TABLE_NAME, FAMILY);
106    } finally {
107      admin.deleteTable(TABLE_NAME);
108    }
109  }
110
111  @Test
112  public void testCreateTableWithSetVersion() throws Exception {
113    TEST_UTIL.shutdownMiniCluster();
114    TEST_UTIL.getConfiguration().setInt("hbase.column.max.version", 3);
115    TEST_UTIL.startMiniCluster(1);
116
117    Admin admin = TEST_UTIL.getAdmin();
118    // Create a table with one family
119    TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(TABLE_NAME)
120      .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(FAMILY).setMaxVersions(5).build())
121      .build();
122    admin.createTable(tableDescriptor);
123    admin.disableTable(TABLE_NAME);
124    try {
125      // Verify the column descriptor
126      verifyHColumnDescriptor(5, TABLE_NAME, FAMILY);
127
128    } finally {
129      admin.deleteTable(TABLE_NAME);
130    }
131  }
132
133  @Test
134  public void testHColumnDescriptorCachedMaxVersions() throws Exception {
135    ColumnFamilyDescriptor familyDescriptor =
136      ColumnFamilyDescriptorBuilder.newBuilder(FAMILY).setMaxVersions(5).build();
137    // Verify the max version
138    assertEquals(5, familyDescriptor.getMaxVersions());
139
140    // modify the max version
141    familyDescriptor = ColumnFamilyDescriptorBuilder.newBuilder(familyDescriptor)
142      .setValue(Bytes.toBytes(HConstants.VERSIONS), Bytes.toBytes("8")).build();
143    // Verify the max version
144    assertEquals(8, familyDescriptor.getMaxVersions());
145  }
146
147  private void verifyHColumnDescriptor(int expected, final TableName tableName,
148    final byte[]... families) throws IOException {
149    Admin admin = TEST_UTIL.getAdmin();
150
151    // Verify descriptor from master
152    TableDescriptor htd = admin.getDescriptor(tableName);
153    ColumnFamilyDescriptor[] hcds = htd.getColumnFamilies();
154    verifyColumnFamilyDescriptor(expected, hcds, tableName, families);
155
156    // Verify descriptor from HDFS
157    MasterFileSystem mfs = TEST_UTIL.getMiniHBaseCluster().getMaster().getMasterFileSystem();
158    Path tableDir = CommonFSUtils.getTableDir(mfs.getRootDir(), tableName);
159    TableDescriptor td = FSTableDescriptors.getTableDescriptorFromFs(mfs.getFileSystem(), tableDir);
160    hcds = td.getColumnFamilies();
161    verifyColumnFamilyDescriptor(expected, hcds, tableName, families);
162  }
163
164  private void verifyColumnFamilyDescriptor(int expected, final ColumnFamilyDescriptor[] hcds,
165    final TableName tableName, final byte[]... families) {
166    for (ColumnFamilyDescriptor hcd : hcds) {
167      assertEquals(expected, hcd.getMaxVersions());
168    }
169  }
170}