1 /*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002, 2014 Oracle and/or its affiliates. All rights reserved. 5 * 6 */ 7 8 package com.sleepycat.je.rep.impl.node; 9 10 import static org.junit.Assert.assertTrue; 11 import static org.junit.Assert.fail; 12 13 import java.util.concurrent.TimeUnit; 14 15 import org.junit.Before; 16 import org.junit.Test; 17 18 import com.sleepycat.je.CommitToken; 19 import com.sleepycat.je.rep.GroupShutdownException; 20 import com.sleepycat.je.rep.NoConsistencyRequiredPolicy; 21 import com.sleepycat.je.rep.NodeType; 22 import com.sleepycat.je.rep.ReplicatedEnvironment; 23 import com.sleepycat.je.rep.impl.RepTestBase; 24 import com.sleepycat.je.rep.utilint.RepTestUtils; 25 import com.sleepycat.je.rep.utilint.RepTestUtils.RepEnvInfo; 26 27 public class GroupShutdownTest extends RepTestBase { 28 29 @Override 30 @Before setUp()31 public void setUp() 32 throws Exception { 33 34 super.setUp(); 35 36 /* Include a SECONDARY node. */ 37 repEnvInfo = RepTestUtils.setupExtendEnvInfo(repEnvInfo, 1); 38 repEnvInfo[repEnvInfo.length-1].getRepConfig().setNodeType( 39 NodeType.SECONDARY); 40 } 41 42 @Test testShutdownExceptions()43 public void testShutdownExceptions() { 44 createGroup(); 45 ReplicatedEnvironment mrep = repEnvInfo[0].getEnv(); 46 47 try { 48 repEnvInfo[1].getEnv().shutdownGroup(10000, TimeUnit.MILLISECONDS); 49 fail("expected exception"); 50 } catch (IllegalStateException e) { 51 /* OK, shutdownGroup on Replica. */ 52 } 53 54 ReplicatedEnvironment mrep2 = 55 new ReplicatedEnvironment(repEnvInfo[0].getEnvHome(), 56 repEnvInfo[0].getRepConfig(), 57 repEnvInfo[0].getEnvConfig()); 58 59 try { 60 mrep.shutdownGroup(10000, TimeUnit.MILLISECONDS); 61 fail("expected exception"); 62 } catch (IllegalStateException e) { 63 /* OK, multiple master handles. */ 64 mrep2.close(); 65 } 66 mrep.shutdownGroup(10000, TimeUnit.MILLISECONDS); 67 for (int i=1; i < repEnvInfo.length; i++) { 68 repEnvInfo[i].closeEnv(); 69 } 70 } 71 72 @Test testShutdownTimeout()73 public void testShutdownTimeout() 74 throws InterruptedException { 75 76 new ShutdownSupport() { 77 @Override 78 void checkException(GroupShutdownException e){} 79 }.shutdownBasic(500, 1); 80 } 81 82 @Test testShutdownBasic()83 public void testShutdownBasic() 84 throws InterruptedException { 85 86 new ShutdownSupport() { 87 @Override 88 void checkException(GroupShutdownException e) { 89 /* 90 * It's possible, in rare circumstances, for the exception to 91 * not contain the shutdown VLSN, that is, for it to be null, 92 * because the VLSNIndex range was not yet initialized. Ignore 93 * it in that circumstance. 94 */ 95 assertTrue((e.getShutdownVLSN() == null) || 96 (ct.getVLSN() <= 97 e.getShutdownVLSN().getSequence())); 98 } 99 }.shutdownBasic(10000, 0); 100 } 101 102 abstract class ShutdownSupport { 103 CommitToken ct; 104 checkException(GroupShutdownException e)105 abstract void checkException(GroupShutdownException e); 106 shutdownBasic(long timeoutMs, int testDelayMs)107 public void shutdownBasic(long timeoutMs, 108 int testDelayMs) 109 throws InterruptedException { 110 111 createGroup(); 112 ReplicatedEnvironment mrep = repEnvInfo[0].getEnv(); 113 leaveGroupAllButMaster(); 114 115 ct = populateDB(mrep, TEST_DB_NAME, 1000); 116 repEnvInfo[0].getRepNode().feederManager(). 117 setTestDelayMs(testDelayMs); 118 restartReplicasNoWait(); 119 120 mrep.shutdownGroup(timeoutMs, TimeUnit.MILLISECONDS); 121 122 for (int i=1; i < repEnvInfo.length; i++) { 123 RepEnvInfo repi = repEnvInfo[i]; 124 final int retries = 100; 125 for (int j=0; j < retries; j++) { 126 try { 127 /* Provoke exception */ 128 repi.getEnv().getState(); 129 if ((j+1) == retries) { 130 fail("expected exception from " + 131 repi.getRepNode().getNameIdPair()); 132 } 133 /* Give the replica time to react */ 134 Thread.sleep(1000); /* a second between retries */ 135 } catch (GroupShutdownException e) { 136 checkException(e); 137 break; 138 } 139 } 140 /* Close the handle. */ 141 repi.closeEnv(); 142 } 143 } 144 } 145 146 /** 147 * Start up replicas for existing master, but don't wait for any 148 * consistency to be reached. 149 */ restartReplicasNoWait()150 private void restartReplicasNoWait() { 151 for (int i=1; i < repEnvInfo.length; i++) { 152 RepEnvInfo ri = repEnvInfo[i]; 153 ri.openEnv(new NoConsistencyRequiredPolicy()); 154 } 155 } 156 } 157