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.master.assignment.AssignmentManager; 030import org.apache.hadoop.hbase.master.assignment.RegionStates; 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 private static final class DummyMasterServices extends MockNoopMasterServices { 052 053 private final AssignmentManager am; 054 055 public DummyMasterServices(Configuration conf) { 056 super(conf); 057 am = mock(AssignmentManager.class); 058 RegionStates rss = mock(RegionStates.class); 059 when(am.getRegionStates()).thenReturn(rss); 060 } 061 062 @Override 063 public AssignmentManager getAssignmentManager() { 064 return am; 065 } 066 } 067 068 @Test 069 public void testClockSkewDetection() throws Exception { 070 final Configuration conf = HBaseConfiguration.create(); 071 ServerManager sm = 072 new ServerManager(new DummyMasterServices(conf), new DummyRegionServerList()); 073 074 LOG.debug("regionServerStartup 1"); 075 InetAddress ia1 = InetAddress.getLocalHost(); 076 RegionServerStartupRequest.Builder request = RegionServerStartupRequest.newBuilder(); 077 request.setPort(1234); 078 request.setServerStartCode(-1); 079 request.setServerCurrentTime(EnvironmentEdgeManager.currentTime()); 080 sm.regionServerStartup(request.build(), 0, "0.0.0", ia1); 081 082 final Configuration c = HBaseConfiguration.create(); 083 long maxSkew = c.getLong("hbase.master.maxclockskew", 30000); 084 long warningSkew = c.getLong("hbase.master.warningclockskew", 1000); 085 086 try { 087 // Master Time > Region Server Time 088 LOG.debug("Test: Master Time > Region Server Time"); 089 LOG.debug("regionServerStartup 2"); 090 InetAddress ia2 = InetAddress.getLocalHost(); 091 request = RegionServerStartupRequest.newBuilder(); 092 request.setPort(1235); 093 request.setServerStartCode(-1); 094 request.setServerCurrentTime(EnvironmentEdgeManager.currentTime() - maxSkew * 2); 095 sm.regionServerStartup(request.build(), 0, "0.0.0", ia2); 096 fail("HMaster should have thrown a ClockOutOfSyncException but didn't."); 097 } catch (ClockOutOfSyncException e) { 098 // we want an exception 099 LOG.info("Received expected exception: " + e); 100 } 101 102 try { 103 // Master Time < Region Server Time 104 LOG.debug("Test: Master Time < Region Server Time"); 105 LOG.debug("regionServerStartup 3"); 106 InetAddress ia3 = InetAddress.getLocalHost(); 107 request = RegionServerStartupRequest.newBuilder(); 108 request.setPort(1236); 109 request.setServerStartCode(-1); 110 request.setServerCurrentTime(EnvironmentEdgeManager.currentTime() + maxSkew * 2); 111 sm.regionServerStartup(request.build(), 0, "0.0.0", ia3); 112 fail("HMaster should have thrown a ClockOutOfSyncException but didn't."); 113 } catch (ClockOutOfSyncException e) { 114 // we want an exception 115 LOG.info("Received expected exception: " + e); 116 } 117 118 // make sure values above warning threshold but below max threshold don't kill 119 LOG.debug("regionServerStartup 4"); 120 InetAddress ia4 = InetAddress.getLocalHost(); 121 request = RegionServerStartupRequest.newBuilder(); 122 request.setPort(1237); 123 request.setServerStartCode(-1); 124 request.setServerCurrentTime(EnvironmentEdgeManager.currentTime() - warningSkew * 2); 125 sm.regionServerStartup(request.build(), 0, "0.0.0", ia4); 126 127 // make sure values above warning threshold but below max threshold don't kill 128 LOG.debug("regionServerStartup 5"); 129 InetAddress ia5 = InetAddress.getLocalHost(); 130 request = RegionServerStartupRequest.newBuilder(); 131 request.setPort(1238); 132 request.setServerStartCode(-1); 133 request.setServerCurrentTime(EnvironmentEdgeManager.currentTime() + warningSkew * 2); 134 sm.regionServerStartup(request.build(), 0, "0.0.0", ia5); 135 } 136}