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.master; 019 020import static org.junit.Assert.fail; 021import static org.mockito.Mockito.mock; 022import static org.mockito.Mockito.when; 023 024import java.net.InetAddress; 025import org.apache.hadoop.conf.Configuration; 026import org.apache.hadoop.hbase.ClockOutOfSyncException; 027import org.apache.hadoop.hbase.HBaseClassTestRule; 028import org.apache.hadoop.hbase.HBaseConfiguration; 029import org.apache.hadoop.hbase.client.ClusterConnection; 030import org.apache.hadoop.hbase.ipc.RpcControllerFactory; 031import org.apache.hadoop.hbase.testclassification.MasterTests; 032import org.apache.hadoop.hbase.testclassification.SmallTests; 033import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 034import org.junit.ClassRule; 035import org.junit.Test; 036import org.junit.experimental.categories.Category; 037import org.slf4j.Logger; 038import org.slf4j.LoggerFactory; 039 040import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionServerStartupRequest; 041 042@Category({ MasterTests.class, SmallTests.class }) 043public class TestClockSkewDetection { 044 045 @ClassRule 046 public static final HBaseClassTestRule CLASS_RULE = 047 HBaseClassTestRule.forClass(TestClockSkewDetection.class); 048 049 private static final Logger LOG = LoggerFactory.getLogger(TestClockSkewDetection.class); 050 051 @Test 052 public void testClockSkewDetection() throws Exception { 053 final Configuration conf = HBaseConfiguration.create(); 054 ServerManager sm = new ServerManager(new MockNoopMasterServices(conf) { 055 @Override 056 public ClusterConnection getClusterConnection() { 057 ClusterConnection conn = mock(ClusterConnection.class); 058 when(conn.getRpcControllerFactory()).thenReturn(mock(RpcControllerFactory.class)); 059 return conn; 060 } 061 }, new DummyRegionServerList()); 062 063 LOG.debug("regionServerStartup 1"); 064 InetAddress ia1 = InetAddress.getLocalHost(); 065 RegionServerStartupRequest.Builder request = RegionServerStartupRequest.newBuilder(); 066 request.setPort(1234); 067 request.setServerStartCode(-1); 068 request.setServerCurrentTime(EnvironmentEdgeManager.currentTime()); 069 sm.regionServerStartup(request.build(), 0, "0.0.0", ia1); 070 071 final Configuration c = HBaseConfiguration.create(); 072 long maxSkew = c.getLong("hbase.master.maxclockskew", 30000); 073 long warningSkew = c.getLong("hbase.master.warningclockskew", 1000); 074 075 try { 076 // Master Time > Region Server Time 077 LOG.debug("Test: Master Time > Region Server Time"); 078 LOG.debug("regionServerStartup 2"); 079 InetAddress ia2 = InetAddress.getLocalHost(); 080 request = RegionServerStartupRequest.newBuilder(); 081 request.setPort(1235); 082 request.setServerStartCode(-1); 083 request.setServerCurrentTime(EnvironmentEdgeManager.currentTime() - maxSkew * 2); 084 sm.regionServerStartup(request.build(), 0, "0.0.0", ia2); 085 fail("HMaster should have thrown a ClockOutOfSyncException but didn't."); 086 } catch (ClockOutOfSyncException e) { 087 // we want an exception 088 LOG.info("Received expected exception: " + e); 089 } 090 091 try { 092 // Master Time < Region Server Time 093 LOG.debug("Test: Master Time < Region Server Time"); 094 LOG.debug("regionServerStartup 3"); 095 InetAddress ia3 = InetAddress.getLocalHost(); 096 request = RegionServerStartupRequest.newBuilder(); 097 request.setPort(1236); 098 request.setServerStartCode(-1); 099 request.setServerCurrentTime(EnvironmentEdgeManager.currentTime() + maxSkew * 2); 100 sm.regionServerStartup(request.build(), 0, "0.0.0", ia3); 101 fail("HMaster should have thrown a ClockOutOfSyncException but didn't."); 102 } catch (ClockOutOfSyncException e) { 103 // we want an exception 104 LOG.info("Received expected exception: " + e); 105 } 106 107 // make sure values above warning threshold but below max threshold don't kill 108 LOG.debug("regionServerStartup 4"); 109 InetAddress ia4 = InetAddress.getLocalHost(); 110 request = RegionServerStartupRequest.newBuilder(); 111 request.setPort(1237); 112 request.setServerStartCode(-1); 113 request.setServerCurrentTime(EnvironmentEdgeManager.currentTime() - warningSkew * 2); 114 sm.regionServerStartup(request.build(), 0, "0.0.0", ia4); 115 116 // make sure values above warning threshold but below max threshold don't kill 117 LOG.debug("regionServerStartup 5"); 118 InetAddress ia5 = InetAddress.getLocalHost(); 119 request = RegionServerStartupRequest.newBuilder(); 120 request.setPort(1238); 121 request.setServerStartCode(-1); 122 request.setServerCurrentTime(EnvironmentEdgeManager.currentTime() + warningSkew * 2); 123 sm.regionServerStartup(request.build(), 0, "0.0.0", ia5); 124 } 125}