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 org.junit.Test; 11 import static org.junit.Assert.*; 12 13 import java.io.File; 14 15 /** 16 * Test of Replication Manager's ability to discriminate between 17 * per-connection wire protocol versions. When configured to use 18 * heartbeats, a modern repmgr nevertheless should ignore them when 19 * talking to a v1 connection. 20 */ 21 // TODO: it might make more sense to refer to sites with a name, which 22 // could double as the env directory name. 23 // 24 public class TestMixedHeartbeats extends AbstractUpgTest { 25 26 public interface Ops { setConfig(Config c)27 public void setConfig(Config c); joinExistingClient(int site, boolean useHB)28 public void joinExistingClient(int site, boolean useHB) 29 throws Exception; becomeMaster(int site)30 public void becomeMaster(int site) throws Exception; getStats(int site)31 public MyStats getStats(int site) throws Exception; checkMinVersion()32 public void checkMinVersion() throws Exception; checkpoint(int site)33 public void checkpoint(int site) throws Exception; 34 } 35 36 public interface Ops46 { setConfig(Config c)37 public void setConfig(Config c); createMaster(int site, boolean configureClient)38 public void createMaster(int site, boolean configureClient) 39 throws Exception; establishClient(int site, boolean configureMaster)40 public void establishClient(int site, boolean configureMaster) 41 throws Exception; shutDown(int siteId)42 public void shutDown(int siteId) throws Exception; remove(int site)43 public void remove(int site) throws Exception; checkMaxVersion()44 public void checkMaxVersion() throws Exception; 45 } 46 47 TestMixedHeartbeats()48 public TestMixedHeartbeats() { 49 super("46", "repmgrtests.V46impl", "repmgrtests.CurrentImpl"); 50 } 51 upg()52 @Test public void upg() throws Exception { 53 Ops46 oldGroup = (Ops46)oldGroup_o; 54 Ops currentGroup = (Ops)currentGroup_o; 55 56 // also: ask DB its version, and make sure it's what we expect 57 // (or at least in reasonable range), 58 // otherwise we have no business running this test. 59 60 // create a v1 master, maybe add some data 61 // create a v2 client to join (configured for hb), wait for start-up done 62 // maybe write some new txns at master, see that they get to client 63 // pause for hb monitor time expiration 64 // verify that no election has been called (check election stats at each site, I guess) 65 // shut down v1 master 66 // verify that client site takes over (use nsites == 2, and don't disable kluge) 67 // upgrade site 1, and have it rejoin as a client 68 // pause again, verify no add'l election (not counting the one take-over we know about) 69 // (maybe we don't need fiddler, since we've already tested normal v2 hb operation) 70 // 71 // V1 operations: 72 // create master 73 // write some txns 74 // read some stats 75 // shut down, recover, remove (for upgrade) 76 // v2 operations: 77 // join a group, wait for start-up done 78 // read some stats 79 // run a checkpoint 80 // 81 // version-independent configuration: 82 // master port 6000 83 // client port 6001 84 // base directory (site directories to be generated by some simple rule?) 85 86 File testdir = new File("TESTDIR"); 87 Util.rm_rf(testdir); 88 testdir.mkdir(); 89 Config config = new Config(testdir); 90 oldGroup.setConfig(config); 91 currentGroup.setConfig(config); 92 93 oldGroup.createMaster(0, false); 94 oldGroup.establishClient(1, true); 95 96 currentGroup.joinExistingClient(1, true); 97 98 // Even though the v1 site clearly cannot be sending heartbeats, 99 // the v2 site should be smart enough not to consider that an 100 // error, even though it is configured for heartbeats. 101 // 102 MyStats s1 = currentGroup.getStats(1); 103 long initialCount = s1.elections; 104 long initialEgen = s1.egen; 105 Thread.sleep(10000); 106 s1 = currentGroup.getStats(1); 107 assertEquals(initialCount, s1.elections); 108 assertEquals(initialEgen, s1.egen); 109 110 // Shut down master, verify that client takes over. 111 // 112 oldGroup.shutDown(0); 113 currentGroup.becomeMaster(1); 114 s1 = currentGroup.getStats(1); 115 assertEquals(initialCount+1, s1.elections); 116 assertTrue("Site 1 is now master", s1.envId == s1.master); 117 118 // Upgrade the former master (site 0), and rejoin the group. 119 // NB: IINM, this form of upgrade works when the log formats may have 120 // changed, but database formats have not. I guess if a 121 // future release changes database formats, we'll have to go 122 // through a bit more work to do this upgrade in the test here. 123 // 124 oldGroup.remove(0); 125 currentGroup.checkpoint(0); 126 currentGroup.joinExistingClient(0, true); 127 128 // Now site 1 is master, and site 0 has rejoined as a client, both running 129 // 4.7 (or higher). Pause again; heartbeats should be flowing, and there 130 // should be no interruption for elections. 131 // 132 MyStats s0 = currentGroup.getStats(0); 133 assertTrue(s0.envId != s0.master); 134 s1 = currentGroup.getStats(1); 135 assertTrue(s1.envId == s1.master); 136 initialCount = s0.elections; 137 initialEgen = s0.egen; 138 Thread.sleep(10000); 139 s0 = currentGroup.getStats(0); 140 assertEquals(initialCount, s0.elections); 141 assertEquals(initialEgen, s0.egen); 142 } 143 144 // TODO: during mixed mode, write some txns at master to verify that 145 // acks can be transmitted correctly. (Shall we check that the master 146 // really does recognize that it has a site connected?) 147 } 148