2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org
.apache
.hadoop
.hbase
.client
;
20 import static org
.junit
.Assert
.assertEquals
;
22 import java
.io
.IOException
;
23 import java
.util
.concurrent
.CountDownLatch
;
24 import org
.apache
.hadoop
.hbase
.HBaseClassTestRule
;
25 import org
.apache
.hadoop
.hbase
.HBaseTestingUtility
;
26 import org
.apache
.hadoop
.hbase
.MasterNotRunningException
;
27 import org
.apache
.hadoop
.hbase
.TableName
;
28 import org
.apache
.hadoop
.hbase
.Waiter
;
29 import org
.apache
.hadoop
.hbase
.master
.procedure
.MasterProcedureEnv
;
30 import org
.apache
.hadoop
.hbase
.master
.procedure
.TableProcedureInterface
;
31 import org
.apache
.hadoop
.hbase
.procedure2
.Procedure
;
32 import org
.apache
.hadoop
.hbase
.procedure2
.ProcedureExecutor
;
33 import org
.apache
.hadoop
.hbase
.procedure2
.ProcedureStateSerializer
;
34 import org
.apache
.hadoop
.hbase
.procedure2
.ProcedureSuspendedException
;
35 import org
.apache
.hadoop
.hbase
.procedure2
.ProcedureYieldException
;
36 import org
.apache
.hadoop
.hbase
.testclassification
.MasterTests
;
37 import org
.apache
.hadoop
.hbase
.testclassification
.MediumTests
;
38 import org
.junit
.AfterClass
;
39 import org
.junit
.BeforeClass
;
40 import org
.junit
.ClassRule
;
41 import org
.junit
.Test
;
42 import org
.junit
.experimental
.categories
.Category
;
44 import org
.apache
.hbase
.thirdparty
.com
.google
.protobuf
.ServiceException
;
46 import org
.apache
.hadoop
.hbase
.shaded
.protobuf
.generated
.MasterProtos
;
47 import org
.apache
.hadoop
.hbase
.shaded
.protobuf
.generated
.MasterProtos
.GetProcedureResultRequest
;
48 import org
.apache
.hadoop
.hbase
.shaded
.protobuf
.generated
.MasterProtos
.GetProcedureResultResponse
;
51 * Testcase for HBASE-19608.
53 @Category({ MasterTests
.class, MediumTests
.class })
54 public class TestGetProcedureResult
{
57 public static final HBaseClassTestRule CLASS_RULE
=
58 HBaseClassTestRule
.forClass(TestGetProcedureResult
.class);
60 private static final HBaseTestingUtility UTIL
= new HBaseTestingUtility();
62 public static final class DummyProcedure
extends Procedure
<MasterProcedureEnv
>
63 implements TableProcedureInterface
{
65 private final CountDownLatch failureSet
= new CountDownLatch(1);
67 private final CountDownLatch canRollback
= new CountDownLatch(1);
70 public TableName
getTableName() {
71 return TableName
.valueOf("dummy");
75 public TableOperationType
getTableOperationType() {
76 return TableOperationType
.READ
;
80 protected Procedure
<MasterProcedureEnv
>[] execute(MasterProcedureEnv env
)
81 throws ProcedureYieldException
, ProcedureSuspendedException
, InterruptedException
{
82 setFailure("dummy", new IOException("inject error"));
83 failureSet
.countDown();
88 protected void rollback(MasterProcedureEnv env
) throws IOException
, InterruptedException
{
93 protected boolean abort(MasterProcedureEnv env
) {
98 protected void serializeStateData(ProcedureStateSerializer serializer
) throws IOException
{
102 protected void deserializeStateData(ProcedureStateSerializer serializer
) throws IOException
{
107 public static void setUp() throws Exception
{
108 UTIL
.startMiniCluster(1);
112 public static void tearDown() throws Exception
{
113 UTIL
.shutdownMiniCluster();
116 private GetProcedureResultResponse
.State
getState(long procId
)
117 throws MasterNotRunningException
, IOException
, ServiceException
{
118 MasterProtos
.MasterService
.BlockingInterface master
=
119 ((ConnectionImplementation
) UTIL
.getConnection()).getMaster();
120 GetProcedureResultResponse resp
= master
.getProcedureResult(null,
121 GetProcedureResultRequest
.newBuilder().setProcId(procId
).build());
122 return resp
.getState();
126 public void testRace() throws Exception
{
127 ProcedureExecutor
<MasterProcedureEnv
> executor
=
128 UTIL
.getMiniHBaseCluster().getMaster().getMasterProcedureExecutor();
129 DummyProcedure p
= new DummyProcedure();
130 long procId
= executor
.submitProcedure(p
);
131 p
.failureSet
.await();
132 assertEquals(GetProcedureResultResponse
.State
.RUNNING
, getState(procId
));
133 p
.canRollback
.countDown();
134 UTIL
.waitFor(30000, new Waiter
.ExplainingPredicate
<Exception
>() {
137 public boolean evaluate() throws Exception
{
138 return getState(procId
) == GetProcedureResultResponse
.State
.FINISHED
;
142 public String
explainFailure() throws Exception
{
143 return "Procedure pid=" + procId
+ " is still in " + getState(procId
) +
144 " state, expected " + GetProcedureResultResponse
.State
.FINISHED
;