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 org.junit.Assert.assertTrue;
021
022import io.opentelemetry.sdk.testing.junit4.OpenTelemetryRule;
023import java.io.IOException;
024import java.util.ArrayList;
025import java.util.List;
026import org.apache.hadoop.fs.Path;
027import org.apache.hadoop.hbase.HBaseClassTestRule;
028import org.apache.hadoop.hbase.HBaseTestingUtil;
029import org.apache.hadoop.hbase.TableName;
030import org.apache.hadoop.hbase.TableNameTestRule;
031import org.apache.hadoop.hbase.client.Append;
032import org.apache.hadoop.hbase.client.CheckAndMutate;
033import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
034import org.apache.hadoop.hbase.client.Delete;
035import org.apache.hadoop.hbase.client.Get;
036import org.apache.hadoop.hbase.client.Increment;
037import org.apache.hadoop.hbase.client.Mutation;
038import org.apache.hadoop.hbase.client.Put;
039import org.apache.hadoop.hbase.client.RegionInfo;
040import org.apache.hadoop.hbase.client.RegionInfoBuilder;
041import org.apache.hadoop.hbase.client.Scan;
042import org.apache.hadoop.hbase.client.TableDescriptor;
043import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
044import org.apache.hadoop.hbase.testclassification.MediumTests;
045import org.apache.hadoop.hbase.testclassification.RegionServerTests;
046import org.apache.hadoop.hbase.trace.HBaseSemanticAttributes;
047import org.apache.hadoop.hbase.util.Bytes;
048import org.apache.hadoop.hbase.wal.WAL;
049import org.junit.After;
050import org.junit.AfterClass;
051import org.junit.Before;
052import org.junit.ClassRule;
053import org.junit.Rule;
054import org.junit.Test;
055import org.junit.experimental.categories.Category;
056
057import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
058
059@Category({ RegionServerTests.class, MediumTests.class })
060public class TestHRegionTracing {
061
062  @ClassRule
063  public static final HBaseClassTestRule CLASS_RULE =
064    HBaseClassTestRule.forClass(TestHRegionTracing.class);
065
066  private static HBaseTestingUtil UTIL = new HBaseTestingUtil();
067
068  private static byte[] FAMILY = Bytes.toBytes("family");
069
070  private static byte[] QUALIFIER = Bytes.toBytes("qual");
071
072  private static byte[] ROW = Bytes.toBytes("row");
073
074  private static byte[] VALUE = Bytes.toBytes("value");
075
076  @Rule
077  public final OpenTelemetryRule traceRule = OpenTelemetryRule.create();
078
079  @Rule
080  public final TableNameTestRule tableNameRule = new TableNameTestRule();
081
082  private WAL wal;
083
084  private HRegion region;
085
086  @AfterClass
087  public static void tearDownAfterClass() throws IOException {
088    UTIL.cleanupTestDir();
089  }
090
091  @Before
092  public void setUp() throws IOException {
093    TableName tableName = tableNameRule.getTableName();
094    TableDescriptor desc = TableDescriptorBuilder.newBuilder(tableName)
095      .setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAMILY)).build();
096    RegionInfo info = RegionInfoBuilder.newBuilder(tableName).build();
097    ChunkCreator.initialize(MemStoreLAB.CHUNK_SIZE_DEFAULT, false, 0, 0, 0, null,
098      MemStoreLAB.INDEX_CHUNK_SIZE_PERCENTAGE_DEFAULT);
099    wal = HBaseTestingUtil.createWal(UTIL.getConfiguration(),
100      new Path(UTIL.getDataTestDir(), tableName.getNameAsString()), null);
101    region = HRegion.createHRegion(info, UTIL.getDataTestDir(), UTIL.getConfiguration(), desc, wal);
102    region = UTIL.createLocalHRegion(info, desc);
103  }
104
105  @After
106  public void tearDown() throws IOException {
107    if (region != null) {
108      region.close();
109    }
110    Closeables.close(wal, true);
111  }
112
113  private void assertSpan(String spanName) {
114    assertTrue(traceRule.getSpans().stream().anyMatch(span -> {
115      if (!span.getName().equals(spanName)) {
116        return false;
117      }
118      List<String> regionNames = span.getAttributes().get(HBaseSemanticAttributes.REGION_NAMES_KEY);
119      return regionNames != null && regionNames.size() == 1
120        && regionNames.get(0).equals(region.getRegionInfo().getRegionNameAsString());
121    }));
122  }
123
124  @Test
125  public void testGet() throws IOException {
126    region.get(new Get(ROW));
127    assertSpan("Region.get");
128  }
129
130  @Test
131  public void testPut() throws IOException {
132    region.put(new Put(ROW).addColumn(FAMILY, QUALIFIER, VALUE));
133    assertSpan("Region.put");
134    assertSpan("Region.getRowLock");
135  }
136
137  @Test
138  public void testDelete() throws IOException {
139    region.delete(new Delete(ROW).addColumn(FAMILY, QUALIFIER));
140    assertSpan("Region.delete");
141    assertSpan("Region.getRowLock");
142  }
143
144  @Test
145  public void testAppend() throws IOException {
146    region.append(new Append(ROW).addColumn(FAMILY, QUALIFIER, VALUE));
147    assertSpan("Region.append");
148    assertSpan("Region.getRowLock");
149  }
150
151  @Test
152  public void testIncrement() throws IOException {
153    region.increment(new Increment(ROW).addColumn(FAMILY, QUALIFIER, 1));
154    assertSpan("Region.increment");
155    assertSpan("Region.getRowLock");
156  }
157
158  @Test
159  public void testBatchMutate() throws IOException {
160    region.batchMutate(new Mutation[] { new Put(ROW).addColumn(FAMILY, QUALIFIER, VALUE) });
161    assertSpan("Region.batchMutate");
162    assertSpan("Region.getRowLock");
163  }
164
165  @Test
166  public void testCheckAndMutate() throws IOException {
167    region.checkAndMutate(CheckAndMutate.newBuilder(ROW).ifNotExists(FAMILY, QUALIFIER)
168      .build(new Put(ROW).addColumn(FAMILY, QUALIFIER, VALUE)));
169    assertSpan("Region.checkAndMutate");
170    assertSpan("Region.getRowLock");
171  }
172
173  @Test
174  public void testScanner() throws IOException {
175    try (RegionScanner scanner = region.getScanner(new Scan())) {
176      scanner.reseek(ROW);
177      scanner.next(new ArrayList<>());
178    }
179    assertSpan("Region.getScanner");
180    assertSpan("RegionScanner.reseek");
181    assertSpan("RegionScanner.close");
182  }
183}