1 /*- 2 * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved. 3 * 4 * See the file LICENSE for license information. 5 * 6 */ 7 8 package repmgrtests; 9 10 import static org.junit.Assert.assertEquals; 11 import static org.junit.Assert.assertTrue; 12 13 import java.io.File; 14 15 import org.junit.Test; 16 import org.junit.Before; 17 18 import com.sleepycat.db.Environment; 19 import com.sleepycat.db.EnvironmentConfig; 20 import com.sleepycat.db.ReplicationConfig; 21 import com.sleepycat.db.ReplicationManagerSiteConfig; 22 import com.sleepycat.db.ReplicationManagerStartPolicy; 23 import com.sleepycat.db.ReplicationStats; 24 import com.sleepycat.db.ReplicationTimeoutType; 25 import com.sleepycat.db.StatsConfig; 26 import com.sleepycat.db.VerboseConfig; 27 28 /** 29 * Tests for repmgr's handling of elections, and the "strict 2-site" 30 * config flag. 31 */ 32 public class TestStrictElect { 33 private int[] testPorts; 34 private int masterPort; 35 private int clientPort; 36 private int client2Port; 37 setUp()38 @Before public void setUp() throws Exception { 39 testPorts = Util.findAvailablePorts(3); 40 masterPort = testPorts[0]; 41 clientPort = testPorts[1]; 42 client2Port = testPorts[2]; 43 } 44 45 /** 46 * Verifies that by default in a 2-site group, client takes over 47 * when master seems to have failed. 48 */ liberal()49 @Test public void liberal() throws Exception { 50 EnvironmentConfig ec = makeBasicConfig(); 51 ReplicationManagerSiteConfig local = new ReplicationManagerSiteConfig("localhost", masterPort); 52 local.setLocalSite(true); 53 ec.addReplicationManagerSite(local); 54 File masterDir = Util.mkdir("master"); 55 Environment master = new Environment(masterDir, ec); 56 master.setReplicationConfig(ReplicationConfig.STRICT_2SITE, true); 57 master.replicationManagerStart(1, ReplicationManagerStartPolicy.REP_MASTER); 58 59 ec = makeBasicConfig(); 60 local = new ReplicationManagerSiteConfig("localhost", clientPort); 61 local.setLocalSite(true); 62 ec.addReplicationManagerSite(local); 63 ReplicationManagerSiteConfig remote = new ReplicationManagerSiteConfig("localhost", masterPort); 64 remote.setBootstrapHelper(true); 65 ec.addReplicationManagerSite(remote); 66 EventHandler mon = new EventHandler(); 67 ec.setEventHandler(mon); 68 File clientDir = Util.mkdir("client"); 69 Environment client = new Environment(clientDir, ec); 70 client.setReplicationConfig(ReplicationConfig.STRICT_2SITE, true); 71 client.setReplicationTimeout(ReplicationTimeoutType.ELECTION_RETRY, 500000); 72 client.setReplicationTimeout(ReplicationTimeoutType.ELECTION_TIMEOUT, 500000); 73 client.replicationManagerStart(1, ReplicationManagerStartPolicy.REP_CLIENT); 74 75 mon.await(); 76 77 // check stats, at this point there should be 0 elections 78 ReplicationStats stats = client.getReplicationStats(StatsConfig.DEFAULT); 79 assertTrue(stats.getElections() == 0); 80 81 master.close(); 82 83 // wait a little while 84 // there should be a couple of failed elections, and we should 85 // not be master 86 Thread.sleep(5000); 87 stats = client.getReplicationStats(StatsConfig.DEFAULT); 88 assertTrue(stats.getElections() > 2); 89 assertTrue(stats.getEnvId() != stats.getMaster()); 90 91 client.close(); 92 } 93 94 /** 95 * Verifies that when the "strict" setting is on, failures 96 * of a master leaves the group with no master: the client does 97 * not take over. 98 */ strict()99 @Test public void strict() throws Exception { 100 EnvironmentConfig ec = makeBasicConfig(); 101 ReplicationManagerSiteConfig local = new ReplicationManagerSiteConfig("localhost", masterPort); 102 local.setLocalSite(true); 103 ec.addReplicationManagerSite(local); 104 File masterDir = Util.mkdir("master"); 105 Environment master = new Environment(masterDir, ec); 106 master.replicationManagerStart(1, ReplicationManagerStartPolicy.REP_MASTER); 107 108 ec = makeBasicConfig(); 109 local = new ReplicationManagerSiteConfig("localhost", clientPort); 110 local.setLocalSite(true); 111 ec.addReplicationManagerSite(local); 112 ReplicationManagerSiteConfig remote = new ReplicationManagerSiteConfig("localhost", masterPort); 113 remote.setBootstrapHelper(true); 114 ec.addReplicationManagerSite(remote); 115 EventHandler mon = new EventHandler(); 116 ec.setEventHandler(mon); 117 File clientDir = Util.mkdir("client"); 118 Environment client = new Environment(clientDir, ec); 119 client.replicationManagerStart(1, ReplicationManagerStartPolicy.REP_CLIENT); 120 121 mon.await(); 122 123 // check stats, at this point there should be 0 elections 124 ReplicationStats stats = client.getReplicationStats(StatsConfig.DEFAULT); 125 assertTrue(stats.getElections() == 0); 126 127 master.close(); 128 129 Thread.sleep(3000); 130 stats = client.getReplicationStats(StatsConfig.DEFAULT); 131 assertEquals(1, stats.getElections()); 132 assertEquals(ReplicationStats.REP_CLIENT, stats.getStatus()); 133 134 client.close(); 135 } 136 137 /** 138 * Verifies that the usual strict majority rule is observed in a 139 * group with more than two sites, regardless of the config setting. 140 */ threeSite()141 @Test public void threeSite() throws Exception { 142 EnvironmentConfig ec = makeBasicConfig(); 143 ReplicationManagerSiteConfig local = new ReplicationManagerSiteConfig("localhost", masterPort); 144 local.setLocalSite(true); 145 ec.addReplicationManagerSite(local); 146 File masterDir = Util.mkdir("master"); 147 Environment master = new Environment(masterDir, ec); 148 master.setReplicationConfig(ReplicationConfig.STRICT_2SITE, true); 149 master.replicationManagerStart(1, ReplicationManagerStartPolicy.REP_MASTER); 150 151 ec = makeBasicConfig(); 152 local = new ReplicationManagerSiteConfig("localhost", clientPort); 153 local.setLocalSite(true); 154 ec.addReplicationManagerSite(local); 155 ReplicationManagerSiteConfig remote = new ReplicationManagerSiteConfig("localhost", masterPort); 156 remote.setBootstrapHelper(true); 157 ec.addReplicationManagerSite(remote); 158 EventHandler mon = new EventHandler(); 159 ec.setEventHandler(mon); 160 File clientDir = Util.mkdir("client"); 161 Environment client = new Environment(clientDir, ec); 162 client.setReplicationConfig(ReplicationConfig.STRICT_2SITE, true); 163 client.setReplicationTimeout(ReplicationTimeoutType.ELECTION_RETRY, 500000); 164 client.setReplicationTimeout(ReplicationTimeoutType.ELECTION_TIMEOUT, 500000); 165 client.replicationManagerStart(1, ReplicationManagerStartPolicy.REP_CLIENT); 166 167 mon.await(); 168 169 // Create, start, and sync the 3rd site, just to establish its 170 // existence (so that the rest of the group recognizes that 171 // the group size is 3); then shut it down so that the later 172 // election will fail for insufficient sites. 173 // 174 ec = makeBasicConfig(); 175 local = new ReplicationManagerSiteConfig("localhost", client2Port); 176 local.setLocalSite(true); 177 ec.addReplicationManagerSite(local); 178 remote = new ReplicationManagerSiteConfig("localhost", masterPort); 179 remote.setBootstrapHelper(true); 180 ec.addReplicationManagerSite(remote); 181 mon = new EventHandler(); 182 ec.setEventHandler(mon); 183 clientDir = Util.mkdir("client2"); 184 Environment client2 = new Environment(clientDir, ec); 185 client2.setReplicationConfig(ReplicationConfig.STRICT_2SITE, true); 186 client2.setReplicationTimeout(ReplicationTimeoutType.ELECTION_RETRY, 500000); 187 client2.setReplicationTimeout(ReplicationTimeoutType.ELECTION_TIMEOUT, 500000); 188 client2.replicationManagerStart(1, ReplicationManagerStartPolicy.REP_CLIENT); 189 190 mon.await(); 191 client2.close(); 192 193 // check stats, at this point there should be 0 elections 194 ReplicationStats stats = client.getReplicationStats(StatsConfig.DEFAULT); 195 assertTrue(stats.getElections() == 0); 196 197 master.close(); 198 199 // wait a little while 200 // there should be a couple of failed elections, and we should 201 // not be master 202 Thread.sleep(5000); 203 stats = client.getReplicationStats(StatsConfig.DEFAULT); 204 assertTrue(stats.getElections() > 2); 205 assertTrue(stats.getEnvId() != stats.getMaster()); 206 207 client.close(); 208 } 209 makeBasicConfig()210 private EnvironmentConfig makeBasicConfig() throws Exception { 211 EnvironmentConfig ec = new EnvironmentConfig(); 212 ec.setAllowCreate(true); 213 ec.setInitializeCache(true); 214 ec.setInitializeLocking(true); 215 ec.setInitializeLogging(true); 216 ec.setInitializeReplication(true); 217 ec.setTransactional(true); 218 ec.setThreaded(true); 219 if (Boolean.getBoolean("VERB_REPLICATION")) 220 ec.setVerbose(VerboseConfig.REPLICATION, true); 221 return (ec); 222 } 223 } 224