1   /*
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
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
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.
17   */
18  package org.apache.hadoop.hbase.rest.client;
19  
20  import static org.junit.Assert.assertTrue;
21  import static org.junit.Assert.fail;
22  import static org.mockito.Matchers.any;
23  import static org.mockito.Matchers.anyString;
24  import static org.mockito.Mockito.mock;
25  import static org.mockito.Mockito.times;
26  import static org.mockito.Mockito.verify;
27  import static org.mockito.Mockito.when;
28  
29  import java.io.IOException;
30  import java.util.regex.Pattern;
31  
32  import org.apache.hadoop.conf.Configuration;
33  import org.apache.hadoop.hbase.HBaseTestingUtility;
34  import org.apache.hadoop.hbase.HTableDescriptor;
35  import org.apache.hadoop.hbase.SmallTests;
36  import org.apache.hadoop.hbase.util.Bytes;
37  import org.junit.Before;
38  import org.junit.Test;
39  import org.junit.experimental.categories.Category;
40  
41  /**
42   * Tests {@link RemoteAdmin} retries.
43   */
44  @Category(SmallTests.class)
45  public class TestRemoteAdminRetries {
46  
47    private static final int SLEEP_TIME = 50;
48    private static final int RETRIES = 3;
49    private static final long MAX_TIME = SLEEP_TIME * (RETRIES - 1);
50    
51    private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
52    
53    private RemoteAdmin remoteAdmin;
54    private Client client;
55  
56    @Before
57    public void setup() throws Exception {
58      client = mock(Client.class);
59      Response response = new Response(509);
60      when(client.get(anyString(), anyString())).thenReturn(response);
61      when(client.delete(anyString())).thenReturn(response);
62      when(client.put(anyString(), anyString(), any(byte[].class))).thenReturn(response);
63      when(client.post(anyString(), anyString(), any(byte[].class))).thenReturn(response);
64      Configuration configuration = TEST_UTIL.getConfiguration();
65  
66      configuration.setInt("hbase.rest.client.max.retries", RETRIES);
67      configuration.setInt("hbase.rest.client.sleep", SLEEP_TIME);
68  
69      remoteAdmin = new RemoteAdmin(client, TEST_UTIL.getConfiguration(), "MyTable");
70    }
71  
72    @Test
73    public void testFailingGetRestVersion() throws Exception  {
74      testTimedOutGetCall(new CallExecutor() {
75        @Override
76        public void run() throws Exception {
77          remoteAdmin.getRestVersion();
78        }
79      });
80    }
81    
82    @Test
83    public void testFailingGetClusterStatus() throws Exception  {
84      testTimedOutGetCall(new CallExecutor() {
85        @Override
86        public void run() throws Exception {
87          remoteAdmin.getClusterStatus();
88        }
89      });
90    }
91  
92    @Test
93    public void testFailingGetClusterVersion() throws Exception {
94      testTimedOutGetCall(new CallExecutor() {
95        @Override
96        public void run() throws Exception {
97          remoteAdmin.getClusterVersion();
98        }
99      });
100   }
101 
102   @Test
103   public void testFailingGetTableAvailable() throws Exception {
104     testTimedOutCall(new CallExecutor() {
105       @Override
106       public void run() throws Exception {
107         remoteAdmin.isTableAvailable(Bytes.toBytes("TestTable"));
108       }
109     });
110   }
111 
112   @Test
113   public void testFailingCreateTable() throws Exception {
114     testTimedOutCall(new CallExecutor() {
115       @Override
116       public void run() throws Exception {
117         remoteAdmin.createTable(new HTableDescriptor(Bytes.toBytes("TestTable")));
118       }
119     });
120     verify(client, times(RETRIES)).put(anyString(), anyString(), any(byte[].class));
121   }
122 
123   @Test
124   public void testFailingDeleteTable() throws Exception {
125     testTimedOutCall(new CallExecutor() {
126       @Override
127       public void run() throws Exception {
128         remoteAdmin.deleteTable("TestTable");
129       }
130     });
131     verify(client, times(RETRIES)).delete(anyString());
132   }
133 
134   @Test
135   public void testFailingGetTableList() throws Exception {
136     testTimedOutGetCall(new CallExecutor() {
137       @Override
138       public void run() throws Exception {
139         remoteAdmin.getTableList();
140       }
141     });
142   }
143   
144   private void testTimedOutGetCall(CallExecutor callExecutor) throws Exception {
145     testTimedOutCall(callExecutor);
146     verify(client, times(RETRIES)).get(anyString(), anyString());
147   }
148   
149   private void testTimedOutCall(CallExecutor callExecutor) throws Exception {
150     long start = System.currentTimeMillis();
151     try {
152       callExecutor.run();
153       fail("should be timeout exception!");
154     } catch (IOException e) {
155       assertTrue(Pattern.matches(".*MyTable.*timed out", e.toString()));
156     }
157     assertTrue((System.currentTimeMillis() - start) > MAX_TIME);
158   }
159 
160   private static interface CallExecutor {
161     void run() throws Exception;
162   }
163   
164 }