|
18 | 18 | package org.apache.hadoop.hbase.client; |
19 | 19 |
|
20 | 20 | import static org.apache.hadoop.hbase.client.RegionReplicaTestHelper.testLocator; |
21 | | - |
| 21 | +import static org.apache.hadoop.hbase.client.trace.hamcrest.SpanDataMatchers.hasEnded; |
| 22 | +import static org.apache.hadoop.hbase.client.trace.hamcrest.SpanDataMatchers.hasKind; |
| 23 | +import static org.apache.hadoop.hbase.client.trace.hamcrest.SpanDataMatchers.hasName; |
| 24 | +import static org.apache.hadoop.hbase.client.trace.hamcrest.SpanDataMatchers.hasParentSpanId; |
| 25 | +import static org.hamcrest.MatcherAssert.assertThat; |
| 26 | +import static org.hamcrest.Matchers.allOf; |
| 27 | +import static org.hamcrest.Matchers.endsWith; |
| 28 | +import static org.hamcrest.Matchers.hasItem; |
| 29 | +import io.opentelemetry.api.trace.SpanKind; |
| 30 | +import io.opentelemetry.sdk.trace.data.SpanData; |
| 31 | +import java.util.List; |
| 32 | +import java.util.concurrent.TimeUnit; |
| 33 | +import org.apache.hadoop.conf.Configuration; |
| 34 | +import org.apache.hadoop.hbase.ConnectionRule; |
22 | 35 | import org.apache.hadoop.hbase.HBaseClassTestRule; |
23 | 36 | import org.apache.hadoop.hbase.HBaseTestingUtil; |
24 | 37 | import org.apache.hadoop.hbase.HRegionLocation; |
| 38 | +import org.apache.hadoop.hbase.MatcherPredicate; |
| 39 | +import org.apache.hadoop.hbase.MiniClusterRule; |
25 | 40 | import org.apache.hadoop.hbase.RegionLocations; |
| 41 | +import org.apache.hadoop.hbase.StartTestingClusterOption; |
26 | 42 | import org.apache.hadoop.hbase.TableName; |
| 43 | +import org.apache.hadoop.hbase.Waiter; |
27 | 44 | import org.apache.hadoop.hbase.client.RegionReplicaTestHelper.Locator; |
| 45 | +import org.apache.hadoop.hbase.client.trace.StringTraceRenderer; |
28 | 46 | import org.apache.hadoop.hbase.testclassification.ClientTests; |
29 | 47 | import org.apache.hadoop.hbase.testclassification.MediumTests; |
30 | | -import org.junit.AfterClass; |
31 | | -import org.junit.BeforeClass; |
| 48 | +import org.apache.hadoop.hbase.trace.OpenTelemetryClassRule; |
| 49 | +import org.apache.hadoop.hbase.trace.OpenTelemetryTestRule; |
| 50 | +import org.apache.hadoop.hbase.trace.TraceUtil; |
| 51 | +import org.hamcrest.Matcher; |
32 | 52 | import org.junit.ClassRule; |
| 53 | +import org.junit.Rule; |
33 | 54 | import org.junit.Test; |
34 | 55 | import org.junit.experimental.categories.Category; |
35 | | - |
36 | | -import org.apache.hbase.thirdparty.com.google.common.io.Closeables; |
| 56 | +import org.junit.rules.ExternalResource; |
| 57 | +import org.junit.rules.RuleChain; |
| 58 | +import org.junit.rules.TestRule; |
| 59 | +import org.slf4j.Logger; |
| 60 | +import org.slf4j.LoggerFactory; |
37 | 61 |
|
38 | 62 | @Category({ MediumTests.class, ClientTests.class }) |
39 | 63 | public class TestAsyncMetaRegionLocator { |
| 64 | + private static final Logger logger = LoggerFactory.getLogger(TestAsyncMetaRegionLocator.class); |
40 | 65 |
|
41 | 66 | @ClassRule |
42 | 67 | public static final HBaseClassTestRule CLASS_RULE = |
43 | 68 | HBaseClassTestRule.forClass(TestAsyncMetaRegionLocator.class); |
44 | 69 |
|
45 | | - private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil(); |
| 70 | + private static final OpenTelemetryClassRule otelClassRule = OpenTelemetryClassRule.create(); |
| 71 | + private static final MiniClusterRule miniClusterRule = MiniClusterRule.newBuilder() |
| 72 | + .setMiniClusterOption(StartTestingClusterOption.builder() |
| 73 | + .numWorkers(3) |
| 74 | + .build()) |
| 75 | + .build(); |
| 76 | + private static final ConnectionRule connectionRule = |
| 77 | + ConnectionRule.createAsyncConnectionRule(miniClusterRule::createAsyncConnection); |
46 | 78 |
|
47 | | - private static ConnectionRegistry REGISTRY; |
| 79 | + private static final class Setup extends ExternalResource { |
| 80 | + private ConnectionRegistry registry; |
48 | 81 |
|
49 | | - private static AsyncMetaRegionLocator LOCATOR; |
| 82 | + @Override |
| 83 | + protected void before() throws Throwable { |
| 84 | + final AsyncAdmin admin = connectionRule.getAsyncConnection().getAdmin(); |
| 85 | + TEST_UTIL = miniClusterRule.getTestingUtility(); |
| 86 | + HBaseTestingUtil.setReplicas(admin, TableName.META_TABLE_NAME, 3); |
| 87 | + TEST_UTIL.waitUntilNoRegionsInTransition(); |
| 88 | + registry = ConnectionRegistryFactory.getRegistry(TEST_UTIL.getConfiguration()); |
| 89 | + RegionReplicaTestHelper.waitUntilAllMetaReplicasAreReady(TEST_UTIL, registry); |
| 90 | + admin.balancerSwitch(false).get(); |
| 91 | + LOCATOR = new AsyncMetaRegionLocator(registry); |
| 92 | + } |
50 | 93 |
|
51 | | - @BeforeClass |
52 | | - public static void setUp() throws Exception { |
53 | | - TEST_UTIL.startMiniCluster(3); |
54 | | - HBaseTestingUtil.setReplicas(TEST_UTIL.getAdmin(), TableName.META_TABLE_NAME, 3); |
55 | | - TEST_UTIL.waitUntilNoRegionsInTransition(); |
56 | | - REGISTRY = ConnectionRegistryFactory.getRegistry(TEST_UTIL.getConfiguration()); |
57 | | - RegionReplicaTestHelper.waitUntilAllMetaReplicasAreReady(TEST_UTIL, REGISTRY); |
58 | | - TEST_UTIL.getAdmin().balancerSwitch(false, true); |
59 | | - LOCATOR = new AsyncMetaRegionLocator(REGISTRY); |
| 94 | + @Override |
| 95 | + protected void after() { |
| 96 | + registry.close(); |
| 97 | + } |
60 | 98 | } |
61 | 99 |
|
62 | | - @AfterClass |
63 | | - public static void tearDown() throws Exception { |
64 | | - Closeables.close(REGISTRY, true); |
65 | | - TEST_UTIL.shutdownMiniCluster(); |
66 | | - } |
| 100 | + @ClassRule |
| 101 | + public static final TestRule classRule = RuleChain.outerRule(otelClassRule) |
| 102 | + .around(miniClusterRule) |
| 103 | + .around(connectionRule) |
| 104 | + .around(new Setup()); |
| 105 | + |
| 106 | + private static HBaseTestingUtil TEST_UTIL; |
| 107 | + private static AsyncMetaRegionLocator LOCATOR; |
| 108 | + |
| 109 | + @Rule |
| 110 | + public final OpenTelemetryTestRule otelTestRule = new OpenTelemetryTestRule(otelClassRule); |
67 | 111 |
|
68 | 112 | @Test |
69 | 113 | public void test() throws Exception { |
70 | | - testLocator(TEST_UTIL, TableName.META_TABLE_NAME, new Locator() { |
| 114 | + TraceUtil.trace(() -> { |
| 115 | + try { |
| 116 | + testLocator(miniClusterRule.getTestingUtility(), TableName.META_TABLE_NAME, new Locator() { |
| 117 | + @Override |
| 118 | + public void updateCachedLocationOnError(HRegionLocation loc, Throwable error) { |
| 119 | + LOCATOR.updateCachedLocationOnError(loc, error); |
| 120 | + } |
71 | 121 |
|
72 | | - @Override |
73 | | - public void updateCachedLocationOnError(HRegionLocation loc, Throwable error) |
74 | | - throws Exception { |
75 | | - LOCATOR.updateCachedLocationOnError(loc, error); |
| 122 | + @Override |
| 123 | + public RegionLocations getRegionLocations( |
| 124 | + TableName tableName, |
| 125 | + int replicaId, |
| 126 | + boolean reload |
| 127 | + ) throws Exception { |
| 128 | + return LOCATOR.getRegionLocations(replicaId, reload).get(); |
| 129 | + } |
| 130 | + }); |
| 131 | + } catch (Exception e) { |
| 132 | + throw new RuntimeException(e); |
76 | 133 | } |
| 134 | + }, "test"); |
77 | 135 |
|
78 | | - @Override |
79 | | - public RegionLocations getRegionLocations(TableName tableName, int replicaId, boolean reload) |
80 | | - throws Exception { |
81 | | - return LOCATOR.getRegionLocations(replicaId, reload).get(); |
82 | | - } |
83 | | - }); |
| 136 | + final Configuration conf = TEST_UTIL.getConfiguration(); |
| 137 | + final Matcher<SpanData> parentSpanMatcher = allOf(hasName("test"), hasEnded()); |
| 138 | + Waiter.waitFor(conf, TimeUnit.SECONDS.toMillis(5), new MatcherPredicate<>( |
| 139 | + otelClassRule::getSpans, hasItem(parentSpanMatcher))); |
| 140 | + final List<SpanData> spans = otelClassRule.getSpans(); |
| 141 | + if (logger.isDebugEnabled()) { |
| 142 | + StringTraceRenderer renderer = new StringTraceRenderer(spans); |
| 143 | + renderer.render(logger::debug); |
| 144 | + } |
| 145 | + |
| 146 | + assertThat(spans, hasItem(parentSpanMatcher)); |
| 147 | + final SpanData parentSpan = spans.stream() |
| 148 | + .filter(parentSpanMatcher::matches) |
| 149 | + .findAny() |
| 150 | + .orElseThrow(AssertionError::new); |
| 151 | + |
| 152 | + final Matcher<SpanData> registryGetMetaRegionLocationsMatcher = allOf( |
| 153 | + hasName(endsWith("ConnectionRegistry.getMetaRegionLocations")), |
| 154 | + hasParentSpanId(parentSpan), |
| 155 | + hasKind(SpanKind.INTERNAL), |
| 156 | + hasEnded()); |
| 157 | + assertThat(spans, hasItem(registryGetMetaRegionLocationsMatcher)); |
| 158 | + final SpanData registry_getMetaRegionLocationsSpan = spans.stream() |
| 159 | + .filter(registryGetMetaRegionLocationsMatcher::matches) |
| 160 | + .findAny() |
| 161 | + .orElseThrow(AssertionError::new); |
| 162 | + |
| 163 | + final Matcher<SpanData> clientGetMetaRegionLocationsMatcher = allOf( |
| 164 | + hasName(endsWith("ClientMetaService/GetMetaRegionLocations")), |
| 165 | + hasParentSpanId(registry_getMetaRegionLocationsSpan), |
| 166 | + hasKind(SpanKind.CLIENT), |
| 167 | + hasEnded()); |
| 168 | + assertThat(spans, hasItem(clientGetMetaRegionLocationsMatcher)); |
84 | 169 | } |
85 | 170 | } |
0 commit comments